Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sfc: add skeleton ef100 VF representors

No net_device_ops yet, just a placeholder netdev created per VF.

Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Edward Cree and committed by
David S. Miller
08135eec 95287e1b

+196 -11
+1 -1
drivers/net/ethernet/sfc/Makefile
··· 8 8 ef100.o ef100_nic.o ef100_netdev.o \ 9 9 ef100_ethtool.o ef100_rx.o ef100_tx.o 10 10 sfc-$(CONFIG_SFC_MTD) += mtd.o 11 - sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o 11 + sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o 12 12 13 13 obj-$(CONFIG_SFC) += sfc.o 14 14
+1 -1
drivers/net/ethernet/sfc/ef100_netdev.c
··· 312 312 unregister_netdevice_notifier(&efx->netdev_notifier); 313 313 #if defined(CONFIG_SFC_SRIOV) 314 314 if (!efx->type->is_vf) 315 - efx_ef100_pci_sriov_disable(efx); 315 + efx_ef100_pci_sriov_disable(efx, true); 316 316 #endif 317 317 318 318 ef100_unregister_netdev(efx);
+126
drivers/net/ethernet/sfc/ef100_rep.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2019 Solarflare Communications Inc. 5 + * Copyright 2020-2022 Xilinx Inc. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published 9 + * by the Free Software Foundation, incorporated herein by reference. 10 + */ 11 + 12 + #include "ef100_rep.h" 13 + #include "ef100_nic.h" 14 + 15 + static int efx_ef100_rep_init_struct(struct efx_nic *efx, struct efx_rep *efv) 16 + { 17 + efv->parent = efx; 18 + INIT_LIST_HEAD(&efv->list); 19 + efv->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE | 20 + NETIF_MSG_LINK | NETIF_MSG_IFDOWN | 21 + NETIF_MSG_IFUP | NETIF_MSG_RX_ERR | 22 + NETIF_MSG_TX_ERR | NETIF_MSG_HW; 23 + return 0; 24 + } 25 + 26 + static const struct net_device_ops efx_ef100_rep_netdev_ops = { 27 + }; 28 + 29 + static const struct ethtool_ops efx_ef100_rep_ethtool_ops = { 30 + }; 31 + 32 + static struct efx_rep *efx_ef100_rep_create_netdev(struct efx_nic *efx, 33 + unsigned int i) 34 + { 35 + struct net_device *net_dev; 36 + struct efx_rep *efv; 37 + int rc; 38 + 39 + net_dev = alloc_etherdev_mq(sizeof(*efv), 1); 40 + if (!net_dev) 41 + return ERR_PTR(-ENOMEM); 42 + 43 + efv = netdev_priv(net_dev); 44 + rc = efx_ef100_rep_init_struct(efx, efv); 45 + if (rc) 46 + goto fail1; 47 + efv->net_dev = net_dev; 48 + rtnl_lock(); 49 + spin_lock_bh(&efx->vf_reps_lock); 50 + list_add_tail(&efv->list, &efx->vf_reps); 51 + spin_unlock_bh(&efx->vf_reps_lock); 52 + netif_carrier_off(net_dev); 53 + netif_tx_stop_all_queues(net_dev); 54 + rtnl_unlock(); 55 + 56 + net_dev->netdev_ops = &efx_ef100_rep_netdev_ops; 57 + net_dev->ethtool_ops = &efx_ef100_rep_ethtool_ops; 58 + net_dev->min_mtu = EFX_MIN_MTU; 59 + net_dev->max_mtu = EFX_MAX_MTU; 60 + return efv; 61 + fail1: 62 + free_netdev(net_dev); 63 + return ERR_PTR(rc); 64 + } 65 + 66 + static void efx_ef100_rep_destroy_netdev(struct efx_rep *efv) 67 + { 68 + struct efx_nic *efx = efv->parent; 69 + 70 + spin_lock_bh(&efx->vf_reps_lock); 71 + list_del(&efv->list); 72 + spin_unlock_bh(&efx->vf_reps_lock); 73 + free_netdev(efv->net_dev); 74 + } 75 + 76 + int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i) 77 + { 78 + struct efx_rep *efv; 79 + int rc; 80 + 81 + efv = efx_ef100_rep_create_netdev(efx, i); 82 + if (IS_ERR(efv)) { 83 + rc = PTR_ERR(efv); 84 + pci_err(efx->pci_dev, 85 + "Failed to create representor for VF %d, rc %d\n", i, 86 + rc); 87 + return rc; 88 + } 89 + rc = register_netdev(efv->net_dev); 90 + if (rc) { 91 + pci_err(efx->pci_dev, 92 + "Failed to register representor for VF %d, rc %d\n", 93 + i, rc); 94 + goto fail; 95 + } 96 + pci_dbg(efx->pci_dev, "Representor for VF %d is %s\n", i, 97 + efv->net_dev->name); 98 + return 0; 99 + fail: 100 + efx_ef100_rep_destroy_netdev(efv); 101 + return rc; 102 + } 103 + 104 + void efx_ef100_vfrep_destroy(struct efx_nic *efx, struct efx_rep *efv) 105 + { 106 + struct net_device *rep_dev; 107 + 108 + rep_dev = efv->net_dev; 109 + if (!rep_dev) 110 + return; 111 + netif_dbg(efx, drv, rep_dev, "Removing VF representor\n"); 112 + unregister_netdev(rep_dev); 113 + efx_ef100_rep_destroy_netdev(efv); 114 + } 115 + 116 + void efx_ef100_fini_vfreps(struct efx_nic *efx) 117 + { 118 + struct ef100_nic_data *nic_data = efx->nic_data; 119 + struct efx_rep *efv, *next; 120 + 121 + if (!nic_data->grp_mae) 122 + return; 123 + 124 + list_for_each_entry_safe(efv, next, &efx->vf_reps, list) 125 + efx_ef100_vfrep_destroy(efx, efv); 126 + }
+37
drivers/net/ethernet/sfc/ef100_rep.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /**************************************************************************** 3 + * Driver for Solarflare network controllers and boards 4 + * Copyright 2019 Solarflare Communications Inc. 5 + * Copyright 2020-2022 Xilinx Inc. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published 9 + * by the Free Software Foundation, incorporated herein by reference. 10 + */ 11 + 12 + /* Handling for ef100 representor netdevs */ 13 + #ifndef EF100_REP_H 14 + #define EF100_REP_H 15 + 16 + #include "net_driver.h" 17 + 18 + /** 19 + * struct efx_rep - Private data for an Efx representor 20 + * 21 + * @parent: the efx PF which manages this representor 22 + * @net_dev: representor netdevice 23 + * @msg_enable: log message enable flags 24 + * @list: entry on efx->vf_reps 25 + */ 26 + struct efx_rep { 27 + struct efx_nic *parent; 28 + struct net_device *net_dev; 29 + u32 msg_enable; 30 + struct list_head list; 31 + }; 32 + 33 + int efx_ef100_vfrep_create(struct efx_nic *efx, unsigned int i); 34 + void efx_ef100_vfrep_destroy(struct efx_nic *efx, struct efx_rep *efv); 35 + void efx_ef100_fini_vfreps(struct efx_nic *efx); 36 + 37 + #endif /* EF100_REP_H */
+24 -8
drivers/net/ethernet/sfc/ef100_sriov.c
··· 11 11 12 12 #include "ef100_sriov.h" 13 13 #include "ef100_nic.h" 14 + #include "ef100_rep.h" 14 15 15 16 static int efx_ef100_pci_sriov_enable(struct efx_nic *efx, int num_vfs) 16 17 { 18 + struct ef100_nic_data *nic_data = efx->nic_data; 17 19 struct pci_dev *dev = efx->pci_dev; 18 - int rc; 20 + struct efx_rep *efv, *next; 21 + int rc, i; 19 22 20 23 efx->vf_count = num_vfs; 21 24 rc = pci_enable_sriov(dev, num_vfs); 22 25 if (rc) 23 - goto fail; 26 + goto fail1; 24 27 28 + if (!nic_data->grp_mae) 29 + return 0; 30 + 31 + for (i = 0; i < num_vfs; i++) { 32 + rc = efx_ef100_vfrep_create(efx, i); 33 + if (rc) 34 + goto fail2; 35 + } 25 36 return 0; 26 37 27 - fail: 38 + fail2: 39 + list_for_each_entry_safe(efv, next, &efx->vf_reps, list) 40 + efx_ef100_vfrep_destroy(efx, efv); 41 + pci_disable_sriov(dev); 42 + fail1: 28 43 netif_err(efx, probe, efx->net_dev, "Failed to enable SRIOV VFs\n"); 29 44 efx->vf_count = 0; 30 45 return rc; 31 46 } 32 47 33 - int efx_ef100_pci_sriov_disable(struct efx_nic *efx) 48 + int efx_ef100_pci_sriov_disable(struct efx_nic *efx, bool force) 34 49 { 35 50 struct pci_dev *dev = efx->pci_dev; 36 51 unsigned int vfs_assigned; 37 52 38 53 vfs_assigned = pci_vfs_assigned(dev); 39 - if (vfs_assigned) { 54 + if (vfs_assigned && !force) { 40 55 netif_info(efx, drv, efx->net_dev, "VFs are assigned to guests; " 41 56 "please detach them before disabling SR-IOV\n"); 42 57 return -EBUSY; 43 58 } 44 59 45 - pci_disable_sriov(dev); 46 - 60 + efx_ef100_fini_vfreps(efx); 61 + if (!vfs_assigned) 62 + pci_disable_sriov(dev); 47 63 return 0; 48 64 } 49 65 50 66 int efx_ef100_sriov_configure(struct efx_nic *efx, int num_vfs) 51 67 { 52 68 if (num_vfs == 0) 53 - return efx_ef100_pci_sriov_disable(efx); 69 + return efx_ef100_pci_sriov_disable(efx, false); 54 70 else 55 71 return efx_ef100_pci_sriov_enable(efx, num_vfs); 56 72 }
+1 -1
drivers/net/ethernet/sfc/ef100_sriov.h
··· 11 11 #include "net_driver.h" 12 12 13 13 int efx_ef100_sriov_configure(struct efx_nic *efx, int num_vfs); 14 - int efx_ef100_pci_sriov_disable(struct efx_nic *efx); 14 + int efx_ef100_pci_sriov_disable(struct efx_nic *efx, bool force);
+2
drivers/net/ethernet/sfc/efx_common.c
··· 1021 1021 efx->rps_hash_table = kcalloc(EFX_ARFS_HASH_TABLE_SIZE, 1022 1022 sizeof(*efx->rps_hash_table), GFP_KERNEL); 1023 1023 #endif 1024 + spin_lock_init(&efx->vf_reps_lock); 1025 + INIT_LIST_HEAD(&efx->vf_reps); 1024 1026 INIT_WORK(&efx->mac_work, efx_mac_work); 1025 1027 init_waitqueue_head(&efx->flush_wq); 1026 1028
+4
drivers/net/ethernet/sfc/net_driver.h
··· 966 966 * @vf_count: Number of VFs intended to be enabled. 967 967 * @vf_init_count: Number of VFs that have been fully initialised. 968 968 * @vi_scale: log2 number of vnics per VF. 969 + * @vf_reps_lock: Protects vf_reps list 970 + * @vf_reps: local VF reps 969 971 * @ptp_data: PTP state data 970 972 * @ptp_warned: has this NIC seen and warned about unexpected PTP events? 971 973 * @vpd_sn: Serial number read from VPD ··· 1147 1145 unsigned vf_init_count; 1148 1146 unsigned vi_scale; 1149 1147 #endif 1148 + spinlock_t vf_reps_lock; 1149 + struct list_head vf_reps; 1150 1150 1151 1151 struct efx_ptp_data *ptp_data; 1152 1152 bool ptp_warned;