Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue into main
Tony nguyen says: ==================== Intel Wired LAN Driver Updates 2024-06-28 (MAINTAINERS, ice) This series contains updates to MAINTAINERS file and ice driver. Jesse replaces himself with Przemek in the maintainers file. Karthik Sundaravel adds support for VF get/set MAC address via devlink. Eric checks for errors from ice_vsi_rebuild() during queue reconfiguration. Paul adjusts FW API version check for E830 devices. Piotr adds differentiation of unload type when shutting down AdminQ. Przemek changes ice_adapter initialization to occur once per physical card. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
f61c72be2d
@ -11051,8 +11051,8 @@ F: include/drm/xe*
|
||||
F: include/uapi/drm/xe_drm.h
|
||||
|
||||
INTEL ETHERNET DRIVERS
|
||||
M: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
M: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
M: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
L: intel-wired-lan@lists.osuosl.org (moderated for non-subscribers)
|
||||
S: Supported
|
||||
W: https://www.intel.com/content/www/us/en/support.html
|
||||
|
@ -372,6 +372,62 @@ void ice_devlink_destroy_pf_port(struct ice_pf *pf)
|
||||
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
|
||||
* @vf: the VF to create a port for
|
||||
@ -407,7 +463,8 @@ int ice_devlink_create_vf_port(struct ice_vf *vf)
|
||||
devlink_port_attrs_set(devlink_port, &attrs);
|
||||
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) {
|
||||
dev_err(dev, "Failed to create devlink port for VF %d, error %d\n",
|
||||
vf->vf_id, err);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "ice_adapter.h"
|
||||
|
||||
static DEFINE_XARRAY(ice_adapters);
|
||||
static DEFINE_MUTEX(ice_adapters_mutex);
|
||||
|
||||
/* PCI bus number is 8 bits. Slot is 5 bits. Domain can have the rest. */
|
||||
#define INDEX_FIELD_DOMAIN GENMASK(BITS_PER_LONG - 1, 13)
|
||||
@ -47,8 +48,6 @@ static void ice_adapter_free(struct ice_adapter *adapter)
|
||||
kfree(adapter);
|
||||
}
|
||||
|
||||
DEFINE_FREE(ice_adapter_free, struct ice_adapter*, if (_T) ice_adapter_free(_T))
|
||||
|
||||
/**
|
||||
* ice_adapter_get - Get a shared ice_adapter structure.
|
||||
* @pdev: Pointer to the pci_dev whose driver is getting the ice_adapter.
|
||||
@ -64,27 +63,26 @@ DEFINE_FREE(ice_adapter_free, struct ice_adapter*, if (_T) ice_adapter_free(_T))
|
||||
*/
|
||||
struct ice_adapter *ice_adapter_get(const struct pci_dev *pdev)
|
||||
{
|
||||
struct ice_adapter *ret, __free(ice_adapter_free) *adapter = NULL;
|
||||
unsigned long index = ice_adapter_index(pdev);
|
||||
struct ice_adapter *adapter;
|
||||
int err;
|
||||
|
||||
adapter = ice_adapter_new();
|
||||
if (!adapter)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
scoped_guard(mutex, &ice_adapters_mutex) {
|
||||
err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
|
||||
if (err == -EBUSY) {
|
||||
adapter = xa_load(&ice_adapters, index);
|
||||
refcount_inc(&adapter->refcount);
|
||||
return adapter;
|
||||
}
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
xa_lock(&ice_adapters);
|
||||
ret = __xa_cmpxchg(&ice_adapters, index, NULL, adapter, GFP_KERNEL);
|
||||
if (xa_is_err(ret)) {
|
||||
ret = ERR_PTR(xa_err(ret));
|
||||
goto unlock;
|
||||
adapter = ice_adapter_new();
|
||||
if (!adapter)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
|
||||
}
|
||||
if (ret) {
|
||||
refcount_inc(&ret->refcount);
|
||||
goto unlock;
|
||||
}
|
||||
ret = no_free_ptr(adapter);
|
||||
unlock:
|
||||
xa_unlock(&ice_adapters);
|
||||
return ret;
|
||||
return adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,23 +92,21 @@ unlock:
|
||||
* Releases the reference to ice_adapter previously obtained with
|
||||
* ice_adapter_get.
|
||||
*
|
||||
* Context: Any.
|
||||
* Context: Process, may sleep.
|
||||
*/
|
||||
void ice_adapter_put(const struct pci_dev *pdev)
|
||||
{
|
||||
unsigned long index = ice_adapter_index(pdev);
|
||||
struct ice_adapter *adapter;
|
||||
|
||||
xa_lock(&ice_adapters);
|
||||
adapter = xa_load(&ice_adapters, index);
|
||||
if (WARN_ON(!adapter))
|
||||
goto unlock;
|
||||
scoped_guard(mutex, &ice_adapters_mutex) {
|
||||
adapter = xa_load(&ice_adapters, index);
|
||||
if (WARN_ON(!adapter))
|
||||
return;
|
||||
if (!refcount_dec_and_test(&adapter->refcount))
|
||||
return;
|
||||
|
||||
if (!refcount_dec_and_test(&adapter->refcount))
|
||||
goto unlock;
|
||||
|
||||
WARN_ON(__xa_erase(&ice_adapters, index) != adapter);
|
||||
WARN_ON(xa_erase(&ice_adapters, index) != adapter);
|
||||
}
|
||||
ice_adapter_free(adapter);
|
||||
unlock:
|
||||
xa_unlock(&ice_adapters);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ int ice_check_reset(struct ice_hw *hw);
|
||||
int ice_reset(struct ice_hw *hw, enum ice_reset_req req);
|
||||
int ice_create_all_ctrlq(struct ice_hw *hw);
|
||||
int ice_init_all_ctrlq(struct ice_hw *hw);
|
||||
void ice_shutdown_all_ctrlq(struct ice_hw *hw);
|
||||
void ice_shutdown_all_ctrlq(struct ice_hw *hw, bool unloading);
|
||||
void ice_destroy_all_ctrlq(struct ice_hw *hw);
|
||||
int
|
||||
ice_clean_rq_elem(struct ice_hw *hw, struct ice_ctl_q_info *cq,
|
||||
|
@ -510,16 +510,19 @@ shutdown_sq_out:
|
||||
*/
|
||||
static bool ice_aq_ver_check(struct ice_hw *hw)
|
||||
{
|
||||
if (hw->api_maj_ver > EXP_FW_API_VER_MAJOR) {
|
||||
u8 exp_fw_api_ver_major = EXP_FW_API_VER_MAJOR_BY_MAC(hw);
|
||||
u8 exp_fw_api_ver_minor = EXP_FW_API_VER_MINOR_BY_MAC(hw);
|
||||
|
||||
if (hw->api_maj_ver > exp_fw_api_ver_major) {
|
||||
/* Major API version is newer than expected, don't load */
|
||||
dev_warn(ice_hw_to_dev(hw),
|
||||
"The driver for the device stopped because the NVM image is newer than expected. You must install the most recent version of the network driver.\n");
|
||||
return false;
|
||||
} else if (hw->api_maj_ver == EXP_FW_API_VER_MAJOR) {
|
||||
if (hw->api_min_ver > (EXP_FW_API_VER_MINOR + 2))
|
||||
} else if (hw->api_maj_ver == exp_fw_api_ver_major) {
|
||||
if (hw->api_min_ver > (exp_fw_api_ver_minor + 2))
|
||||
dev_info(ice_hw_to_dev(hw),
|
||||
"The driver for the device detected a newer version of the NVM image than expected. Please install the most recent version of the network driver.\n");
|
||||
else if ((hw->api_min_ver + 2) < EXP_FW_API_VER_MINOR)
|
||||
else if ((hw->api_min_ver + 2) < exp_fw_api_ver_minor)
|
||||
dev_info(ice_hw_to_dev(hw),
|
||||
"The driver for the device detected an older version of the NVM image than expected. Please update the NVM image.\n");
|
||||
} else {
|
||||
@ -684,10 +687,12 @@ struct ice_ctl_q_info *ice_get_sbq(struct ice_hw *hw)
|
||||
* ice_shutdown_ctrlq - shutdown routine for any control queue
|
||||
* @hw: pointer to the hardware structure
|
||||
* @q_type: specific Control queue type
|
||||
* @unloading: is the driver unloading itself
|
||||
*
|
||||
* NOTE: this function does not destroy the control queue locks.
|
||||
*/
|
||||
static void ice_shutdown_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
|
||||
static void ice_shutdown_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type,
|
||||
bool unloading)
|
||||
{
|
||||
struct ice_ctl_q_info *cq;
|
||||
|
||||
@ -695,7 +700,7 @@ static void ice_shutdown_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
|
||||
case ICE_CTL_Q_ADMIN:
|
||||
cq = &hw->adminq;
|
||||
if (ice_check_sq_alive(hw, cq))
|
||||
ice_aq_q_shutdown(hw, true);
|
||||
ice_aq_q_shutdown(hw, unloading);
|
||||
break;
|
||||
case ICE_CTL_Q_SB:
|
||||
cq = &hw->sbq;
|
||||
@ -714,20 +719,21 @@ static void ice_shutdown_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
|
||||
/**
|
||||
* ice_shutdown_all_ctrlq - shutdown routine for all control queues
|
||||
* @hw: pointer to the hardware structure
|
||||
* @unloading: is the driver unloading itself
|
||||
*
|
||||
* NOTE: this function does not destroy the control queue locks. The driver
|
||||
* may call this at runtime to shutdown and later restart control queues, such
|
||||
* as in response to a reset event.
|
||||
*/
|
||||
void ice_shutdown_all_ctrlq(struct ice_hw *hw)
|
||||
void ice_shutdown_all_ctrlq(struct ice_hw *hw, bool unloading)
|
||||
{
|
||||
/* Shutdown FW admin queue */
|
||||
ice_shutdown_ctrlq(hw, ICE_CTL_Q_ADMIN);
|
||||
ice_shutdown_ctrlq(hw, ICE_CTL_Q_ADMIN, unloading);
|
||||
/* Shutdown PHY Sideband */
|
||||
if (ice_is_sbq_supported(hw))
|
||||
ice_shutdown_ctrlq(hw, ICE_CTL_Q_SB);
|
||||
ice_shutdown_ctrlq(hw, ICE_CTL_Q_SB, unloading);
|
||||
/* Shutdown PF-VF Mailbox */
|
||||
ice_shutdown_ctrlq(hw, ICE_CTL_Q_MAILBOX);
|
||||
ice_shutdown_ctrlq(hw, ICE_CTL_Q_MAILBOX, unloading);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -759,7 +765,7 @@ int ice_init_all_ctrlq(struct ice_hw *hw)
|
||||
break;
|
||||
|
||||
ice_debug(hw, ICE_DBG_AQ_MSG, "Retry Admin Queue init due to FW critical error\n");
|
||||
ice_shutdown_ctrlq(hw, ICE_CTL_Q_ADMIN);
|
||||
ice_shutdown_ctrlq(hw, ICE_CTL_Q_ADMIN, true);
|
||||
msleep(ICE_CTL_Q_ADMIN_INIT_MSEC);
|
||||
} while (retry++ < ICE_CTL_Q_ADMIN_INIT_TIMEOUT);
|
||||
|
||||
@ -840,7 +846,7 @@ static void ice_destroy_ctrlq_locks(struct ice_ctl_q_info *cq)
|
||||
void ice_destroy_all_ctrlq(struct ice_hw *hw)
|
||||
{
|
||||
/* shut down all the control queues first */
|
||||
ice_shutdown_all_ctrlq(hw);
|
||||
ice_shutdown_all_ctrlq(hw, true);
|
||||
|
||||
ice_destroy_ctrlq_locks(&hw->adminq);
|
||||
if (ice_is_sbq_supported(hw))
|
||||
|
@ -21,9 +21,18 @@
|
||||
/* Defines that help manage the driver vs FW API checks.
|
||||
* Take a look at ice_aq_ver_check in ice_controlq.c for actual usage.
|
||||
*/
|
||||
#define EXP_FW_API_VER_BRANCH 0x00
|
||||
#define EXP_FW_API_VER_MAJOR 0x01
|
||||
#define EXP_FW_API_VER_MINOR 0x05
|
||||
#define EXP_FW_API_VER_MAJOR_E810 0x01
|
||||
#define EXP_FW_API_VER_MINOR_E810 0x05
|
||||
|
||||
#define EXP_FW_API_VER_MAJOR_E830 0x01
|
||||
#define EXP_FW_API_VER_MINOR_E830 0x07
|
||||
|
||||
#define EXP_FW_API_VER_MAJOR_BY_MAC(hw) ((hw)->mac_type == ICE_MAC_E830 ? \
|
||||
EXP_FW_API_VER_MAJOR_E830 : \
|
||||
EXP_FW_API_VER_MAJOR_E810)
|
||||
#define EXP_FW_API_VER_MINOR_BY_MAC(hw) ((hw)->mac_type == ICE_MAC_E830 ? \
|
||||
EXP_FW_API_VER_MINOR_E830 : \
|
||||
EXP_FW_API_VER_MINOR_E810)
|
||||
|
||||
/* Different control queue types: These are mainly for SW consumption. */
|
||||
enum ice_ctl_q {
|
||||
|
@ -623,7 +623,7 @@ skip:
|
||||
if (hw->port_info)
|
||||
ice_sched_clear_port(hw->port_info);
|
||||
|
||||
ice_shutdown_all_ctrlq(hw);
|
||||
ice_shutdown_all_ctrlq(hw, false);
|
||||
|
||||
set_bit(ICE_PREPARED_FOR_RESET, pf->state);
|
||||
}
|
||||
@ -4158,13 +4158,17 @@ int ice_vsi_recfg_qs(struct ice_vsi *vsi, int new_rx, int new_tx, bool locked)
|
||||
|
||||
/* set for the next time the netdev is started */
|
||||
if (!netif_running(vsi->netdev)) {
|
||||
ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT);
|
||||
err = ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT);
|
||||
if (err)
|
||||
goto rebuild_err;
|
||||
dev_dbg(ice_pf_to_dev(pf), "Link is down, queue count change happens when link is brought up\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
ice_vsi_close(vsi);
|
||||
ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT);
|
||||
err = ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT);
|
||||
if (err)
|
||||
goto rebuild_err;
|
||||
|
||||
ice_for_each_traffic_class(i) {
|
||||
if (vsi->tc_cfg.ena_tc & BIT(i))
|
||||
@ -4175,6 +4179,11 @@ int ice_vsi_recfg_qs(struct ice_vsi *vsi, int new_rx, int new_tx, bool locked)
|
||||
}
|
||||
ice_pf_dcb_recfg(pf, locked);
|
||||
ice_vsi_open(vsi);
|
||||
goto done;
|
||||
|
||||
rebuild_err:
|
||||
dev_err(ice_pf_to_dev(pf), "Error during VSI rebuild: %d. Unload and reload the driver.\n",
|
||||
err);
|
||||
done:
|
||||
clear_bit(ICE_CFG_BUSY, pf->state);
|
||||
return err;
|
||||
@ -5490,7 +5499,7 @@ static void ice_prepare_for_shutdown(struct ice_pf *pf)
|
||||
if (pf->vsi[v])
|
||||
pf->vsi[v]->vsi_num = 0;
|
||||
|
||||
ice_shutdown_all_ctrlq(hw);
|
||||
ice_shutdown_all_ctrlq(hw, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -7750,7 +7759,7 @@ err_vsi_rebuild:
|
||||
err_sched_init_port:
|
||||
ice_sched_cleanup_all(hw);
|
||||
err_init_ctrlq:
|
||||
ice_shutdown_all_ctrlq(hw);
|
||||
ice_shutdown_all_ctrlq(hw, false);
|
||||
set_bit(ICE_RESET_FAILED, pf->state);
|
||||
clear_recovery:
|
||||
/* set this bit in PF state to control service task scheduling */
|
||||
|
@ -1416,21 +1416,23 @@ out_put_vf:
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_set_vf_mac
|
||||
* @netdev: network interface device structure
|
||||
* __ice_set_vf_mac - program VF MAC address
|
||||
* @pf: PF to be configure
|
||||
* @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)
|
||||
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;
|
||||
int ret;
|
||||
|
||||
dev = ice_pf_to_dev(pf);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1459,13 +1461,13 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
|
||||
if (is_zero_ether_addr(mac)) {
|
||||
/* VF will send VIRTCHNL_OP_ADD_ETH_ADDR message with its MAC */
|
||||
vf->pf_set_mac = false;
|
||||
netdev_info(netdev, "Removing MAC on VF %d. VF driver will be reinitialized\n",
|
||||
vf->vf_id);
|
||||
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;
|
||||
netdev_info(netdev, "Setting MAC %pM on VF %d. VF driver will be reinitialized\n",
|
||||
mac, vf_id);
|
||||
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);
|
||||
@ -1476,6 +1478,20 @@ out_put_vf:
|
||||
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
|
||||
* @netdev: network interface device structure
|
||||
|
@ -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_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_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,
|
||||
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
|
||||
ice_set_vf_mac(struct net_device __always_unused *netdev,
|
||||
int __always_unused vf_id, u8 __always_unused *mac)
|
||||
|
Loading…
x
Reference in New Issue
Block a user