Merge branch 'nfp-port-speed-and-eeprom-get-set-updates'
Simon Horman says: ==================== nfp: port speed and eeprom get/set updates this short series is the initial updates for the NFP driver for the v6.1 Kernel. It covers two enhancements: 1. Patches 1/3 and 2/3: - Support cases where application firmware does not know port speeds a priori by relaying this information from the management firmware to the application firmware. This allows the existing mechanism, whereby the driver reports port speeds to user-space as provided by the application firmware, to work in this case. 2. Patch 2/3: - Add support for eeprom get and set command ==================== Link: https://lore.kernel.org/r/20220825141223.22346-1-simon.horman@corigine.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
commit
d287532edf
@ -65,6 +65,7 @@ struct nfp_dumpspec {
|
||||
* @num_vfs: Number of SR-IOV VFs enabled
|
||||
* @fw_loaded: Is the firmware loaded?
|
||||
* @unload_fw_on_remove:Do we need to unload firmware on driver removal?
|
||||
* @sp_indiff: Is the firmware indifferent to physical port speed?
|
||||
* @ctrl_vnic: Pointer to the control vNIC if available
|
||||
* @mip: MIP handle
|
||||
* @rtbl: RTsym table
|
||||
@ -114,6 +115,7 @@ struct nfp_pf {
|
||||
|
||||
bool fw_loaded;
|
||||
bool unload_fw_on_remove;
|
||||
bool sp_indiff;
|
||||
|
||||
struct nfp_net *ctrl_vnic;
|
||||
|
||||
@ -190,4 +192,7 @@ int nfp_shared_buf_pool_set(struct nfp_pf *pf, unsigned int sb,
|
||||
|
||||
int nfp_devlink_params_register(struct nfp_pf *pf);
|
||||
void nfp_devlink_params_unregister(struct nfp_pf *pf);
|
||||
|
||||
unsigned int nfp_net_lr2speed(unsigned int linkrate);
|
||||
unsigned int nfp_net_speed2lr(unsigned int speed);
|
||||
#endif /* NFP_MAIN_H */
|
||||
|
@ -474,19 +474,22 @@ static void nfp_net_read_link_status(struct nfp_net *nn)
|
||||
{
|
||||
unsigned long flags;
|
||||
bool link_up;
|
||||
u32 sts;
|
||||
u16 sts;
|
||||
|
||||
spin_lock_irqsave(&nn->link_status_lock, flags);
|
||||
|
||||
sts = nn_readl(nn, NFP_NET_CFG_STS);
|
||||
sts = nn_readw(nn, NFP_NET_CFG_STS);
|
||||
link_up = !!(sts & NFP_NET_CFG_STS_LINK);
|
||||
|
||||
if (nn->link_up == link_up)
|
||||
goto out;
|
||||
|
||||
nn->link_up = link_up;
|
||||
if (nn->port)
|
||||
if (nn->port) {
|
||||
set_bit(NFP_PORT_CHANGED, &nn->port->flags);
|
||||
if (nn->port->link_cb)
|
||||
nn->port->link_cb(nn->port);
|
||||
}
|
||||
|
||||
if (nn->link_up) {
|
||||
netif_carrier_on(nn->dp.netdev);
|
||||
|
@ -148,6 +148,14 @@ int nfp_net_tlv_caps_parse(struct device *dev, u8 __iomem *ctrl_mem,
|
||||
true))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case NFP_NET_CFG_TLV_TYPE_SP_INDIFF:
|
||||
if (length) {
|
||||
dev_err(dev, "Unexpected len of SP_INDIFF TLV:%u\n", length);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
caps->sp_indiff = true;
|
||||
break;
|
||||
default:
|
||||
if (!FIELD_GET(NFP_NET_CFG_TLV_HEADER_REQUIRED, hdr))
|
||||
break;
|
||||
|
@ -193,6 +193,10 @@
|
||||
#define NFP_NET_CFG_STS_LINK_RATE_40G 5
|
||||
#define NFP_NET_CFG_STS_LINK_RATE_50G 6
|
||||
#define NFP_NET_CFG_STS_LINK_RATE_100G 7
|
||||
/* NSP Link rate is a 16-bit word. It's determined by NSP and
|
||||
* written to CFG BAR by NFP driver.
|
||||
*/
|
||||
#define NFP_NET_CFG_STS_NSP_LINK_RATE 0x0036
|
||||
#define NFP_NET_CFG_CAP 0x0038
|
||||
#define NFP_NET_CFG_MAX_TXRINGS 0x003c
|
||||
#define NFP_NET_CFG_MAX_RXRINGS 0x0040
|
||||
@ -488,6 +492,10 @@
|
||||
* %NFP_NET_CFG_TLV_TYPE_CRYPTO_OPS_RX_SCAN:
|
||||
* Same as %NFP_NET_CFG_TLV_TYPE_CRYPTO_OPS, but crypto TLS does stream scan
|
||||
* RX sync, rather than kernel-assisted sync.
|
||||
*
|
||||
* %NFP_NET_CFG_TLV_TYPE_SP_INDIFF:
|
||||
* Empty, indicate the firmware is indifferent to port speed. Then no need to
|
||||
* reload driver and firmware when port speed is changed.
|
||||
*/
|
||||
#define NFP_NET_CFG_TLV_TYPE_UNKNOWN 0
|
||||
#define NFP_NET_CFG_TLV_TYPE_RESERVED 1
|
||||
@ -501,6 +509,7 @@
|
||||
#define NFP_NET_CFG_TLV_TYPE_CRYPTO_OPS 11 /* see crypto/fw.h */
|
||||
#define NFP_NET_CFG_TLV_TYPE_VNIC_STATS 12
|
||||
#define NFP_NET_CFG_TLV_TYPE_CRYPTO_OPS_RX_SCAN 13
|
||||
#define NFP_NET_CFG_TLV_TYPE_SP_INDIFF 14
|
||||
|
||||
struct device;
|
||||
|
||||
@ -515,6 +524,7 @@ struct device;
|
||||
* @vnic_stats_off: offset of vNIC stats area
|
||||
* @vnic_stats_cnt: number of vNIC stats
|
||||
* @tls_resync_ss: TLS resync will be performed via stream scan
|
||||
* @sp_indiff: Firmware is indifferent to port speed
|
||||
*/
|
||||
struct nfp_net_tlv_caps {
|
||||
u32 me_freq_mhz;
|
||||
@ -527,6 +537,7 @@ struct nfp_net_tlv_caps {
|
||||
unsigned int vnic_stats_off;
|
||||
unsigned int vnic_stats_cnt;
|
||||
unsigned int tls_resync_ss:1;
|
||||
unsigned int sp_indiff:1;
|
||||
};
|
||||
|
||||
int nfp_net_tlv_caps_parse(struct device *dev, u8 __iomem *ctrl_mem,
|
||||
|
@ -273,20 +273,11 @@ static int
|
||||
nfp_net_get_link_ksettings(struct net_device *netdev,
|
||||
struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
static const u32 ls_to_ethtool[] = {
|
||||
[NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED] = 0,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_UNKNOWN] = SPEED_UNKNOWN,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_1G] = SPEED_1000,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_10G] = SPEED_10000,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_25G] = SPEED_25000,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_40G] = SPEED_40000,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_50G] = SPEED_50000,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_100G] = SPEED_100000,
|
||||
};
|
||||
struct nfp_eth_table_port *eth_port;
|
||||
struct nfp_port *port;
|
||||
struct nfp_net *nn;
|
||||
u32 sts, ls;
|
||||
unsigned int speed;
|
||||
u16 sts;
|
||||
|
||||
/* Init to unknowns */
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
|
||||
@ -319,18 +310,15 @@ nfp_net_get_link_ksettings(struct net_device *netdev,
|
||||
return -EOPNOTSUPP;
|
||||
nn = netdev_priv(netdev);
|
||||
|
||||
sts = nn_readl(nn, NFP_NET_CFG_STS);
|
||||
|
||||
ls = FIELD_GET(NFP_NET_CFG_STS_LINK_RATE, sts);
|
||||
if (ls == NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED)
|
||||
sts = nn_readw(nn, NFP_NET_CFG_STS);
|
||||
speed = nfp_net_lr2speed(FIELD_GET(NFP_NET_CFG_STS_LINK_RATE, sts));
|
||||
if (!speed)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (ls == NFP_NET_CFG_STS_LINK_RATE_UNKNOWN ||
|
||||
ls >= ARRAY_SIZE(ls_to_ethtool))
|
||||
return 0;
|
||||
|
||||
cmd->base.speed = ls_to_ethtool[ls];
|
||||
cmd->base.duplex = DUPLEX_FULL;
|
||||
if (speed != SPEED_UNKNOWN) {
|
||||
cmd->base.speed = speed;
|
||||
cmd->base.duplex = DUPLEX_FULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1676,6 +1664,160 @@ static int nfp_net_set_phys_id(struct net_device *netdev,
|
||||
return err;
|
||||
}
|
||||
|
||||
#define NFP_EEPROM_LEN ETH_ALEN
|
||||
|
||||
static int
|
||||
nfp_net_get_eeprom_len(struct net_device *netdev)
|
||||
{
|
||||
struct nfp_eth_table_port *eth_port;
|
||||
struct nfp_port *port;
|
||||
|
||||
port = nfp_port_from_netdev(netdev);
|
||||
eth_port = __nfp_port_get_eth_port(port);
|
||||
if (!eth_port)
|
||||
return 0;
|
||||
|
||||
return NFP_EEPROM_LEN;
|
||||
}
|
||||
|
||||
static int
|
||||
nfp_net_get_nsp_hwindex(struct net_device *netdev,
|
||||
struct nfp_nsp **nspptr,
|
||||
u32 *index)
|
||||
{
|
||||
struct nfp_eth_table_port *eth_port;
|
||||
struct nfp_port *port;
|
||||
struct nfp_nsp *nsp;
|
||||
int err;
|
||||
|
||||
port = nfp_port_from_netdev(netdev);
|
||||
eth_port = __nfp_port_get_eth_port(port);
|
||||
if (!eth_port)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
nsp = nfp_nsp_open(port->app->cpp);
|
||||
if (IS_ERR(nsp)) {
|
||||
err = PTR_ERR(nsp);
|
||||
netdev_err(netdev, "Failed to access the NSP: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!nfp_nsp_has_hwinfo_lookup(nsp)) {
|
||||
netdev_err(netdev, "NSP doesn't support PF MAC generation\n");
|
||||
nfp_nsp_close(nsp);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
*nspptr = nsp;
|
||||
*index = eth_port->eth_index;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nfp_net_get_port_mac_by_hwinfo(struct net_device *netdev,
|
||||
u8 *mac_addr)
|
||||
{
|
||||
char hwinfo[32] = {};
|
||||
struct nfp_nsp *nsp;
|
||||
u32 index;
|
||||
int err;
|
||||
|
||||
err = nfp_net_get_nsp_hwindex(netdev, &nsp, &index);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
snprintf(hwinfo, sizeof(hwinfo), "eth%u.mac", index);
|
||||
err = nfp_nsp_hwinfo_lookup(nsp, hwinfo, sizeof(hwinfo));
|
||||
nfp_nsp_close(nsp);
|
||||
if (err) {
|
||||
netdev_err(netdev, "Reading persistent MAC address failed: %d\n",
|
||||
err);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (sscanf(hwinfo, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
|
||||
&mac_addr[0], &mac_addr[1], &mac_addr[2],
|
||||
&mac_addr[3], &mac_addr[4], &mac_addr[5]) != 6) {
|
||||
netdev_err(netdev, "Can't parse persistent MAC address (%s)\n",
|
||||
hwinfo);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nfp_net_set_port_mac_by_hwinfo(struct net_device *netdev,
|
||||
u8 *mac_addr)
|
||||
{
|
||||
char hwinfo[32] = {};
|
||||
struct nfp_nsp *nsp;
|
||||
u32 index;
|
||||
int err;
|
||||
|
||||
err = nfp_net_get_nsp_hwindex(netdev, &nsp, &index);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
snprintf(hwinfo, sizeof(hwinfo),
|
||||
"eth%u.mac=%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
|
||||
index, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
|
||||
mac_addr[4], mac_addr[5]);
|
||||
|
||||
err = nfp_nsp_hwinfo_set(nsp, hwinfo, sizeof(hwinfo));
|
||||
nfp_nsp_close(nsp);
|
||||
if (err) {
|
||||
netdev_err(netdev, "HWinfo set failed: %d, hwinfo: %s\n",
|
||||
err, hwinfo);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nfp_net_get_eeprom(struct net_device *netdev,
|
||||
struct ethtool_eeprom *eeprom, u8 *bytes)
|
||||
{
|
||||
struct nfp_net *nn = netdev_priv(netdev);
|
||||
u8 buf[NFP_EEPROM_LEN] = {};
|
||||
|
||||
if (eeprom->len == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (nfp_net_get_port_mac_by_hwinfo(netdev, buf))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
eeprom->magic = nn->pdev->vendor | (nn->pdev->device << 16);
|
||||
memcpy(bytes, buf + eeprom->offset, eeprom->len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nfp_net_set_eeprom(struct net_device *netdev,
|
||||
struct ethtool_eeprom *eeprom, u8 *bytes)
|
||||
{
|
||||
struct nfp_net *nn = netdev_priv(netdev);
|
||||
u8 buf[NFP_EEPROM_LEN] = {};
|
||||
|
||||
if (eeprom->len == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (eeprom->magic != (nn->pdev->vendor | nn->pdev->device << 16))
|
||||
return -EINVAL;
|
||||
|
||||
if (nfp_net_get_port_mac_by_hwinfo(netdev, buf))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
memcpy(buf + eeprom->offset, bytes, eeprom->len);
|
||||
if (nfp_net_set_port_mac_by_hwinfo(netdev, buf))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ethtool_ops nfp_net_ethtool_ops = {
|
||||
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
|
||||
ETHTOOL_COALESCE_MAX_FRAMES |
|
||||
@ -1699,6 +1841,9 @@ static const struct ethtool_ops nfp_net_ethtool_ops = {
|
||||
.set_dump = nfp_app_set_dump,
|
||||
.get_dump_flag = nfp_app_get_dump_flag,
|
||||
.get_dump_data = nfp_app_get_dump_data,
|
||||
.get_eeprom_len = nfp_net_get_eeprom_len,
|
||||
.get_eeprom = nfp_net_get_eeprom,
|
||||
.set_eeprom = nfp_net_set_eeprom,
|
||||
.get_module_info = nfp_port_get_module_info,
|
||||
.get_module_eeprom = nfp_port_get_module_eeprom,
|
||||
.get_coalesce = nfp_net_get_coalesce,
|
||||
|
@ -202,7 +202,11 @@ nfp_net_pf_alloc_vnics(struct nfp_pf *pf, void __iomem *ctrl_bar,
|
||||
goto err_free_prev;
|
||||
}
|
||||
|
||||
if (nn->port)
|
||||
nn->port->link_cb = nfp_net_refresh_port_table;
|
||||
|
||||
ctrl_bar += NFP_PF_CSR_SLICE_SIZE;
|
||||
pf->sp_indiff |= nn->tlv_caps.sp_indiff;
|
||||
|
||||
/* Kill the vNIC if app init marked it as invalid */
|
||||
if (nn->port && nn->port->type == NFP_PORT_INVALID)
|
||||
@ -304,6 +308,37 @@ err_prev_deinit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nfp_net_pf_cfg_nsp(struct nfp_pf *pf, bool sp_indiff)
|
||||
{
|
||||
struct nfp_nsp *nsp;
|
||||
char hwinfo[32];
|
||||
int err;
|
||||
|
||||
nsp = nfp_nsp_open(pf->cpp);
|
||||
if (IS_ERR(nsp)) {
|
||||
err = PTR_ERR(nsp);
|
||||
return err;
|
||||
}
|
||||
|
||||
snprintf(hwinfo, sizeof(hwinfo), "sp_indiff=%d", sp_indiff);
|
||||
err = nfp_nsp_hwinfo_set(nsp, hwinfo, sizeof(hwinfo));
|
||||
if (err)
|
||||
nfp_warn(pf->cpp, "HWinfo(sp_indiff=%d) set failed: %d\n", sp_indiff, err);
|
||||
|
||||
nfp_nsp_close(nsp);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nfp_net_pf_init_nsp(struct nfp_pf *pf)
|
||||
{
|
||||
return nfp_net_pf_cfg_nsp(pf, pf->sp_indiff);
|
||||
}
|
||||
|
||||
static void nfp_net_pf_clean_nsp(struct nfp_pf *pf)
|
||||
{
|
||||
(void)nfp_net_pf_cfg_nsp(pf, false);
|
||||
}
|
||||
|
||||
static int
|
||||
nfp_net_pf_app_init(struct nfp_pf *pf, u8 __iomem *qc_bar, unsigned int stride)
|
||||
{
|
||||
@ -315,6 +350,8 @@ nfp_net_pf_app_init(struct nfp_pf *pf, u8 __iomem *qc_bar, unsigned int stride)
|
||||
if (IS_ERR(pf->app))
|
||||
return PTR_ERR(pf->app);
|
||||
|
||||
pf->sp_indiff |= pf->app->type->id == NFP_APP_FLOWER_NIC;
|
||||
|
||||
devl_lock(devlink);
|
||||
err = nfp_app_init(pf->app);
|
||||
devl_unlock(devlink);
|
||||
@ -523,6 +560,57 @@ err_unmap_ctrl:
|
||||
return err;
|
||||
}
|
||||
|
||||
static const unsigned int lr_to_speed[] = {
|
||||
[NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED] = 0,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_UNKNOWN] = SPEED_UNKNOWN,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_1G] = SPEED_1000,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_10G] = SPEED_10000,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_25G] = SPEED_25000,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_40G] = SPEED_40000,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_50G] = SPEED_50000,
|
||||
[NFP_NET_CFG_STS_LINK_RATE_100G] = SPEED_100000,
|
||||
};
|
||||
|
||||
unsigned int nfp_net_lr2speed(unsigned int linkrate)
|
||||
{
|
||||
if (linkrate < ARRAY_SIZE(lr_to_speed))
|
||||
return lr_to_speed[linkrate];
|
||||
|
||||
return SPEED_UNKNOWN;
|
||||
}
|
||||
|
||||
unsigned int nfp_net_speed2lr(unsigned int speed)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(lr_to_speed); i++) {
|
||||
if (speed == lr_to_speed[i])
|
||||
return i;
|
||||
}
|
||||
|
||||
return NFP_NET_CFG_STS_LINK_RATE_UNKNOWN;
|
||||
}
|
||||
|
||||
static void nfp_net_notify_port_speed(struct nfp_port *port)
|
||||
{
|
||||
struct net_device *netdev = port->netdev;
|
||||
struct nfp_net *nn;
|
||||
u16 sts;
|
||||
|
||||
if (!nfp_netdev_is_nfp_net(netdev))
|
||||
return;
|
||||
|
||||
nn = netdev_priv(netdev);
|
||||
sts = nn_readw(nn, NFP_NET_CFG_STS);
|
||||
|
||||
if (!(sts & NFP_NET_CFG_STS_LINK)) {
|
||||
nn_writew(nn, NFP_NET_CFG_STS_NSP_LINK_RATE, NFP_NET_CFG_STS_LINK_RATE_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
nn_writew(nn, NFP_NET_CFG_STS_NSP_LINK_RATE, nfp_net_speed2lr(port->eth_port->speed));
|
||||
}
|
||||
|
||||
static int
|
||||
nfp_net_eth_port_update(struct nfp_cpp *cpp, struct nfp_port *port,
|
||||
struct nfp_eth_table *eth_table)
|
||||
@ -544,6 +632,7 @@ nfp_net_eth_port_update(struct nfp_cpp *cpp, struct nfp_port *port,
|
||||
}
|
||||
|
||||
memcpy(port->eth_port, eth_port, sizeof(*eth_port));
|
||||
nfp_net_notify_port_speed(port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -725,10 +814,14 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
|
||||
if (err)
|
||||
goto err_clean_ddir;
|
||||
|
||||
err = nfp_net_pf_alloc_irqs(pf);
|
||||
err = nfp_net_pf_init_nsp(pf);
|
||||
if (err)
|
||||
goto err_free_vnics;
|
||||
|
||||
err = nfp_net_pf_alloc_irqs(pf);
|
||||
if (err)
|
||||
goto err_clean_nsp;
|
||||
|
||||
err = nfp_net_pf_app_start(pf);
|
||||
if (err)
|
||||
goto err_free_irqs;
|
||||
@ -746,6 +839,8 @@ err_stop_app:
|
||||
nfp_net_pf_app_stop(pf);
|
||||
err_free_irqs:
|
||||
nfp_net_pf_free_irqs(pf);
|
||||
err_clean_nsp:
|
||||
nfp_net_pf_clean_nsp(pf);
|
||||
err_free_vnics:
|
||||
nfp_net_pf_free_vnics(pf);
|
||||
err_clean_ddir:
|
||||
@ -776,6 +871,7 @@ void nfp_net_pci_remove(struct nfp_pf *pf)
|
||||
nfp_net_pf_free_vnic(pf, nn);
|
||||
}
|
||||
|
||||
nfp_net_pf_clean_nsp(pf);
|
||||
nfp_net_pf_app_stop(pf);
|
||||
/* stop app first, to avoid double free of ctrl vNIC's ddir */
|
||||
nfp_net_debugfs_dir_clean(&pf->ddir);
|
||||
|
@ -46,6 +46,7 @@ enum nfp_port_flags {
|
||||
* @tc_offload_cnt: number of active TC offloads, how offloads are counted
|
||||
* is not defined, use as a boolean
|
||||
* @app: backpointer to the app structure
|
||||
* @link_cb: callback when link status changed
|
||||
* @dl_port: devlink port structure
|
||||
* @eth_id: for %NFP_PORT_PHYS_PORT port ID in NFP enumeration scheme
|
||||
* @eth_forced: for %NFP_PORT_PHYS_PORT port is forced UP or DOWN, don't change
|
||||
@ -66,6 +67,7 @@ struct nfp_port {
|
||||
unsigned long tc_offload_cnt;
|
||||
|
||||
struct nfp_app *app;
|
||||
void (*link_cb)(struct nfp_port *port);
|
||||
|
||||
struct devlink_port dl_port;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user