* [PATCH v7] ice: Add get/set hw address for VFs using devlink commands
@ 2024-04-02 9:22 Karthik Sundaravel
2024-04-02 9:22 ` Karthik Sundaravel
0 siblings, 1 reply; 5+ messages in thread
From: Karthik Sundaravel @ 2024-04-02 9:22 UTC (permalink / raw)
To: jesse.brandeburg, wojciech.drewek, sumang, jacob.e.keller,
anthony.l.nguyen, davem, edumazet, kuba, pabeni, intel-wired-lan,
netdev, linux-kernel
Cc: pmenzel, jiri, michal.swiatkowski, rjarry, aharivel, vchundur,
ksundara, cfontain
Dear Maintainers,
Thanks for the review and suggestions for my patch.
v6 -> v7
--------
- Addressed Smatch and checkpatch issues
v5 -> v6
--------
- Changed data type of vf_id to u16
- Used container_of(port, struct ice_vf, devlink_port) to
get the vf instead of ice_get_vf_by_id()/ice_put_vf()
v4 -> v5
--------
- Cloned ice_set_vf_mac() to ice_set_vf_fn_mac() so that the
parameter ice_pf is used instead of net_device of vf
- removed redundant error handling
v3 -> v4
--------
- Released the vf device by calling ice_put_vf()
v2 -> v3
--------
- Fill the extack message instead of dev_err()
v1 -> v2
--------
- called ice_set_vf_mac() directly from the devlink port function
handlers.
RFC -> v1
---------
- Add the function handlers to set and get the HW address for the
VF representor ports.
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v7] ice: Add get/set hw address for VFs using devlink commands 2024-04-02 9:22 [PATCH v7] ice: Add get/set hw address for VFs using devlink commands Karthik Sundaravel @ 2024-04-02 9:22 ` Karthik Sundaravel 2024-04-02 11:21 ` Jiri Pirko 0 siblings, 1 reply; 5+ messages in thread From: Karthik Sundaravel @ 2024-04-02 9:22 UTC (permalink / raw) To: jesse.brandeburg, wojciech.drewek, sumang, jacob.e.keller, anthony.l.nguyen, davem, edumazet, kuba, pabeni, intel-wired-lan, netdev, linux-kernel Cc: pmenzel, jiri, michal.swiatkowski, rjarry, aharivel, vchundur, ksundara, cfontain Changing the MAC address of the VFs is currently unsupported via devlink. Add the function handlers to set and get the HW address for the VFs. Signed-off-by: Karthik Sundaravel <ksundara@redhat.com> --- drivers/net/ethernet/intel/ice/ice_devlink.c | 63 +++++++++++++++++++- drivers/net/ethernet/intel/ice/ice_sriov.c | 62 +++++++++++++++++++ drivers/net/ethernet/intel/ice/ice_sriov.h | 8 +++ 3 files changed, 132 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c index 80dc5445b50d..10735715403a 100644 --- a/drivers/net/ethernet/intel/ice/ice_devlink.c +++ b/drivers/net/ethernet/intel/ice/ice_devlink.c @@ -1576,6 +1576,66 @@ void ice_devlink_destroy_pf_port(struct ice_pf *pf) devlink_port_unregister(&pf->devlink_port); } +/** + * ice_devlink_port_get_vf_fn_mac - .port_fn_hw_addr_get devlink handler + * @port: devlink port structure + * @hw_addr: MAC address of the port + * @hw_addr_len: length of MAC address + * @extack: extended netdev ack structure + * + * Callback for the devlink .port_fn_hw_addr_get operation + * Return: zero on success or an error code on failure. + */ + +static int ice_devlink_port_get_vf_fn_mac(struct devlink_port *port, + u8 *hw_addr, int *hw_addr_len, + struct netlink_ext_ack *extack) +{ + struct ice_vf *vf = container_of(port, struct ice_vf, devlink_port); + + ether_addr_copy(hw_addr, vf->dev_lan_addr); + *hw_addr_len = ETH_ALEN; + + return 0; +} + +/** + * ice_devlink_port_set_vf_fn_mac - .port_fn_hw_addr_set devlink handler + * @port: devlink port structure + * @hw_addr: MAC address of the port + * @hw_addr_len: length of MAC address + * @extack: extended netdev ack structure + * + * Callback for the devlink .port_fn_hw_addr_set operation + * Return: zero on success or an error code on failure. + */ +static int ice_devlink_port_set_vf_fn_mac(struct devlink_port *port, + const u8 *hw_addr, + int hw_addr_len, + struct netlink_ext_ack *extack) + +{ + struct devlink_port_attrs *attrs = &port->attrs; + struct devlink_port_pci_vf_attrs *pci_vf; + struct devlink *devlink = port->devlink; + struct ice_pf *pf; + u8 mac[ETH_ALEN]; + u16 vf_id; + + pf = devlink_priv(devlink); + pci_vf = &attrs->pci_vf; + vf_id = pci_vf->vf; + + ether_addr_copy(mac, hw_addr); + + return ice_set_vf_fn_mac(pf, vf_id, mac); +} + +static const struct devlink_port_ops ice_devlink_vf_port_ops = { + .port_fn_hw_addr_get = ice_devlink_port_get_vf_fn_mac, + .port_fn_hw_addr_set = ice_devlink_port_set_vf_fn_mac, +}; + /** * ice_devlink_create_vf_port - Create a devlink port for this VF * @vf: the VF to create a port for @@ -1611,7 +1671,8 @@ int ice_devlink_create_vf_port(struct ice_vf *vf) devlink_port_attrs_set(devlink_port, &attrs); devlink = priv_to_devlink(pf); - err = devlink_port_register(devlink, devlink_port, vsi->idx); + err = devlink_port_register_with_ops(devlink, devlink_port, + vsi->idx, &ice_devlink_vf_port_ops); if (err) { dev_err(dev, "Failed to create devlink port for VF %d, error %d\n", vf->vf_id, err); diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c index 31314e7540f8..b1e5cd188fd7 100644 --- a/drivers/net/ethernet/intel/ice/ice_sriov.c +++ b/drivers/net/ethernet/intel/ice/ice_sriov.c @@ -1216,6 +1216,68 @@ ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi) return ret; } +/** + * ice_set_vf_fn_mac + * @pf: PF to be configure + * @vf_id: VF identifier + * @mac: MAC address + * + * program VF MAC address + */ +int ice_set_vf_fn_mac(struct ice_pf *pf, u16 vf_id, u8 *mac) +{ + struct device *dev; + struct ice_vf *vf; + int ret; + + dev = ice_pf_to_dev(pf); + if (is_multicast_ether_addr(mac)) { + dev_err(dev, "%pM not a valid unicast address\n", mac); + return -EINVAL; + } + + vf = ice_get_vf_by_id(pf, vf_id); + if (!vf) + return -EINVAL; + + /* nothing left to do, unicast MAC already set */ + if (ether_addr_equal(vf->dev_lan_addr, mac) && + ether_addr_equal(vf->hw_lan_addr, mac)) { + ret = 0; + goto out_put_vf; + } + + ret = ice_check_vf_ready_for_cfg(vf); + if (ret) + goto out_put_vf; + + mutex_lock(&vf->cfg_lock); + + /* VF is notified of its new MAC via the PF's response to the + * VIRTCHNL_OP_GET_VF_RESOURCES message after the VF has been reset + */ + ether_addr_copy(vf->dev_lan_addr, mac); + ether_addr_copy(vf->hw_lan_addr, mac); + if (is_zero_ether_addr(mac)) { + /* VF will send VIRTCHNL_OP_ADD_ETH_ADDR message with its MAC */ + vf->pf_set_mac = false; + dev_info(dev, "Removing MAC on VF %d. VF driver will be reinitialized\n", + vf->vf_id); + } else { + /* PF will add MAC rule for the VF */ + vf->pf_set_mac = true; + dev_info(dev, "Setting MAC %pM on VF %d. VF driver will be reinitialized\n", + mac, vf_id); + } + + ice_reset_vf(vf, ICE_VF_RESET_NOTIFY); + mutex_unlock(&vf->cfg_lock); + +out_put_vf: + ice_put_vf(vf); + return ret; +} + /** * ice_set_vf_mac * @netdev: network interface device structure diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.h b/drivers/net/ethernet/intel/ice/ice_sriov.h index 346cb2666f3a..11cc522b1d9f 100644 --- a/drivers/net/ethernet/intel/ice/ice_sriov.h +++ b/drivers/net/ethernet/intel/ice/ice_sriov.h @@ -28,6 +28,7 @@ #ifdef CONFIG_PCI_IOV void ice_process_vflr_event(struct ice_pf *pf); int ice_sriov_configure(struct pci_dev *pdev, int num_vfs); +int ice_set_vf_fn_mac(struct ice_pf *pf, u16 vf_id, u8 *mac); int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac); int ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi); @@ -76,6 +77,13 @@ ice_sriov_configure(struct pci_dev __always_unused *pdev, return -EOPNOTSUPP; } +static inline int +ice_set_vf_fn_mac(struct ice_pf __always_unused *pf, + u16 __always_unused vf_id, u8 __always_unused *mac) +{ + return -EOPNOTSUPP; +} + static inline int ice_set_vf_mac(struct net_device __always_unused *netdev, int __always_unused vf_id, u8 __always_unused *mac) -- 2.39.3 (Apple Git-146) ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v7] ice: Add get/set hw address for VFs using devlink commands 2024-04-02 9:22 ` Karthik Sundaravel @ 2024-04-02 11:21 ` Jiri Pirko 2024-04-02 13:57 ` Karthik Sundaravel 0 siblings, 1 reply; 5+ messages in thread From: Jiri Pirko @ 2024-04-02 11:21 UTC (permalink / raw) To: Karthik Sundaravel Cc: jesse.brandeburg, wojciech.drewek, sumang, jacob.e.keller, anthony.l.nguyen, davem, edumazet, kuba, pabeni, intel-wired-lan, netdev, linux-kernel, pmenzel, michal.swiatkowski, rjarry, aharivel, vchundur, cfontain Tue, Apr 02, 2024 at 11:22:54AM CEST, ksundara@redhat.com wrote: >Changing the MAC address of the VFs is currently unsupported via devlink. >Add the function handlers to set and get the HW address for the VFs. > >Signed-off-by: Karthik Sundaravel <ksundara@redhat.com> >--- > drivers/net/ethernet/intel/ice/ice_devlink.c | 63 +++++++++++++++++++- > drivers/net/ethernet/intel/ice/ice_sriov.c | 62 +++++++++++++++++++ > drivers/net/ethernet/intel/ice/ice_sriov.h | 8 +++ > 3 files changed, 132 insertions(+), 1 deletion(-) > >diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c >index 80dc5445b50d..10735715403a 100644 >--- a/drivers/net/ethernet/intel/ice/ice_devlink.c >+++ b/drivers/net/ethernet/intel/ice/ice_devlink.c >@@ -1576,6 +1576,66 @@ void ice_devlink_destroy_pf_port(struct ice_pf *pf) > devlink_port_unregister(&pf->devlink_port); > } > >+/** >+ * ice_devlink_port_get_vf_fn_mac - .port_fn_hw_addr_get devlink handler >+ * @port: devlink port structure >+ * @hw_addr: MAC address of the port >+ * @hw_addr_len: length of MAC address >+ * @extack: extended netdev ack structure >+ * >+ * Callback for the devlink .port_fn_hw_addr_get operation >+ * Return: zero on success or an error code on failure. >+ */ >+ >+static int ice_devlink_port_get_vf_fn_mac(struct devlink_port *port, >+ u8 *hw_addr, int *hw_addr_len, >+ struct netlink_ext_ack *extack) >+{ >+ struct ice_vf *vf = container_of(port, struct ice_vf, devlink_port); >+ >+ ether_addr_copy(hw_addr, vf->dev_lan_addr); >+ *hw_addr_len = ETH_ALEN; >+ >+ return 0; >+} >+ >+/** >+ * ice_devlink_port_set_vf_fn_mac - .port_fn_hw_addr_set devlink handler >+ * @port: devlink port structure >+ * @hw_addr: MAC address of the port >+ * @hw_addr_len: length of MAC address >+ * @extack: extended netdev ack structure >+ * >+ * Callback for the devlink .port_fn_hw_addr_set operation >+ * Return: zero on success or an error code on failure. >+ */ >+static int ice_devlink_port_set_vf_fn_mac(struct devlink_port *port, >+ const u8 *hw_addr, >+ int hw_addr_len, >+ struct netlink_ext_ack *extack) >+ >+{ >+ struct devlink_port_attrs *attrs = &port->attrs; >+ struct devlink_port_pci_vf_attrs *pci_vf; >+ struct devlink *devlink = port->devlink; >+ struct ice_pf *pf; >+ u8 mac[ETH_ALEN]; Why you need this extra variable? >+ u16 vf_id; >+ >+ pf = devlink_priv(devlink); >+ pci_vf = &attrs->pci_vf; >+ vf_id = pci_vf->vf; >+ >+ ether_addr_copy(mac, hw_addr); >+ >+ return ice_set_vf_fn_mac(pf, vf_id, mac); >+} >+ >+static const struct devlink_port_ops ice_devlink_vf_port_ops = { >+ .port_fn_hw_addr_get = ice_devlink_port_get_vf_fn_mac, >+ .port_fn_hw_addr_set = ice_devlink_port_set_vf_fn_mac, >+}; >+ > /** > * ice_devlink_create_vf_port - Create a devlink port for this VF > * @vf: the VF to create a port for >@@ -1611,7 +1671,8 @@ int ice_devlink_create_vf_port(struct ice_vf *vf) > devlink_port_attrs_set(devlink_port, &attrs); > devlink = priv_to_devlink(pf); > >- err = devlink_port_register(devlink, devlink_port, vsi->idx); >+ err = devlink_port_register_with_ops(devlink, devlink_port, >+ vsi->idx, &ice_devlink_vf_port_ops); > if (err) { > dev_err(dev, "Failed to create devlink port for VF %d, error %d\n", > vf->vf_id, err); >diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c >index 31314e7540f8..b1e5cd188fd7 100644 >--- a/drivers/net/ethernet/intel/ice/ice_sriov.c >+++ b/drivers/net/ethernet/intel/ice/ice_sriov.c >@@ -1216,6 +1216,68 @@ ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi) > return ret; > } > >+/** >+ * ice_set_vf_fn_mac >+ * @pf: PF to be configure >+ * @vf_id: VF identifier >+ * @mac: MAC address >+ * >+ * program VF MAC address >+ */ >+int ice_set_vf_fn_mac(struct ice_pf *pf, u16 vf_id, u8 *mac) >+{ >+ struct device *dev; >+ struct ice_vf *vf; >+ int ret; >+ >+ dev = ice_pf_to_dev(pf); >+ if (is_multicast_ether_addr(mac)) { >+ dev_err(dev, "%pM not a valid unicast address\n", mac); >+ return -EINVAL; >+ } >+ >+ vf = ice_get_vf_by_id(pf, vf_id); >+ if (!vf) >+ return -EINVAL; >+ >+ /* nothing left to do, unicast MAC already set */ >+ if (ether_addr_equal(vf->dev_lan_addr, mac) && >+ ether_addr_equal(vf->hw_lan_addr, mac)) { >+ ret = 0; >+ goto out_put_vf; >+ } >+ >+ ret = ice_check_vf_ready_for_cfg(vf); >+ if (ret) >+ goto out_put_vf; >+ >+ mutex_lock(&vf->cfg_lock); >+ >+ /* VF is notified of its new MAC via the PF's response to the >+ * VIRTCHNL_OP_GET_VF_RESOURCES message after the VF has been reset >+ */ >+ ether_addr_copy(vf->dev_lan_addr, mac); >+ ether_addr_copy(vf->hw_lan_addr, mac); >+ if (is_zero_ether_addr(mac)) { >+ /* VF will send VIRTCHNL_OP_ADD_ETH_ADDR message with its MAC */ >+ vf->pf_set_mac = false; >+ dev_info(dev, "Removing MAC on VF %d. VF driver will be reinitialized\n", >+ vf->vf_id); >+ } else { >+ /* PF will add MAC rule for the VF */ >+ vf->pf_set_mac = true; >+ dev_info(dev, "Setting MAC %pM on VF %d. VF driver will be reinitialized\n", >+ mac, vf_id); >+ } >+ >+ ice_reset_vf(vf, ICE_VF_RESET_NOTIFY); >+ mutex_unlock(&vf->cfg_lock); >+ >+out_put_vf: >+ ice_put_vf(vf); >+ return ret; >+} >+ > /** > * ice_set_vf_mac > * @netdev: network interface device structure >diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.h b/drivers/net/ethernet/intel/ice/ice_sriov.h >index 346cb2666f3a..11cc522b1d9f 100644 >--- a/drivers/net/ethernet/intel/ice/ice_sriov.h >+++ b/drivers/net/ethernet/intel/ice/ice_sriov.h >@@ -28,6 +28,7 @@ > #ifdef CONFIG_PCI_IOV > void ice_process_vflr_event(struct ice_pf *pf); > int ice_sriov_configure(struct pci_dev *pdev, int num_vfs); >+int ice_set_vf_fn_mac(struct ice_pf *pf, u16 vf_id, u8 *mac); > int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac); > int > ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi); >@@ -76,6 +77,13 @@ ice_sriov_configure(struct pci_dev __always_unused *pdev, > return -EOPNOTSUPP; > } > >+static inline int >+ice_set_vf_fn_mac(struct ice_pf __always_unused *pf, >+ u16 __always_unused vf_id, u8 __always_unused *mac) >+{ >+ return -EOPNOTSUPP; >+} >+ > static inline int > ice_set_vf_mac(struct net_device __always_unused *netdev, > int __always_unused vf_id, u8 __always_unused *mac) >-- >2.39.3 (Apple Git-146) > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v7] ice: Add get/set hw address for VFs using devlink commands 2024-04-02 11:21 ` Jiri Pirko @ 2024-04-02 13:57 ` Karthik Sundaravel 2024-04-02 14:38 ` Jiri Pirko 0 siblings, 1 reply; 5+ messages in thread From: Karthik Sundaravel @ 2024-04-02 13:57 UTC (permalink / raw) To: Jiri Pirko Cc: jesse.brandeburg, wojciech.drewek, sumang, jacob.e.keller, anthony.l.nguyen, davem, edumazet, kuba, pabeni, intel-wired-lan, netdev, linux-kernel, pmenzel, michal.swiatkowski, rjarry, aharivel, vchundur, cfontain On Tue, Apr 2, 2024 at 4:51 PM Jiri Pirko <jiri@resnulli.us> wrote: > > Tue, Apr 02, 2024 at 11:22:54AM CEST, ksundara@redhat.com wrote: > >Changing the MAC address of the VFs is currently unsupported via devlink. > >Add the function handlers to set and get the HW address for the VFs. > > > >Signed-off-by: Karthik Sundaravel <ksundara@redhat.com> > >--- > > drivers/net/ethernet/intel/ice/ice_devlink.c | 63 +++++++++++++++++++- > > drivers/net/ethernet/intel/ice/ice_sriov.c | 62 +++++++++++++++++++ > > drivers/net/ethernet/intel/ice/ice_sriov.h | 8 +++ > > 3 files changed, 132 insertions(+), 1 deletion(-) > > > >diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c > >index 80dc5445b50d..10735715403a 100644 > >--- a/drivers/net/ethernet/intel/ice/ice_devlink.c > >+++ b/drivers/net/ethernet/intel/ice/ice_devlink.c > >@@ -1576,6 +1576,66 @@ void ice_devlink_destroy_pf_port(struct ice_pf *pf) > > devlink_port_unregister(&pf->devlink_port); > > } > > > >+/** > >+ * ice_devlink_port_get_vf_fn_mac - .port_fn_hw_addr_get devlink handler > >+ * @port: devlink port structure > >+ * @hw_addr: MAC address of the port > >+ * @hw_addr_len: length of MAC address > >+ * @extack: extended netdev ack structure > >+ * > >+ * Callback for the devlink .port_fn_hw_addr_get operation > >+ * Return: zero on success or an error code on failure. > >+ */ > >+ > >+static int ice_devlink_port_get_vf_fn_mac(struct devlink_port *port, > >+ u8 *hw_addr, int *hw_addr_len, > >+ struct netlink_ext_ack *extack) > >+{ > >+ struct ice_vf *vf = container_of(port, struct ice_vf, devlink_port); > >+ > >+ ether_addr_copy(hw_addr, vf->dev_lan_addr); > >+ *hw_addr_len = ETH_ALEN; > >+ > >+ return 0; > >+} > >+ > >+/** > >+ * ice_devlink_port_set_vf_fn_mac - .port_fn_hw_addr_set devlink handler > >+ * @port: devlink port structure > >+ * @hw_addr: MAC address of the port > >+ * @hw_addr_len: length of MAC address > >+ * @extack: extended netdev ack structure > >+ * > >+ * Callback for the devlink .port_fn_hw_addr_set operation > >+ * Return: zero on success or an error code on failure. > >+ */ > >+static int ice_devlink_port_set_vf_fn_mac(struct devlink_port *port, > >+ const u8 *hw_addr, > >+ int hw_addr_len, > >+ struct netlink_ext_ack *extack) > >+ > >+{ > >+ struct devlink_port_attrs *attrs = &port->attrs; > >+ struct devlink_port_pci_vf_attrs *pci_vf; > >+ struct devlink *devlink = port->devlink; > >+ struct ice_pf *pf; > >+ u8 mac[ETH_ALEN]; > > Why you need this extra variable? The function signature of ice_set_vf_fn_mac() is kept to match ice_set_vf_mac(), and hence the ``u8 *mac`` is used instead of ``const u8 *mac``. A copy of the mac is made to facilitate the same. Considering the usage of mac in ice_set_vf_fn_mac(), the function signature could be modified to take a ``const u8 *mac`` as well. > > > >+ u16 vf_id; > >+ > >+ pf = devlink_priv(devlink); > >+ pci_vf = &attrs->pci_vf; > >+ vf_id = pci_vf->vf; > >+ > >+ ether_addr_copy(mac, hw_addr); > >+ > >+ return ice_set_vf_fn_mac(pf, vf_id, mac); > >+} > >+ > >+static const struct devlink_port_ops ice_devlink_vf_port_ops = { > >+ .port_fn_hw_addr_get = ice_devlink_port_get_vf_fn_mac, > >+ .port_fn_hw_addr_set = ice_devlink_port_set_vf_fn_mac, > >+}; > >+ > > /** > > * ice_devlink_create_vf_port - Create a devlink port for this VF > > * @vf: the VF to create a port for > >@@ -1611,7 +1671,8 @@ int ice_devlink_create_vf_port(struct ice_vf *vf) > > devlink_port_attrs_set(devlink_port, &attrs); > > devlink = priv_to_devlink(pf); > > > >- err = devlink_port_register(devlink, devlink_port, vsi->idx); > >+ err = devlink_port_register_with_ops(devlink, devlink_port, > >+ vsi->idx, &ice_devlink_vf_port_ops); > > if (err) { > > dev_err(dev, "Failed to create devlink port for VF %d, error %d\n", > > vf->vf_id, err); > >diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c > >index 31314e7540f8..b1e5cd188fd7 100644 > >--- a/drivers/net/ethernet/intel/ice/ice_sriov.c > >+++ b/drivers/net/ethernet/intel/ice/ice_sriov.c > >@@ -1216,6 +1216,68 @@ ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi) > > return ret; > > } > > > >+/** > >+ * ice_set_vf_fn_mac > >+ * @pf: PF to be configure > >+ * @vf_id: VF identifier > >+ * @mac: MAC address > >+ * > >+ * program VF MAC address > >+ */ > >+int ice_set_vf_fn_mac(struct ice_pf *pf, u16 vf_id, u8 *mac) > >+{ > >+ struct device *dev; > >+ struct ice_vf *vf; > >+ int ret; > >+ > >+ dev = ice_pf_to_dev(pf); > >+ if (is_multicast_ether_addr(mac)) { > >+ dev_err(dev, "%pM not a valid unicast address\n", mac); > >+ return -EINVAL; > >+ } > >+ > >+ vf = ice_get_vf_by_id(pf, vf_id); > >+ if (!vf) > >+ return -EINVAL; > >+ > >+ /* nothing left to do, unicast MAC already set */ > >+ if (ether_addr_equal(vf->dev_lan_addr, mac) && > >+ ether_addr_equal(vf->hw_lan_addr, mac)) { > >+ ret = 0; > >+ goto out_put_vf; > >+ } > >+ > >+ ret = ice_check_vf_ready_for_cfg(vf); > >+ if (ret) > >+ goto out_put_vf; > >+ > >+ mutex_lock(&vf->cfg_lock); > >+ > >+ /* VF is notified of its new MAC via the PF's response to the > >+ * VIRTCHNL_OP_GET_VF_RESOURCES message after the VF has been reset > >+ */ > >+ ether_addr_copy(vf->dev_lan_addr, mac); > >+ ether_addr_copy(vf->hw_lan_addr, mac); > >+ if (is_zero_ether_addr(mac)) { > >+ /* VF will send VIRTCHNL_OP_ADD_ETH_ADDR message with its MAC */ > >+ vf->pf_set_mac = false; > >+ dev_info(dev, "Removing MAC on VF %d. VF driver will be reinitialized\n", > >+ vf->vf_id); > >+ } else { > >+ /* PF will add MAC rule for the VF */ > >+ vf->pf_set_mac = true; > >+ dev_info(dev, "Setting MAC %pM on VF %d. VF driver will be reinitialized\n", > >+ mac, vf_id); > >+ } > >+ > >+ ice_reset_vf(vf, ICE_VF_RESET_NOTIFY); > >+ mutex_unlock(&vf->cfg_lock); > >+ > >+out_put_vf: > >+ ice_put_vf(vf); > >+ return ret; > >+} > >+ > > /** > > * ice_set_vf_mac > > * @netdev: network interface device structure > >diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.h b/drivers/net/ethernet/intel/ice/ice_sriov.h > >index 346cb2666f3a..11cc522b1d9f 100644 > >--- a/drivers/net/ethernet/intel/ice/ice_sriov.h > >+++ b/drivers/net/ethernet/intel/ice/ice_sriov.h > >@@ -28,6 +28,7 @@ > > #ifdef CONFIG_PCI_IOV > > void ice_process_vflr_event(struct ice_pf *pf); > > int ice_sriov_configure(struct pci_dev *pdev, int num_vfs); > >+int ice_set_vf_fn_mac(struct ice_pf *pf, u16 vf_id, u8 *mac); > > int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac); > > int > > ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi); > >@@ -76,6 +77,13 @@ ice_sriov_configure(struct pci_dev __always_unused *pdev, > > return -EOPNOTSUPP; > > } > > > >+static inline int > >+ice_set_vf_fn_mac(struct ice_pf __always_unused *pf, > >+ u16 __always_unused vf_id, u8 __always_unused *mac) > >+{ > >+ return -EOPNOTSUPP; > >+} > >+ > > static inline int > > ice_set_vf_mac(struct net_device __always_unused *netdev, > > int __always_unused vf_id, u8 __always_unused *mac) > >-- > >2.39.3 (Apple Git-146) > > > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v7] ice: Add get/set hw address for VFs using devlink commands 2024-04-02 13:57 ` Karthik Sundaravel @ 2024-04-02 14:38 ` Jiri Pirko 0 siblings, 0 replies; 5+ messages in thread From: Jiri Pirko @ 2024-04-02 14:38 UTC (permalink / raw) To: Karthik Sundaravel Cc: jesse.brandeburg, wojciech.drewek, sumang, jacob.e.keller, anthony.l.nguyen, davem, edumazet, kuba, pabeni, intel-wired-lan, netdev, linux-kernel, pmenzel, michal.swiatkowski, rjarry, aharivel, vchundur, cfontain Tue, Apr 02, 2024 at 03:57:35PM CEST, ksundara@redhat.com wrote: >On Tue, Apr 2, 2024 at 4:51 PM Jiri Pirko <jiri@resnulli.us> wrote: >> >> Tue, Apr 02, 2024 at 11:22:54AM CEST, ksundara@redhat.com wrote: >> >Changing the MAC address of the VFs is currently unsupported via devlink. >> >Add the function handlers to set and get the HW address for the VFs. >> > >> >Signed-off-by: Karthik Sundaravel <ksundara@redhat.com> >> >--- >> > drivers/net/ethernet/intel/ice/ice_devlink.c | 63 +++++++++++++++++++- >> > drivers/net/ethernet/intel/ice/ice_sriov.c | 62 +++++++++++++++++++ >> > drivers/net/ethernet/intel/ice/ice_sriov.h | 8 +++ >> > 3 files changed, 132 insertions(+), 1 deletion(-) >> > >> >diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c >> >index 80dc5445b50d..10735715403a 100644 >> >--- a/drivers/net/ethernet/intel/ice/ice_devlink.c >> >+++ b/drivers/net/ethernet/intel/ice/ice_devlink.c >> >@@ -1576,6 +1576,66 @@ void ice_devlink_destroy_pf_port(struct ice_pf *pf) >> > devlink_port_unregister(&pf->devlink_port); >> > } >> > >> >+/** >> >+ * ice_devlink_port_get_vf_fn_mac - .port_fn_hw_addr_get devlink handler >> >+ * @port: devlink port structure >> >+ * @hw_addr: MAC address of the port >> >+ * @hw_addr_len: length of MAC address >> >+ * @extack: extended netdev ack structure >> >+ * >> >+ * Callback for the devlink .port_fn_hw_addr_get operation >> >+ * Return: zero on success or an error code on failure. >> >+ */ >> >+ >> >+static int ice_devlink_port_get_vf_fn_mac(struct devlink_port *port, >> >+ u8 *hw_addr, int *hw_addr_len, >> >+ struct netlink_ext_ack *extack) >> >+{ >> >+ struct ice_vf *vf = container_of(port, struct ice_vf, devlink_port); >> >+ >> >+ ether_addr_copy(hw_addr, vf->dev_lan_addr); >> >+ *hw_addr_len = ETH_ALEN; >> >+ >> >+ return 0; >> >+} >> >+ >> >+/** >> >+ * ice_devlink_port_set_vf_fn_mac - .port_fn_hw_addr_set devlink handler >> >+ * @port: devlink port structure >> >+ * @hw_addr: MAC address of the port >> >+ * @hw_addr_len: length of MAC address >> >+ * @extack: extended netdev ack structure >> >+ * >> >+ * Callback for the devlink .port_fn_hw_addr_set operation >> >+ * Return: zero on success or an error code on failure. >> >+ */ >> >+static int ice_devlink_port_set_vf_fn_mac(struct devlink_port *port, >> >+ const u8 *hw_addr, >> >+ int hw_addr_len, >> >+ struct netlink_ext_ack *extack) >> >+ >> >+{ >> >+ struct devlink_port_attrs *attrs = &port->attrs; >> >+ struct devlink_port_pci_vf_attrs *pci_vf; >> >+ struct devlink *devlink = port->devlink; >> >+ struct ice_pf *pf; >> >+ u8 mac[ETH_ALEN]; >> >> Why you need this extra variable? >The function signature of ice_set_vf_fn_mac() is kept to match Why? Why can't you just make the arg const? >ice_set_vf_mac(), and hence the ``u8 *mac`` is used instead of ``const >u8 *mac``. >A copy of the mac is made to facilitate the same. >Considering the usage of mac in ice_set_vf_fn_mac(), the function >signature could be modified to take a ``const u8 *mac`` as well. Yep. >> >> >> >+ u16 vf_id; >> >+ >> >+ pf = devlink_priv(devlink); >> >+ pci_vf = &attrs->pci_vf; >> >+ vf_id = pci_vf->vf; >> >+ >> >+ ether_addr_copy(mac, hw_addr); >> >+ >> >+ return ice_set_vf_fn_mac(pf, vf_id, mac); >> >+} >> >+ >> >+static const struct devlink_port_ops ice_devlink_vf_port_ops = { >> >+ .port_fn_hw_addr_get = ice_devlink_port_get_vf_fn_mac, >> >+ .port_fn_hw_addr_set = ice_devlink_port_set_vf_fn_mac, >> >+}; >> >+ >> > /** >> > * ice_devlink_create_vf_port - Create a devlink port for this VF >> > * @vf: the VF to create a port for >> >@@ -1611,7 +1671,8 @@ int ice_devlink_create_vf_port(struct ice_vf *vf) >> > devlink_port_attrs_set(devlink_port, &attrs); >> > devlink = priv_to_devlink(pf); >> > >> >- err = devlink_port_register(devlink, devlink_port, vsi->idx); >> >+ err = devlink_port_register_with_ops(devlink, devlink_port, >> >+ vsi->idx, &ice_devlink_vf_port_ops); >> > if (err) { >> > dev_err(dev, "Failed to create devlink port for VF %d, error %d\n", >> > vf->vf_id, err); >> >diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c >> >index 31314e7540f8..b1e5cd188fd7 100644 >> >--- a/drivers/net/ethernet/intel/ice/ice_sriov.c >> >+++ b/drivers/net/ethernet/intel/ice/ice_sriov.c >> >@@ -1216,6 +1216,68 @@ ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi) >> > return ret; >> > } >> > >> >+/** >> >+ * ice_set_vf_fn_mac >> >+ * @pf: PF to be configure >> >+ * @vf_id: VF identifier >> >+ * @mac: MAC address >> >+ * >> >+ * program VF MAC address >> >+ */ >> >+int ice_set_vf_fn_mac(struct ice_pf *pf, u16 vf_id, u8 *mac) >> >+{ >> >+ struct device *dev; >> >+ struct ice_vf *vf; >> >+ int ret; >> >+ >> >+ dev = ice_pf_to_dev(pf); >> >+ if (is_multicast_ether_addr(mac)) { >> >+ dev_err(dev, "%pM not a valid unicast address\n", mac); >> >+ return -EINVAL; >> >+ } >> >+ >> >+ vf = ice_get_vf_by_id(pf, vf_id); >> >+ if (!vf) >> >+ return -EINVAL; >> >+ >> >+ /* nothing left to do, unicast MAC already set */ >> >+ if (ether_addr_equal(vf->dev_lan_addr, mac) && >> >+ ether_addr_equal(vf->hw_lan_addr, mac)) { >> >+ ret = 0; >> >+ goto out_put_vf; >> >+ } >> >+ >> >+ ret = ice_check_vf_ready_for_cfg(vf); >> >+ if (ret) >> >+ goto out_put_vf; >> >+ >> >+ mutex_lock(&vf->cfg_lock); >> >+ >> >+ /* VF is notified of its new MAC via the PF's response to the >> >+ * VIRTCHNL_OP_GET_VF_RESOURCES message after the VF has been reset >> >+ */ >> >+ ether_addr_copy(vf->dev_lan_addr, mac); >> >+ ether_addr_copy(vf->hw_lan_addr, mac); >> >+ if (is_zero_ether_addr(mac)) { >> >+ /* VF will send VIRTCHNL_OP_ADD_ETH_ADDR message with its MAC */ >> >+ vf->pf_set_mac = false; >> >+ dev_info(dev, "Removing MAC on VF %d. VF driver will be reinitialized\n", >> >+ vf->vf_id); >> >+ } else { >> >+ /* PF will add MAC rule for the VF */ >> >+ vf->pf_set_mac = true; >> >+ dev_info(dev, "Setting MAC %pM on VF %d. VF driver will be reinitialized\n", >> >+ mac, vf_id); >> >+ } >> >+ >> >+ ice_reset_vf(vf, ICE_VF_RESET_NOTIFY); >> >+ mutex_unlock(&vf->cfg_lock); >> >+ >> >+out_put_vf: >> >+ ice_put_vf(vf); >> >+ return ret; >> >+} >> >+ >> > /** >> > * ice_set_vf_mac >> > * @netdev: network interface device structure >> >diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.h b/drivers/net/ethernet/intel/ice/ice_sriov.h >> >index 346cb2666f3a..11cc522b1d9f 100644 >> >--- a/drivers/net/ethernet/intel/ice/ice_sriov.h >> >+++ b/drivers/net/ethernet/intel/ice/ice_sriov.h >> >@@ -28,6 +28,7 @@ >> > #ifdef CONFIG_PCI_IOV >> > void ice_process_vflr_event(struct ice_pf *pf); >> > int ice_sriov_configure(struct pci_dev *pdev, int num_vfs); >> >+int ice_set_vf_fn_mac(struct ice_pf *pf, u16 vf_id, u8 *mac); >> > int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac); >> > int >> > ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi); >> >@@ -76,6 +77,13 @@ ice_sriov_configure(struct pci_dev __always_unused *pdev, >> > return -EOPNOTSUPP; >> > } >> > >> >+static inline int >> >+ice_set_vf_fn_mac(struct ice_pf __always_unused *pf, >> >+ u16 __always_unused vf_id, u8 __always_unused *mac) >> >+{ >> >+ return -EOPNOTSUPP; >> >+} >> >+ >> > static inline int >> > ice_set_vf_mac(struct net_device __always_unused *netdev, >> > int __always_unused vf_id, u8 __always_unused *mac) >> >-- >> >2.39.3 (Apple Git-146) >> > >> > ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2024-04-02 14:38 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-04-02 9:22 [PATCH v7] ice: Add get/set hw address for VFs using devlink commands Karthik Sundaravel 2024-04-02 9:22 ` Karthik Sundaravel 2024-04-02 11:21 ` Jiri Pirko 2024-04-02 13:57 ` Karthik Sundaravel 2024-04-02 14:38 ` Jiri Pirko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox