sfc: Store the efx_nic struct of the current VF in the VF data struct
authorShradha Shah <sshah@solarflare.com>
Wed, 20 May 2015 10:09:46 +0000 (11:09 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 21 May 2015 22:43:53 +0000 (18:43 -0400)
Initialised in efx_probe_vf and removal is dealt with in
efx_ef10_remove.

vf->efx is needed in future patches to change the MAC address
of the VF via the parent PF, while the driver is bound to the
VF.
Example: ip link set dev vf NUM mac LLADDR

Signed-off-by: Shradha Shah <sshah@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sfc/ef10.c
drivers/net/ethernet/sfc/ef10_sriov.c
drivers/net/ethernet/sfc/ef10_sriov.h

index 8b6579aceebbea894936bd19e9d75b3b524d7b44..78d3236a3d672a2e1761e48a41c166ebe147b057 100644 (file)
@@ -544,6 +544,25 @@ static void efx_ef10_remove(struct efx_nic *efx)
        struct efx_ef10_nic_data *nic_data = efx->nic_data;
        int rc;
 
+#ifdef CONFIG_SFC_SRIOV
+       struct efx_ef10_nic_data *nic_data_pf;
+       struct pci_dev *pci_dev_pf;
+       struct efx_nic *efx_pf;
+       struct ef10_vf *vf;
+
+       if (efx->pci_dev->is_virtfn) {
+               pci_dev_pf = efx->pci_dev->physfn;
+               if (pci_dev_pf) {
+                       efx_pf = pci_get_drvdata(pci_dev_pf);
+                       nic_data_pf = efx_pf->nic_data;
+                       vf = nic_data_pf->vf + nic_data->vf_index;
+                       vf->efx = NULL;
+               } else
+                       netif_info(efx, drv, efx->net_dev,
+                                  "Could not get the PF id from VF\n");
+       }
+#endif
+
        efx_ptp_remove(efx);
 
        efx_mcdi_mon_remove(efx);
@@ -582,6 +601,19 @@ static int efx_ef10_probe_vf(struct efx_nic *efx)
        if (rc)
                goto fail;
 
+       if (efx->pci_dev->is_virtfn) {
+               if (efx->pci_dev->physfn) {
+                       struct efx_nic *efx_pf =
+                               pci_get_drvdata(efx->pci_dev->physfn);
+                       struct efx_ef10_nic_data *nic_data_p = efx_pf->nic_data;
+                       struct efx_ef10_nic_data *nic_data = efx->nic_data;
+
+                       nic_data_p->vf[nic_data->vf_index].efx = efx;
+               } else
+                       netif_info(efx, drv, efx->net_dev,
+                                  "Could not get the PF id from VF\n");
+       }
+
        return 0;
 
 fail:
index 1b93acf2d28dc5a454f76429c7027fdcf9c59bd3..6208dd76bc2b3f88a97c2104783ef02db7076040 100644 (file)
@@ -160,6 +160,8 @@ static void efx_ef10_sriov_free_vf_vports(struct efx_nic *efx)
                        efx_ef10_vport_free(efx, vf->vport_id);
                        vf->vport_id = 0;
                }
+
+               vf->efx = NULL;
        }
 }
 
@@ -215,6 +217,7 @@ static int efx_ef10_sriov_alloc_vf_vswitching(struct efx_nic *efx)
 
        for (i = 0; i < efx->vf_count; i++) {
                random_ether_addr(nic_data->vf[i].mac);
+               nic_data->vf[i].efx = NULL;
 
                rc = efx_ef10_sriov_assign_vf_vport(efx, i);
                if (rc)
index 8b67163e2f81bef1fef00ee33740c48a45a5a4c6..6f27a0d30dacdb9b404adce0f121bc5ee7d511a7 100644 (file)
 
 /**
  * struct ef10_vf - PF's store of VF data
+ * @efx: efx_nic struct for the current VF
  * @vport_id: vport ID for the VF
  * @vport_assigned: record whether the vport is currently assigned to the VF
  * @mac: MAC address for the VF, zero when address is removed from the vport
  */
 struct ef10_vf {
+       struct efx_nic *efx;
        unsigned int vport_id;
        unsigned int vport_assigned;
        u8 mac[ETH_ALEN];