Commit 4dbb4f9b authored by Karthik Sundaravel's avatar Karthik Sundaravel Committed by Tony Nguyen

ice: Add get/set hw address for VFs using devlink commands

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: default avatarKarthik Sundaravel <ksundara@redhat.com>
Tested-by: default avatarRafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 28cf7829
...@@ -372,6 +372,62 @@ void ice_devlink_destroy_pf_port(struct ice_pf *pf) ...@@ -372,6 +372,62 @@ void ice_devlink_destroy_pf_port(struct ice_pf *pf)
devl_port_unregister(&pf->devlink_port); devl_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;
u16 vf_id;
pf = devlink_priv(devlink);
pci_vf = &attrs->pci_vf;
vf_id = pci_vf->vf;
return __ice_set_vf_mac(pf, vf_id, hw_addr);
}
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 * ice_devlink_create_vf_port - Create a devlink port for this VF
* @vf: the VF to create a port for * @vf: the VF to create a port for
...@@ -407,7 +463,8 @@ int ice_devlink_create_vf_port(struct ice_vf *vf) ...@@ -407,7 +463,8 @@ int ice_devlink_create_vf_port(struct ice_vf *vf)
devlink_port_attrs_set(devlink_port, &attrs); devlink_port_attrs_set(devlink_port, &attrs);
devlink = priv_to_devlink(pf); devlink = priv_to_devlink(pf);
err = devl_port_register(devlink, devlink_port, vsi->idx); err = devl_port_register_with_ops(devlink, devlink_port, vsi->idx,
&ice_devlink_vf_port_ops);
if (err) { if (err) {
dev_err(dev, "Failed to create devlink port for VF %d, error %d\n", dev_err(dev, "Failed to create devlink port for VF %d, error %d\n",
vf->vf_id, err); vf->vf_id, err);
......
...@@ -1416,21 +1416,23 @@ ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi) ...@@ -1416,21 +1416,23 @@ ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi)
} }
/** /**
* ice_set_vf_mac * __ice_set_vf_mac - program VF MAC address
* @netdev: network interface device structure * @pf: PF to be configure
* @vf_id: VF identifier * @vf_id: VF identifier
* @mac: MAC address * @mac: MAC address
* *
* program VF MAC address * program VF MAC address
* Return: zero on success or an error code on failure
*/ */
int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) int __ice_set_vf_mac(struct ice_pf *pf, u16 vf_id, const u8 *mac)
{ {
struct ice_pf *pf = ice_netdev_to_pf(netdev); struct device *dev;
struct ice_vf *vf; struct ice_vf *vf;
int ret; int ret;
dev = ice_pf_to_dev(pf);
if (is_multicast_ether_addr(mac)) { if (is_multicast_ether_addr(mac)) {
netdev_err(netdev, "%pM not a valid unicast address\n", mac); dev_err(dev, "%pM not a valid unicast address\n", mac);
return -EINVAL; return -EINVAL;
} }
...@@ -1459,13 +1461,13 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) ...@@ -1459,13 +1461,13 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
if (is_zero_ether_addr(mac)) { if (is_zero_ether_addr(mac)) {
/* VF will send VIRTCHNL_OP_ADD_ETH_ADDR message with its MAC */ /* VF will send VIRTCHNL_OP_ADD_ETH_ADDR message with its MAC */
vf->pf_set_mac = false; vf->pf_set_mac = false;
netdev_info(netdev, "Removing MAC on VF %d. VF driver will be reinitialized\n", dev_info(dev, "Removing MAC on VF %d. VF driver will be reinitialized\n",
vf->vf_id); vf->vf_id);
} else { } else {
/* PF will add MAC rule for the VF */ /* PF will add MAC rule for the VF */
vf->pf_set_mac = true; vf->pf_set_mac = true;
netdev_info(netdev, "Setting MAC %pM on VF %d. VF driver will be reinitialized\n", dev_info(dev, "Setting MAC %pM on VF %d. VF driver will be reinitialized\n",
mac, vf_id); mac, vf_id);
} }
ice_reset_vf(vf, ICE_VF_RESET_NOTIFY); ice_reset_vf(vf, ICE_VF_RESET_NOTIFY);
...@@ -1476,6 +1478,20 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) ...@@ -1476,6 +1478,20 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
return ret; return ret;
} }
/**
* ice_set_vf_mac - .ndo_set_vf_mac handler
* @netdev: network interface device structure
* @vf_id: VF identifier
* @mac: MAC address
*
* program VF MAC address
* Return: zero on success or an error code on failure
*/
int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
{
return __ice_set_vf_mac(ice_netdev_to_pf(netdev), vf_id, mac);
}
/** /**
* ice_set_vf_trust * ice_set_vf_trust
* @netdev: network interface device structure * @netdev: network interface device structure
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
void ice_process_vflr_event(struct ice_pf *pf); void ice_process_vflr_event(struct ice_pf *pf);
int ice_sriov_configure(struct pci_dev *pdev, int num_vfs); int ice_sriov_configure(struct pci_dev *pdev, int num_vfs);
int __ice_set_vf_mac(struct ice_pf *pf, u16 vf_id, const u8 *mac);
int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac); int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac);
int int
ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi); ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi);
...@@ -80,6 +81,13 @@ ice_sriov_configure(struct pci_dev __always_unused *pdev, ...@@ -80,6 +81,13 @@ ice_sriov_configure(struct pci_dev __always_unused *pdev,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int
__ice_set_vf_mac(struct ice_pf __always_unused *pf,
u16 __always_unused vf_id, const u8 __always_unused *mac)
{
return -EOPNOTSUPP;
}
static inline int static inline int
ice_set_vf_mac(struct net_device __always_unused *netdev, ice_set_vf_mac(struct net_device __always_unused *netdev,
int __always_unused vf_id, u8 __always_unused *mac) int __always_unused vf_id, u8 __always_unused *mac)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment