Commit cc30c634 authored by David S. Miller's avatar David S. Miller

Merge branch 'i40e-devlink'

Ivan Vecera says:

====================
i40e: Add basic devlink support

The series adds initial support for devlink to i40e driver.

Patch-set overview:
Patch 1: Adds initial devlink support (devlink and port registration)
Patch 2: Refactors and split i40e_nvm_version_str()
Patch 3: Adds support for 'devlink dev info'
Patch 4: Refactors existing helper function to read PBA ID
Patch 5: Adds 'board.id' to 'devlink dev info' using PBA ID
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b22f21f7 3e02480d
...@@ -225,6 +225,7 @@ config I40E ...@@ -225,6 +225,7 @@ config I40E
depends on PTP_1588_CLOCK_OPTIONAL depends on PTP_1588_CLOCK_OPTIONAL
depends on PCI depends on PCI
select AUXILIARY_BUS select AUXILIARY_BUS
select NET_DEVLINK
help help
This driver supports Intel(R) Ethernet Controller XL710 Family of This driver supports Intel(R) Ethernet Controller XL710 Family of
devices. For more information on how to identify your adapter, go devices. For more information on how to identify your adapter, go
......
...@@ -24,6 +24,7 @@ i40e-objs := i40e_main.o \ ...@@ -24,6 +24,7 @@ i40e-objs := i40e_main.o \
i40e_ddp.o \ i40e_ddp.o \
i40e_client.o \ i40e_client.o \
i40e_virtchnl_pf.o \ i40e_virtchnl_pf.o \
i40e_xsk.o i40e_xsk.o \
i40e_devlink.o
i40e-$(CONFIG_I40E_DCB) += i40e_dcb.o i40e_dcb_nl.o i40e-$(CONFIG_I40E_DCB) += i40e_dcb.o i40e_dcb_nl.o
...@@ -9,10 +9,12 @@ ...@@ -9,10 +9,12 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/avf/virtchnl.h> #include <linux/avf/virtchnl.h>
#include <linux/net/intel/i40e_client.h> #include <linux/net/intel/i40e_client.h>
#include <net/devlink.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/udp_tunnel.h> #include <net/udp_tunnel.h>
#include "i40e_dcb.h" #include "i40e_dcb.h"
#include "i40e_debug.h" #include "i40e_debug.h"
#include "i40e_devlink.h"
#include "i40e_io.h" #include "i40e_io.h"
#include "i40e_prototype.h" #include "i40e_prototype.h"
#include "i40e_register.h" #include "i40e_register.h"
...@@ -47,23 +49,19 @@ ...@@ -47,23 +49,19 @@
#define I40E_QUEUE_WAIT_RETRY_LIMIT 10 #define I40E_QUEUE_WAIT_RETRY_LIMIT 10
#define I40E_INT_NAME_STR_LEN (IFNAMSIZ + 16) #define I40E_INT_NAME_STR_LEN (IFNAMSIZ + 16)
#define I40E_NVM_VERSION_LO_SHIFT 0
#define I40E_NVM_VERSION_LO_MASK (0xff << I40E_NVM_VERSION_LO_SHIFT)
#define I40E_NVM_VERSION_HI_SHIFT 12
#define I40E_NVM_VERSION_HI_MASK (0xf << I40E_NVM_VERSION_HI_SHIFT)
#define I40E_OEM_VER_BUILD_MASK 0xffff
#define I40E_OEM_VER_PATCH_MASK 0xff
#define I40E_OEM_VER_BUILD_SHIFT 8
#define I40E_OEM_VER_SHIFT 24
#define I40E_PHY_DEBUG_ALL \ #define I40E_PHY_DEBUG_ALL \
(I40E_AQ_PHY_DEBUG_DISABLE_LINK_FW | \ (I40E_AQ_PHY_DEBUG_DISABLE_LINK_FW | \
I40E_AQ_PHY_DEBUG_DISABLE_ALL_LINK_FW) I40E_AQ_PHY_DEBUG_DISABLE_ALL_LINK_FW)
#define I40E_OEM_EETRACK_ID 0xffffffff #define I40E_OEM_EETRACK_ID 0xffffffff
#define I40E_OEM_GEN_SHIFT 24 #define I40E_NVM_VERSION_LO_MASK GENMASK(7, 0)
#define I40E_OEM_SNAP_MASK 0x00ff0000 #define I40E_NVM_VERSION_HI_MASK GENMASK(15, 12)
#define I40E_OEM_SNAP_SHIFT 16 #define I40E_OEM_VER_BUILD_MASK GENMASK(23, 8)
#define I40E_OEM_RELEASE_MASK 0x0000ffff #define I40E_OEM_VER_PATCH_MASK GENMASK(7, 0)
#define I40E_OEM_VER_MASK GENMASK(31, 24)
#define I40E_OEM_GEN_MASK GENMASK(31, 24)
#define I40E_OEM_SNAP_MASK GENMASK(23, 16)
#define I40E_OEM_RELEASE_MASK GENMASK(15, 0)
#define I40E_RX_DESC(R, i) \ #define I40E_RX_DESC(R, i) \
(&(((union i40e_rx_desc *)((R)->desc))[i])) (&(((union i40e_rx_desc *)((R)->desc))[i]))
...@@ -411,6 +409,7 @@ static inline const u8 *i40e_channel_mac(struct i40e_channel *ch) ...@@ -411,6 +409,7 @@ static inline const u8 *i40e_channel_mac(struct i40e_channel *ch)
/* struct that defines the Ethernet device */ /* struct that defines the Ethernet device */
struct i40e_pf { struct i40e_pf {
struct pci_dev *pdev; struct pci_dev *pdev;
struct devlink_port devlink_port;
struct i40e_hw hw; struct i40e_hw hw;
DECLARE_BITMAP(state, __I40E_STATE_SIZE__); DECLARE_BITMAP(state, __I40E_STATE_SIZE__);
struct msix_entry *msix_entries; struct msix_entry *msix_entries;
...@@ -951,43 +950,104 @@ struct i40e_device { ...@@ -951,43 +950,104 @@ struct i40e_device {
}; };
/** /**
* i40e_nvm_version_str - format the NVM version strings * i40e_info_nvm_ver - format the NVM version string
* @hw: ptr to the hardware info * @hw: ptr to the hardware info
* @buf: string buffer to store
* @len: buffer size
*
* Formats NVM version string as:
* <gen>.<snap>.<release> when eetrackid == I40E_OEM_EETRACK_ID
* <nvm_major>.<nvm_minor> otherwise
**/ **/
static inline char *i40e_nvm_version_str(struct i40e_hw *hw) static inline void i40e_info_nvm_ver(struct i40e_hw *hw, char *buf, size_t len)
{ {
static char buf[32]; struct i40e_nvm_info *nvm = &hw->nvm;
u32 full_ver;
full_ver = hw->nvm.oem_ver; if (nvm->eetrack == I40E_OEM_EETRACK_ID) {
u32 full_ver = nvm->oem_ver;
if (hw->nvm.eetrack == I40E_OEM_EETRACK_ID) {
u8 gen, snap; u8 gen, snap;
u16 release; u16 release;
gen = (u8)(full_ver >> I40E_OEM_GEN_SHIFT); gen = FIELD_GET(I40E_OEM_GEN_MASK, full_ver);
snap = (u8)((full_ver & I40E_OEM_SNAP_MASK) >> snap = FIELD_GET(I40E_OEM_SNAP_MASK, full_ver);
I40E_OEM_SNAP_SHIFT); release = FIELD_GET(I40E_OEM_RELEASE_MASK, full_ver);
release = (u16)(full_ver & I40E_OEM_RELEASE_MASK); snprintf(buf, len, "%x.%x.%x", gen, snap, release);
snprintf(buf, sizeof(buf), "%x.%x.%x", gen, snap, release);
} else { } else {
u8 ver, patch; u8 major, minor;
major = FIELD_GET(I40E_NVM_VERSION_HI_MASK, nvm->version);
minor = FIELD_GET(I40E_NVM_VERSION_LO_MASK, nvm->version);
snprintf(buf, len, "%x.%02x", major, minor);
}
}
/**
* i40e_info_eetrack - format the EETrackID string
* @hw: ptr to the hardware info
* @buf: string buffer to store
* @len: buffer size
*
* Returns hexadecimally formated EETrackID if it is
* different from I40E_OEM_EETRACK_ID or empty string.
**/
static inline void i40e_info_eetrack(struct i40e_hw *hw, char *buf, size_t len)
{
struct i40e_nvm_info *nvm = &hw->nvm;
buf[0] = '\0';
if (nvm->eetrack != I40E_OEM_EETRACK_ID)
snprintf(buf, len, "0x%08x", nvm->eetrack);
}
/**
* i40e_info_civd_ver - format the NVM version strings
* @hw: ptr to the hardware info
* @buf: string buffer to store
* @len: buffer size
*
* Returns formated combo image version if adapter's EETrackID is
* different from I40E_OEM_EETRACK_ID or empty string.
**/
static inline void i40e_info_civd_ver(struct i40e_hw *hw, char *buf, size_t len)
{
struct i40e_nvm_info *nvm = &hw->nvm;
buf[0] = '\0';
if (nvm->eetrack != I40E_OEM_EETRACK_ID) {
u32 full_ver = nvm->oem_ver;
u8 major, minor;
u16 build; u16 build;
ver = (u8)(full_ver >> I40E_OEM_VER_SHIFT); major = FIELD_GET(I40E_OEM_VER_MASK, full_ver);
build = (u16)((full_ver >> I40E_OEM_VER_BUILD_SHIFT) & build = FIELD_GET(I40E_OEM_VER_BUILD_MASK, full_ver);
I40E_OEM_VER_BUILD_MASK); minor = FIELD_GET(I40E_OEM_VER_PATCH_MASK, full_ver);
patch = (u8)(full_ver & I40E_OEM_VER_PATCH_MASK); snprintf(buf, len, "%d.%d.%d", major, build, minor);
snprintf(buf, sizeof(buf),
"%x.%02x 0x%x %d.%d.%d",
(hw->nvm.version & I40E_NVM_VERSION_HI_MASK) >>
I40E_NVM_VERSION_HI_SHIFT,
(hw->nvm.version & I40E_NVM_VERSION_LO_MASK) >>
I40E_NVM_VERSION_LO_SHIFT,
hw->nvm.eetrack, ver, build, patch);
} }
}
/**
* i40e_nvm_version_str - format the NVM version strings
* @hw: ptr to the hardware info
* @buf: string buffer to store
* @len: buffer size
**/
static inline char *i40e_nvm_version_str(struct i40e_hw *hw, char *buf,
size_t len)
{
char ver[16] = " ";
/* Get NVM version */
i40e_info_nvm_ver(hw, buf, len);
/* Append EETrackID if provided */
i40e_info_eetrack(hw, &ver[1], sizeof(ver) - 1);
if (strlen(ver) > 1)
strlcat(buf, ver, len);
/* Append combo image version if provided */
i40e_info_civd_ver(hw, &ver[1], sizeof(ver) - 1);
if (strlen(ver) > 1)
strlcat(buf, ver, len);
return buf; return buf;
} }
......
...@@ -821,62 +821,72 @@ void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable) ...@@ -821,62 +821,72 @@ void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable)
} }
/** /**
* i40e_read_pba_string - Reads part number string from EEPROM * i40e_get_pba_string - Reads part number string from EEPROM
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
* @pba_num: stores the part number string from the EEPROM
* @pba_num_size: part number string buffer length
* *
* Reads the part number string from the EEPROM. * Reads the part number string from the EEPROM and stores it
* into newly allocated buffer and saves resulting pointer
* to i40e_hw->pba_id field.
**/ **/
int i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num, void i40e_get_pba_string(struct i40e_hw *hw)
u32 pba_num_size)
{ {
#define I40E_NVM_PBA_FLAGS_BLK_PRESENT 0xFAFA
u16 pba_word = 0; u16 pba_word = 0;
u16 pba_size = 0; u16 pba_size = 0;
u16 pba_ptr = 0; u16 pba_ptr = 0;
int status = 0; int status;
u16 i = 0; char *ptr;
u16 i;
status = i40e_read_nvm_word(hw, I40E_SR_PBA_FLAGS, &pba_word); status = i40e_read_nvm_word(hw, I40E_SR_PBA_FLAGS, &pba_word);
if (status || (pba_word != 0xFAFA)) { if (status) {
hw_dbg(hw, "Failed to read PBA flags or flag is invalid.\n"); hw_dbg(hw, "Failed to read PBA flags.\n");
return status; return;
}
if (pba_word != I40E_NVM_PBA_FLAGS_BLK_PRESENT) {
hw_dbg(hw, "PBA block is not present.\n");
return;
} }
status = i40e_read_nvm_word(hw, I40E_SR_PBA_BLOCK_PTR, &pba_ptr); status = i40e_read_nvm_word(hw, I40E_SR_PBA_BLOCK_PTR, &pba_ptr);
if (status) { if (status) {
hw_dbg(hw, "Failed to read PBA Block pointer.\n"); hw_dbg(hw, "Failed to read PBA Block pointer.\n");
return status; return;
} }
status = i40e_read_nvm_word(hw, pba_ptr, &pba_size); status = i40e_read_nvm_word(hw, pba_ptr, &pba_size);
if (status) { if (status) {
hw_dbg(hw, "Failed to read PBA Block size.\n"); hw_dbg(hw, "Failed to read PBA Block size.\n");
return status; return;
} }
/* Subtract one to get PBA word count (PBA Size word is included in /* Subtract one to get PBA word count (PBA Size word is included in
* total size) * total size) and advance pointer to first PBA word.
*/ */
pba_size--; pba_size--;
if (pba_num_size < (((u32)pba_size * 2) + 1)) { pba_ptr++;
hw_dbg(hw, "Buffer too small for PBA data.\n"); if (!pba_size) {
return -EINVAL; hw_dbg(hw, "PBA ID is empty.\n");
return;
} }
ptr = devm_kzalloc(i40e_hw_to_dev(hw), pba_size * 2 + 1, GFP_KERNEL);
if (!ptr)
return;
hw->pba_id = ptr;
for (i = 0; i < pba_size; i++) { for (i = 0; i < pba_size; i++) {
status = i40e_read_nvm_word(hw, (pba_ptr + 1) + i, &pba_word); status = i40e_read_nvm_word(hw, pba_ptr + i, &pba_word);
if (status) { if (status) {
hw_dbg(hw, "Failed to read PBA Block word %d.\n", i); hw_dbg(hw, "Failed to read PBA Block word %d.\n", i);
return status; devm_kfree(i40e_hw_to_dev(hw), hw->pba_id);
hw->pba_id = NULL;
return;
} }
pba_num[(i * 2)] = (pba_word >> 8) & 0xFF; *ptr++ = (pba_word >> 8) & 0xFF;
pba_num[(i * 2) + 1] = pba_word & 0xFF; *ptr++ = pba_word & 0xFF;
} }
pba_num[(pba_size * 2)] = '\0';
return status;
} }
/** /**
......
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2023 Intel Corporation. */
#include <net/devlink.h>
#include "i40e.h"
#include "i40e_devlink.h"
static void i40e_info_get_dsn(struct i40e_pf *pf, char *buf, size_t len)
{
u8 dsn[8];
put_unaligned_be64(pci_get_dsn(pf->pdev), dsn);
snprintf(buf, len, "%8phD", dsn);
}
static void i40e_info_fw_mgmt(struct i40e_hw *hw, char *buf, size_t len)
{
struct i40e_adminq_info *aq = &hw->aq;
snprintf(buf, len, "%u.%u.%05d",
aq->fw_maj_ver, aq->fw_min_ver, aq->fw_build);
}
static void i40e_info_fw_api(struct i40e_hw *hw, char *buf, size_t len)
{
struct i40e_adminq_info *aq = &hw->aq;
snprintf(buf, len, "%u.%u", aq->api_maj_ver, aq->api_min_ver);
}
static void i40e_info_pba(struct i40e_hw *hw, char *buf, size_t len)
{
buf[0] = '\0';
if (hw->pba_id)
strscpy(buf, hw->pba_id, len);
}
enum i40e_devlink_version_type {
I40E_DL_VERSION_FIXED,
I40E_DL_VERSION_RUNNING,
};
static int i40e_devlink_info_put(struct devlink_info_req *req,
enum i40e_devlink_version_type type,
const char *key, const char *value)
{
if (!strlen(value))
return 0;
switch (type) {
case I40E_DL_VERSION_FIXED:
return devlink_info_version_fixed_put(req, key, value);
case I40E_DL_VERSION_RUNNING:
return devlink_info_version_running_put(req, key, value);
}
return 0;
}
static int i40e_devlink_info_get(struct devlink *dl,
struct devlink_info_req *req,
struct netlink_ext_ack *extack)
{
struct i40e_pf *pf = devlink_priv(dl);
struct i40e_hw *hw = &pf->hw;
char buf[32];
int err;
i40e_info_get_dsn(pf, buf, sizeof(buf));
err = devlink_info_serial_number_put(req, buf);
if (err)
return err;
i40e_info_fw_mgmt(hw, buf, sizeof(buf));
err = i40e_devlink_info_put(req, I40E_DL_VERSION_RUNNING,
DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, buf);
if (err)
return err;
i40e_info_fw_api(hw, buf, sizeof(buf));
err = i40e_devlink_info_put(req, I40E_DL_VERSION_RUNNING,
DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API,
buf);
if (err)
return err;
i40e_info_nvm_ver(hw, buf, sizeof(buf));
err = i40e_devlink_info_put(req, I40E_DL_VERSION_RUNNING,
DEVLINK_INFO_VERSION_GENERIC_FW_PSID, buf);
if (err)
return err;
i40e_info_eetrack(hw, buf, sizeof(buf));
err = i40e_devlink_info_put(req, I40E_DL_VERSION_RUNNING,
DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID,
buf);
if (err)
return err;
i40e_info_civd_ver(hw, buf, sizeof(buf));
err = i40e_devlink_info_put(req, I40E_DL_VERSION_RUNNING,
DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, buf);
if (err)
return err;
i40e_info_pba(hw, buf, sizeof(buf));
err = i40e_devlink_info_put(req, I40E_DL_VERSION_FIXED,
DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, buf);
return err;
}
static const struct devlink_ops i40e_devlink_ops = {
.info_get = i40e_devlink_info_get,
};
/**
* i40e_alloc_pf - Allocate devlink and return i40e_pf structure pointer
* @dev: the device to allocate for
*
* Allocate a devlink instance for this device and return the private
* area as the i40e_pf structure.
**/
struct i40e_pf *i40e_alloc_pf(struct device *dev)
{
struct devlink *devlink;
devlink = devlink_alloc(&i40e_devlink_ops, sizeof(struct i40e_pf), dev);
if (!devlink)
return NULL;
return devlink_priv(devlink);
}
/**
* i40e_free_pf - Free i40e_pf structure and associated devlink
* @pf: the PF structure
*
* Free i40e_pf structure and devlink allocated by devlink_alloc.
**/
void i40e_free_pf(struct i40e_pf *pf)
{
struct devlink *devlink = priv_to_devlink(pf);
devlink_free(devlink);
}
/**
* i40e_devlink_register - Register devlink interface for this PF
* @pf: the PF to register the devlink for.
*
* Register the devlink instance associated with this physical function.
**/
void i40e_devlink_register(struct i40e_pf *pf)
{
devlink_register(priv_to_devlink(pf));
}
/**
* i40e_devlink_unregister - Unregister devlink resources for this PF.
* @pf: the PF structure to cleanup
*
* Releases resources used by devlink and cleans up associated memory.
**/
void i40e_devlink_unregister(struct i40e_pf *pf)
{
devlink_unregister(priv_to_devlink(pf));
}
/**
* i40e_devlink_set_switch_id - Set unique switch id based on pci dsn
* @pf: the PF to create a devlink port for
* @ppid: struct with switch id information
*/
static void i40e_devlink_set_switch_id(struct i40e_pf *pf,
struct netdev_phys_item_id *ppid)
{
u64 id = pci_get_dsn(pf->pdev);
ppid->id_len = sizeof(id);
put_unaligned_be64(id, &ppid->id);
}
/**
* i40e_devlink_create_port - Create a devlink port for this PF
* @pf: the PF to create a port for
*
* Create and register a devlink_port for this PF. Note that although each
* physical function is connected to a separate devlink instance, the port
* will still be numbered according to the physical function id.
*
* Return: zero on success or an error code on failure.
**/
int i40e_devlink_create_port(struct i40e_pf *pf)
{
struct devlink *devlink = priv_to_devlink(pf);
struct devlink_port_attrs attrs = {};
struct device *dev = &pf->pdev->dev;
int err;
attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
attrs.phys.port_number = pf->hw.pf_id;
i40e_devlink_set_switch_id(pf, &attrs.switch_id);
devlink_port_attrs_set(&pf->devlink_port, &attrs);
err = devlink_port_register(devlink, &pf->devlink_port, pf->hw.pf_id);
if (err) {
dev_err(dev, "devlink_port_register failed: %d\n", err);
return err;
}
return 0;
}
/**
* i40e_devlink_destroy_port - Destroy the devlink_port for this PF
* @pf: the PF to cleanup
*
* Unregisters the devlink_port structure associated with this PF.
**/
void i40e_devlink_destroy_port(struct i40e_pf *pf)
{
devlink_port_type_clear(&pf->devlink_port);
devlink_port_unregister(&pf->devlink_port);
}
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2023, Intel Corporation. */
#ifndef _I40E_DEVLINK_H_
#define _I40E_DEVLINK_H_
#include <linux/device.h>
struct i40e_pf;
struct i40e_pf *i40e_alloc_pf(struct device *dev);
void i40e_free_pf(struct i40e_pf *pf);
void i40e_devlink_register(struct i40e_pf *pf);
void i40e_devlink_unregister(struct i40e_pf *pf);
int i40e_devlink_create_port(struct i40e_pf *pf);
void i40e_devlink_destroy_port(struct i40e_pf *pf);
#endif /* _I40E_DEVLINK_H_ */
...@@ -2006,8 +2006,8 @@ static void i40e_get_drvinfo(struct net_device *netdev, ...@@ -2006,8 +2006,8 @@ static void i40e_get_drvinfo(struct net_device *netdev,
struct i40e_pf *pf = vsi->back; struct i40e_pf *pf = vsi->back;
strscpy(drvinfo->driver, i40e_driver_name, sizeof(drvinfo->driver)); strscpy(drvinfo->driver, i40e_driver_name, sizeof(drvinfo->driver));
strscpy(drvinfo->fw_version, i40e_nvm_version_str(&pf->hw), i40e_nvm_version_str(&pf->hw, drvinfo->fw_version,
sizeof(drvinfo->fw_version)); sizeof(drvinfo->fw_version));
strscpy(drvinfo->bus_info, pci_name(pf->pdev), strscpy(drvinfo->bus_info, pci_name(pf->pdev),
sizeof(drvinfo->bus_info)); sizeof(drvinfo->bus_info));
drvinfo->n_priv_flags = I40E_PRIV_FLAGS_STR_LEN; drvinfo->n_priv_flags = I40E_PRIV_FLAGS_STR_LEN;
......
...@@ -10798,7 +10798,9 @@ static void i40e_get_oem_version(struct i40e_hw *hw) ...@@ -10798,7 +10798,9 @@ static void i40e_get_oem_version(struct i40e_hw *hw)
&gen_snap); &gen_snap);
i40e_read_nvm_word(hw, block_offset + I40E_NVM_OEM_RELEASE_OFFSET, i40e_read_nvm_word(hw, block_offset + I40E_NVM_OEM_RELEASE_OFFSET,
&release); &release);
hw->nvm.oem_ver = (gen_snap << I40E_OEM_SNAP_SHIFT) | release; hw->nvm.oem_ver =
FIELD_PREP(I40E_OEM_GEN_MASK | I40E_OEM_SNAP_MASK, gen_snap) |
FIELD_PREP(I40E_OEM_RELEASE_MASK, release);
hw->nvm.eetrack = I40E_OEM_EETRACK_ID; hw->nvm.eetrack = I40E_OEM_EETRACK_ID;
} }
...@@ -14211,6 +14213,8 @@ int i40e_vsi_release(struct i40e_vsi *vsi) ...@@ -14211,6 +14213,8 @@ int i40e_vsi_release(struct i40e_vsi *vsi)
} }
set_bit(__I40E_VSI_RELEASING, vsi->state); set_bit(__I40E_VSI_RELEASING, vsi->state);
uplink_seid = vsi->uplink_seid; uplink_seid = vsi->uplink_seid;
if (vsi->type == I40E_VSI_MAIN)
i40e_devlink_destroy_port(pf);
if (vsi->type != I40E_VSI_SRIOV) { if (vsi->type != I40E_VSI_SRIOV) {
if (vsi->netdev_registered) { if (vsi->netdev_registered) {
vsi->netdev_registered = false; vsi->netdev_registered = false;
...@@ -14398,6 +14402,8 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi) ...@@ -14398,6 +14402,8 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
err_rings: err_rings:
i40e_vsi_free_q_vectors(vsi); i40e_vsi_free_q_vectors(vsi);
if (vsi->type == I40E_VSI_MAIN)
i40e_devlink_destroy_port(pf);
if (vsi->netdev_registered) { if (vsi->netdev_registered) {
vsi->netdev_registered = false; vsi->netdev_registered = false;
unregister_netdev(vsi->netdev); unregister_netdev(vsi->netdev);
...@@ -14544,9 +14550,15 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type, ...@@ -14544,9 +14550,15 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
ret = i40e_netif_set_realnum_tx_rx_queues(vsi); ret = i40e_netif_set_realnum_tx_rx_queues(vsi);
if (ret) if (ret)
goto err_netdev; goto err_netdev;
if (vsi->type == I40E_VSI_MAIN) {
ret = i40e_devlink_create_port(pf);
if (ret)
goto err_netdev;
SET_NETDEV_DEVLINK_PORT(vsi->netdev, &pf->devlink_port);
}
ret = register_netdev(vsi->netdev); ret = register_netdev(vsi->netdev);
if (ret) if (ret)
goto err_netdev; goto err_dl_port;
vsi->netdev_registered = true; vsi->netdev_registered = true;
netif_carrier_off(vsi->netdev); netif_carrier_off(vsi->netdev);
#ifdef CONFIG_I40E_DCB #ifdef CONFIG_I40E_DCB
...@@ -14589,6 +14601,9 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type, ...@@ -14589,6 +14601,9 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
free_netdev(vsi->netdev); free_netdev(vsi->netdev);
vsi->netdev = NULL; vsi->netdev = NULL;
} }
err_dl_port:
if (vsi->type == I40E_VSI_MAIN)
i40e_devlink_destroy_port(pf);
err_netdev: err_netdev:
i40e_aq_delete_element(&pf->hw, vsi->seid, NULL); i40e_aq_delete_element(&pf->hw, vsi->seid, NULL);
err_vsi: err_vsi:
...@@ -15619,7 +15634,7 @@ static int i40e_init_recovery_mode(struct i40e_pf *pf, struct i40e_hw *hw) ...@@ -15619,7 +15634,7 @@ static int i40e_init_recovery_mode(struct i40e_pf *pf, struct i40e_hw *hw)
iounmap(hw->hw_addr); iounmap(hw->hw_addr);
pci_release_mem_regions(pf->pdev); pci_release_mem_regions(pf->pdev);
pci_disable_device(pf->pdev); pci_disable_device(pf->pdev);
kfree(pf); i40e_free_pf(pf);
return err; return err;
} }
...@@ -15661,6 +15676,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -15661,6 +15676,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct i40e_hw *hw; struct i40e_hw *hw;
static u16 pfs_found; static u16 pfs_found;
u16 wol_nvm_bits; u16 wol_nvm_bits;
char nvm_ver[32];
u16 link_status; u16 link_status;
#ifdef CONFIG_I40E_DCB #ifdef CONFIG_I40E_DCB
int status; int status;
...@@ -15696,7 +15712,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -15696,7 +15712,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* the Admin Queue structures and then querying for the * the Admin Queue structures and then querying for the
* device's current profile information. * device's current profile information.
*/ */
pf = kzalloc(sizeof(*pf), GFP_KERNEL); pf = i40e_alloc_pf(&pdev->dev);
if (!pf) { if (!pf) {
err = -ENOMEM; err = -ENOMEM;
goto err_pf_alloc; goto err_pf_alloc;
...@@ -15830,13 +15846,15 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -15830,13 +15846,15 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_pf_reset; goto err_pf_reset;
} }
i40e_get_oem_version(hw); i40e_get_oem_version(hw);
i40e_get_pba_string(hw);
/* provide nvm, fw, api versions, vendor:device id, subsys vendor:device id */ /* provide nvm, fw, api versions, vendor:device id, subsys vendor:device id */
i40e_nvm_version_str(hw, nvm_ver, sizeof(nvm_ver));
dev_info(&pdev->dev, "fw %d.%d.%05d api %d.%d nvm %s [%04x:%04x] [%04x:%04x]\n", dev_info(&pdev->dev, "fw %d.%d.%05d api %d.%d nvm %s [%04x:%04x] [%04x:%04x]\n",
hw->aq.fw_maj_ver, hw->aq.fw_min_ver, hw->aq.fw_build, hw->aq.fw_maj_ver, hw->aq.fw_min_ver, hw->aq.fw_build,
hw->aq.api_maj_ver, hw->aq.api_min_ver, hw->aq.api_maj_ver, hw->aq.api_min_ver, nvm_ver,
i40e_nvm_version_str(hw), hw->vendor_id, hw->device_id, hw->vendor_id, hw->device_id, hw->subsystem_vendor_id,
hw->subsystem_vendor_id, hw->subsystem_device_id); hw->subsystem_device_id);
if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR && if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
hw->aq.api_min_ver > I40E_FW_MINOR_VERSION(hw)) hw->aq.api_min_ver > I40E_FW_MINOR_VERSION(hw))
...@@ -16223,6 +16241,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -16223,6 +16241,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* print a string summarizing features */ /* print a string summarizing features */
i40e_print_features(pf); i40e_print_features(pf);
i40e_devlink_register(pf);
return 0; return 0;
/* Unwind what we've done if something failed in the setup */ /* Unwind what we've done if something failed in the setup */
...@@ -16243,7 +16263,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -16243,7 +16263,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err_pf_reset: err_pf_reset:
iounmap(hw->hw_addr); iounmap(hw->hw_addr);
err_ioremap: err_ioremap:
kfree(pf); i40e_free_pf(pf);
err_pf_alloc: err_pf_alloc:
pci_release_mem_regions(pdev); pci_release_mem_regions(pdev);
err_pci_reg: err_pci_reg:
...@@ -16268,6 +16288,8 @@ static void i40e_remove(struct pci_dev *pdev) ...@@ -16268,6 +16288,8 @@ static void i40e_remove(struct pci_dev *pdev)
int ret_code; int ret_code;
int i; int i;
i40e_devlink_unregister(pf);
i40e_dbg_pf_exit(pf); i40e_dbg_pf_exit(pf);
i40e_ptp_stop(pf); i40e_ptp_stop(pf);
...@@ -16393,7 +16415,7 @@ static void i40e_remove(struct pci_dev *pdev) ...@@ -16393,7 +16415,7 @@ static void i40e_remove(struct pci_dev *pdev)
kfree(pf->vsi); kfree(pf->vsi);
iounmap(hw->hw_addr); iounmap(hw->hw_addr);
kfree(pf); i40e_free_pf(pf);
pci_release_mem_regions(pdev); pci_release_mem_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
......
...@@ -341,8 +341,7 @@ i40e_aq_configure_partition_bw(struct i40e_hw *hw, ...@@ -341,8 +341,7 @@ i40e_aq_configure_partition_bw(struct i40e_hw *hw,
struct i40e_aqc_configure_partition_bw_data *bw_data, struct i40e_aqc_configure_partition_bw_data *bw_data,
struct i40e_asq_cmd_details *cmd_details); struct i40e_asq_cmd_details *cmd_details);
int i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr); int i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
int i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num, void i40e_get_pba_string(struct i40e_hw *hw);
u32 pba_num_size);
void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable); void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable);
/* prototype for functions used for NVM access */ /* prototype for functions used for NVM access */
int i40e_init_nvm(struct i40e_hw *hw); int i40e_init_nvm(struct i40e_hw *hw);
......
...@@ -493,6 +493,9 @@ struct i40e_hw { ...@@ -493,6 +493,9 @@ struct i40e_hw {
struct i40e_nvm_info nvm; struct i40e_nvm_info nvm;
struct i40e_fc_info fc; struct i40e_fc_info fc;
/* PBA ID */
const char *pba_id;
/* pci info */ /* pci info */
u16 device_id; u16 device_id;
u16 vendor_id; u16 vendor_id;
......
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