From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nambiar, Amritha Date: Tue, 9 Aug 2016 17:18:19 -0700 Subject: [Intel-wired-lan] [next PATCH 2/5] i40e: Introduce VF representor/control netdevs. In-Reply-To: <1470329387-25138-2-git-send-email-sridhar.samudrala@intel.com> References: <1470329387-25138-1-git-send-email-sridhar.samudrala@intel.com> <1470329387-25138-2-git-send-email-sridhar.samudrala@intel.com> Message-ID: <57AA72CB.1060705@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: intel-wired-lan@osuosl.org List-ID: On 8/4/2016 9:49 AM, Sridhar Samudrala wrote: > VF representor/control netdevs are created for each VF if the switch mode > is set to 'switchdev'. These netdevs can be used to control and configure > VFs from PFs namespace. They enable exposing VF statistics, configuring > ntuple filters, additional mac/vlans to VFs etc. > > Sample script to create VF representors > # devlink dev set pci/0000:05:00.0 smode switchdev > # echo 2 > /sys/class/net/enp5s0f0/device/sriov_numvfs > # ip l show > 297: enp5s0f0: mtu 1500 qdisc noop portid 6805ca2e7268 state DOWN mode DEFAULT group default qlen 1000 > link/ether 68:05:ca:2e:72:68 brd ff:ff:ff:ff:ff:ff > vf 0 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off > vf 1 MAC 00:00:00:00:00:00, spoof checking on, link-state auto, trust off > 299: enp5s0f0-vf0: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 > link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff > 300: enp5s0f0-vf1: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 > link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff > > Signed-off-by: Sridhar Samudrala Acked-by: Amritha Nambiar > --- > drivers/net/ethernet/intel/i40e/i40e_main.c | 13 +++- > drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 90 ++++++++++++++++++++++ > drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h | 14 ++++ > 3 files changed, 116 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c > index bb44f09..208da9f 100644 > --- a/drivers/net/ethernet/intel/i40e/i40e_main.c > +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c > @@ -10700,14 +10700,25 @@ static int i40e_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode) > static int i40e_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode) > { > struct i40e_pf *pf = devlink_priv(devlink); > - int err = 0; > + struct i40e_vf *vf; > + int i, err = 0; > > if (mode == pf->eswitch_mode) > goto done; > > switch (mode) { > case DEVLINK_ESWITCH_MODE_LEGACY: > + for (i = 0; i < pf->num_alloc_vfs; i++) { > + vf = &(pf->vf[i]); > + i40e_free_vf_netdev(vf); > + } > + pf->eswitch_mode = mode; > + break; > case DEVLINK_ESWITCH_MODE_SWITCHDEV: > + for (i = 0; i < pf->num_alloc_vfs; i++) { > + vf = &(pf->vf[i]); > + i40e_alloc_vf_netdev(vf, i); > + } > pf->eswitch_mode = mode; > break; > default: > diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c > index 4bd66d7..d41c37c 100644 > --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c > +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c > @@ -1000,6 +1000,90 @@ complete_reset: > clear_bit(__I40E_VF_DISABLE, &pf->state); > } > > +static int i40e_vf_netdev_open(struct net_device *dev) > +{ > + return 0; > +} > + > +static int i40e_vf_netdev_stop(struct net_device *dev) > +{ > + return 0; > +} > + > +static const struct net_device_ops i40e_vf_netdev_ops = { > + .ndo_open = i40e_vf_netdev_open, > + .ndo_stop = i40e_vf_netdev_stop, > +}; > + > +/** > + * i40e_alloc_vf_netdev > + * @vf: pointer to the VF structure > + * @vf_num: VF number > + * > + * Create VF representor/control netdev > + **/ > +int i40e_alloc_vf_netdev(struct i40e_vf *vf, u16 vf_num) > +{ > + struct net_device *netdev; > + char netdev_name[IFNAMSIZ]; > + struct i40e_vf_netdev_priv *priv; > + struct i40e_pf *pf = vf->pf; > + struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; > + int err; > + > + snprintf(netdev_name, IFNAMSIZ, "%s-vf%d", vsi->netdev->name, vf_num); > + netdev = alloc_netdev(sizeof(struct i40e_vf_netdev_priv), netdev_name, > + NET_NAME_UNKNOWN, ether_setup); > + if (!netdev) { > + dev_err(&pf->pdev->dev, "alloc_netdev failed for vf:%d\n", > + vf_num); > + return -ENOMEM; > + } > + > + pf->vf[vf_num].ctrl_netdev = netdev; > + > + priv = netdev_priv(netdev); > + priv->vf = &(pf->vf[vf_num]); > + > + netdev->netdev_ops = &i40e_vf_netdev_ops; > + > + netif_carrier_off(netdev); > + netif_tx_disable(netdev); > + > + err = register_netdev(netdev); > + if (err) { > + dev_err(&pf->pdev->dev, "register_netdev failed for vf: %s\n", > + vf->ctrl_netdev->name); > + free_netdev(netdev); > + return err; > + } > + > + dev_info(&pf->pdev->dev, "VF representor(%s) created for VF %d\n", > + vf->ctrl_netdev->name, vf_num); > + > + return 0; > +} > + > +/** > + * i40e_free_vf_netdev > + * @vf: pointer to the VF structure > + * > + * Free VF representor/control netdev > + **/ > +void i40e_free_vf_netdev(struct i40e_vf *vf) > +{ > + struct i40e_pf *pf = vf->pf; > + > + if (!vf->ctrl_netdev) > + return; > + > + dev_info(&pf->pdev->dev, "Freeing VF representor(%s)\n", > + vf->ctrl_netdev->name); > + > + unregister_netdev(vf->ctrl_netdev); > + free_netdev(vf->ctrl_netdev); > +} > + > /** > * i40e_free_vfs > * @pf: pointer to the PF structure > @@ -1042,6 +1126,9 @@ void i40e_free_vfs(struct i40e_pf *pf) > i40e_free_vf_res(&pf->vf[i]); > /* disable qp mappings */ > i40e_disable_vf_mappings(&pf->vf[i]); > + > + if (pf->eswitch_mode == DEVLINK_ESWITCH_MODE_SWITCHDEV) > + i40e_free_vf_netdev(&pf->vf[i]); > } > > kfree(pf->vf); > @@ -1110,6 +1197,9 @@ int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs) > /* VF resources get allocated during reset */ > i40e_reset_vf(&vfs[i], false); > > + if (pf->eswitch_mode == DEVLINK_ESWITCH_MODE_SWITCHDEV) > + i40e_alloc_vf_netdev(&vfs[i], i); > + > } > pf->num_alloc_vfs = num_alloc_vfs; > > diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h > index 8751741..8446547 100644 > --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h > +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h > @@ -72,10 +72,21 @@ enum i40e_vf_capabilities { > I40E_VIRTCHNL_VF_CAP_IWARP, > }; > > +/* VF Ctrl netdev private structure */ > +struct i40e_vf_netdev_priv { > + struct i40e_vf *vf; > +}; > + > /* VF information structure */ > struct i40e_vf { > struct i40e_pf *pf; > > + /* VF representor netdev that allows control and configuration of > + * VFs from the host. Enables returning VF stats, configuring ntuple > + * filters on VFs, adding multiple mac/vlans to VFs etc. > + */ > + struct net_device *ctrl_netdev; > + > /* VF id in the PF space */ > s16 vf_id; > /* all VF vsis connect to the same parent */ > @@ -142,4 +153,7 @@ int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable); > void i40e_vc_notify_link_state(struct i40e_pf *pf); > void i40e_vc_notify_reset(struct i40e_pf *pf); > > +int i40e_alloc_vf_netdev(struct i40e_vf *vf, u16 vf_num); > +void i40e_free_vf_netdev(struct i40e_vf *vf); > + > #endif /* _I40E_VIRTCHNL_PF_H_ */