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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
cc30c6346b
@ -225,6 +225,7 @@ config I40E
|
||||
depends on PTP_1588_CLOCK_OPTIONAL
|
||||
depends on PCI
|
||||
select AUXILIARY_BUS
|
||||
select NET_DEVLINK
|
||||
help
|
||||
This driver supports Intel(R) Ethernet Controller XL710 Family of
|
||||
devices. For more information on how to identify your adapter, go
|
||||
|
@ -24,6 +24,7 @@ i40e-objs := i40e_main.o \
|
||||
i40e_ddp.o \
|
||||
i40e_client.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
|
||||
|
@ -9,10 +9,12 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/avf/virtchnl.h>
|
||||
#include <linux/net/intel/i40e_client.h>
|
||||
#include <net/devlink.h>
|
||||
#include <net/pkt_cls.h>
|
||||
#include <net/udp_tunnel.h>
|
||||
#include "i40e_dcb.h"
|
||||
#include "i40e_debug.h"
|
||||
#include "i40e_devlink.h"
|
||||
#include "i40e_io.h"
|
||||
#include "i40e_prototype.h"
|
||||
#include "i40e_register.h"
|
||||
@ -47,23 +49,19 @@
|
||||
#define I40E_QUEUE_WAIT_RETRY_LIMIT 10
|
||||
#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 \
|
||||
(I40E_AQ_PHY_DEBUG_DISABLE_LINK_FW | \
|
||||
I40E_AQ_PHY_DEBUG_DISABLE_ALL_LINK_FW)
|
||||
|
||||
#define I40E_OEM_EETRACK_ID 0xffffffff
|
||||
#define I40E_OEM_GEN_SHIFT 24
|
||||
#define I40E_OEM_SNAP_MASK 0x00ff0000
|
||||
#define I40E_OEM_SNAP_SHIFT 16
|
||||
#define I40E_OEM_RELEASE_MASK 0x0000ffff
|
||||
#define I40E_NVM_VERSION_LO_MASK GENMASK(7, 0)
|
||||
#define I40E_NVM_VERSION_HI_MASK GENMASK(15, 12)
|
||||
#define I40E_OEM_VER_BUILD_MASK GENMASK(23, 8)
|
||||
#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) \
|
||||
(&(((union i40e_rx_desc *)((R)->desc))[i]))
|
||||
@ -411,6 +409,7 @@ static inline const u8 *i40e_channel_mac(struct i40e_channel *ch)
|
||||
/* struct that defines the Ethernet device */
|
||||
struct i40e_pf {
|
||||
struct pci_dev *pdev;
|
||||
struct devlink_port devlink_port;
|
||||
struct i40e_hw hw;
|
||||
DECLARE_BITMAP(state, __I40E_STATE_SIZE__);
|
||||
struct msix_entry *msix_entries;
|
||||
@ -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
|
||||
* @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];
|
||||
u32 full_ver;
|
||||
struct i40e_nvm_info *nvm = &hw->nvm;
|
||||
|
||||
full_ver = hw->nvm.oem_ver;
|
||||
|
||||
if (hw->nvm.eetrack == I40E_OEM_EETRACK_ID) {
|
||||
if (nvm->eetrack == I40E_OEM_EETRACK_ID) {
|
||||
u32 full_ver = nvm->oem_ver;
|
||||
u8 gen, snap;
|
||||
u16 release;
|
||||
|
||||
gen = (u8)(full_ver >> I40E_OEM_GEN_SHIFT);
|
||||
snap = (u8)((full_ver & I40E_OEM_SNAP_MASK) >>
|
||||
I40E_OEM_SNAP_SHIFT);
|
||||
release = (u16)(full_ver & I40E_OEM_RELEASE_MASK);
|
||||
|
||||
snprintf(buf, sizeof(buf), "%x.%x.%x", gen, snap, release);
|
||||
gen = FIELD_GET(I40E_OEM_GEN_MASK, full_ver);
|
||||
snap = FIELD_GET(I40E_OEM_SNAP_MASK, full_ver);
|
||||
release = FIELD_GET(I40E_OEM_RELEASE_MASK, full_ver);
|
||||
snprintf(buf, len, "%x.%x.%x", gen, snap, release);
|
||||
} 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;
|
||||
|
||||
ver = (u8)(full_ver >> I40E_OEM_VER_SHIFT);
|
||||
build = (u16)((full_ver >> I40E_OEM_VER_BUILD_SHIFT) &
|
||||
I40E_OEM_VER_BUILD_MASK);
|
||||
patch = (u8)(full_ver & I40E_OEM_VER_PATCH_MASK);
|
||||
|
||||
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);
|
||||
major = FIELD_GET(I40E_OEM_VER_MASK, full_ver);
|
||||
build = FIELD_GET(I40E_OEM_VER_BUILD_MASK, full_ver);
|
||||
minor = FIELD_GET(I40E_OEM_VER_PATCH_MASK, full_ver);
|
||||
snprintf(buf, len, "%d.%d.%d", major, build, minor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
@ -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
|
||||
* @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,
|
||||
u32 pba_num_size)
|
||||
void i40e_get_pba_string(struct i40e_hw *hw)
|
||||
{
|
||||
#define I40E_NVM_PBA_FLAGS_BLK_PRESENT 0xFAFA
|
||||
u16 pba_word = 0;
|
||||
u16 pba_size = 0;
|
||||
u16 pba_ptr = 0;
|
||||
int status = 0;
|
||||
u16 i = 0;
|
||||
int status;
|
||||
char *ptr;
|
||||
u16 i;
|
||||
|
||||
status = i40e_read_nvm_word(hw, I40E_SR_PBA_FLAGS, &pba_word);
|
||||
if (status || (pba_word != 0xFAFA)) {
|
||||
hw_dbg(hw, "Failed to read PBA flags or flag is invalid.\n");
|
||||
return status;
|
||||
if (status) {
|
||||
hw_dbg(hw, "Failed to read PBA flags.\n");
|
||||
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);
|
||||
if (status) {
|
||||
hw_dbg(hw, "Failed to read PBA Block pointer.\n");
|
||||
return status;
|
||||
return;
|
||||
}
|
||||
|
||||
status = i40e_read_nvm_word(hw, pba_ptr, &pba_size);
|
||||
if (status) {
|
||||
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
|
||||
* total size)
|
||||
* total size) and advance pointer to first PBA word.
|
||||
*/
|
||||
pba_size--;
|
||||
if (pba_num_size < (((u32)pba_size * 2) + 1)) {
|
||||
hw_dbg(hw, "Buffer too small for PBA data.\n");
|
||||
return -EINVAL;
|
||||
pba_ptr++;
|
||||
if (!pba_size) {
|
||||
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++) {
|
||||
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) {
|
||||
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;
|
||||
pba_num[(i * 2) + 1] = pba_word & 0xFF;
|
||||
*ptr++ = (pba_word >> 8) & 0xFF;
|
||||
*ptr++ = pba_word & 0xFF;
|
||||
}
|
||||
pba_num[(pba_size * 2)] = '\0';
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
224
drivers/net/ethernet/intel/i40e/i40e_devlink.c
Normal file
224
drivers/net/ethernet/intel/i40e/i40e_devlink.c
Normal file
@ -0,0 +1,224 @@
|
||||
// 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);
|
||||
}
|
18
drivers/net/ethernet/intel/i40e/i40e_devlink.h
Normal file
18
drivers/net/ethernet/intel/i40e/i40e_devlink.h
Normal file
@ -0,0 +1,18 @@
|
||||
/* 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,
|
||||
struct i40e_pf *pf = vsi->back;
|
||||
|
||||
strscpy(drvinfo->driver, i40e_driver_name, sizeof(drvinfo->driver));
|
||||
strscpy(drvinfo->fw_version, i40e_nvm_version_str(&pf->hw),
|
||||
sizeof(drvinfo->fw_version));
|
||||
i40e_nvm_version_str(&pf->hw, drvinfo->fw_version,
|
||||
sizeof(drvinfo->fw_version));
|
||||
strscpy(drvinfo->bus_info, pci_name(pf->pdev),
|
||||
sizeof(drvinfo->bus_info));
|
||||
drvinfo->n_priv_flags = I40E_PRIV_FLAGS_STR_LEN;
|
||||
|
@ -10798,7 +10798,9 @@ static void i40e_get_oem_version(struct i40e_hw *hw)
|
||||
&gen_snap);
|
||||
i40e_read_nvm_word(hw, block_offset + I40E_NVM_OEM_RELEASE_OFFSET,
|
||||
&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;
|
||||
}
|
||||
|
||||
@ -14211,6 +14213,8 @@ int i40e_vsi_release(struct i40e_vsi *vsi)
|
||||
}
|
||||
set_bit(__I40E_VSI_RELEASING, vsi->state);
|
||||
uplink_seid = vsi->uplink_seid;
|
||||
if (vsi->type == I40E_VSI_MAIN)
|
||||
i40e_devlink_destroy_port(pf);
|
||||
if (vsi->type != I40E_VSI_SRIOV) {
|
||||
if (vsi->netdev_registered) {
|
||||
vsi->netdev_registered = false;
|
||||
@ -14398,6 +14402,8 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
|
||||
|
||||
err_rings:
|
||||
i40e_vsi_free_q_vectors(vsi);
|
||||
if (vsi->type == I40E_VSI_MAIN)
|
||||
i40e_devlink_destroy_port(pf);
|
||||
if (vsi->netdev_registered) {
|
||||
vsi->netdev_registered = false;
|
||||
unregister_netdev(vsi->netdev);
|
||||
@ -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);
|
||||
if (ret)
|
||||
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);
|
||||
if (ret)
|
||||
goto err_netdev;
|
||||
goto err_dl_port;
|
||||
vsi->netdev_registered = true;
|
||||
netif_carrier_off(vsi->netdev);
|
||||
#ifdef CONFIG_I40E_DCB
|
||||
@ -14589,6 +14601,9 @@ err_msix:
|
||||
free_netdev(vsi->netdev);
|
||||
vsi->netdev = NULL;
|
||||
}
|
||||
err_dl_port:
|
||||
if (vsi->type == I40E_VSI_MAIN)
|
||||
i40e_devlink_destroy_port(pf);
|
||||
err_netdev:
|
||||
i40e_aq_delete_element(&pf->hw, vsi->seid, NULL);
|
||||
err_vsi:
|
||||
@ -15619,7 +15634,7 @@ err_switch_setup:
|
||||
iounmap(hw->hw_addr);
|
||||
pci_release_mem_regions(pf->pdev);
|
||||
pci_disable_device(pf->pdev);
|
||||
kfree(pf);
|
||||
i40e_free_pf(pf);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -15661,6 +15676,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
struct i40e_hw *hw;
|
||||
static u16 pfs_found;
|
||||
u16 wol_nvm_bits;
|
||||
char nvm_ver[32];
|
||||
u16 link_status;
|
||||
#ifdef CONFIG_I40E_DCB
|
||||
int status;
|
||||
@ -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
|
||||
* device's current profile information.
|
||||
*/
|
||||
pf = kzalloc(sizeof(*pf), GFP_KERNEL);
|
||||
pf = i40e_alloc_pf(&pdev->dev);
|
||||
if (!pf) {
|
||||
err = -ENOMEM;
|
||||
goto err_pf_alloc;
|
||||
@ -15830,13 +15846,15 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
goto err_pf_reset;
|
||||
}
|
||||
i40e_get_oem_version(hw);
|
||||
i40e_get_pba_string(hw);
|
||||
|
||||
/* 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",
|
||||
hw->aq.fw_maj_ver, hw->aq.fw_min_ver, hw->aq.fw_build,
|
||||
hw->aq.api_maj_ver, hw->aq.api_min_ver,
|
||||
i40e_nvm_version_str(hw), hw->vendor_id, hw->device_id,
|
||||
hw->subsystem_vendor_id, hw->subsystem_device_id);
|
||||
hw->aq.api_maj_ver, hw->aq.api_min_ver, nvm_ver,
|
||||
hw->vendor_id, hw->device_id, hw->subsystem_vendor_id,
|
||||
hw->subsystem_device_id);
|
||||
|
||||
if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
|
||||
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)
|
||||
/* print a string summarizing features */
|
||||
i40e_print_features(pf);
|
||||
|
||||
i40e_devlink_register(pf);
|
||||
|
||||
return 0;
|
||||
|
||||
/* Unwind what we've done if something failed in the setup */
|
||||
@ -16243,7 +16263,7 @@ err_adminq_setup:
|
||||
err_pf_reset:
|
||||
iounmap(hw->hw_addr);
|
||||
err_ioremap:
|
||||
kfree(pf);
|
||||
i40e_free_pf(pf);
|
||||
err_pf_alloc:
|
||||
pci_release_mem_regions(pdev);
|
||||
err_pci_reg:
|
||||
@ -16268,6 +16288,8 @@ static void i40e_remove(struct pci_dev *pdev)
|
||||
int ret_code;
|
||||
int i;
|
||||
|
||||
i40e_devlink_unregister(pf);
|
||||
|
||||
i40e_dbg_pf_exit(pf);
|
||||
|
||||
i40e_ptp_stop(pf);
|
||||
@ -16393,7 +16415,7 @@ unmap:
|
||||
kfree(pf->vsi);
|
||||
|
||||
iounmap(hw->hw_addr);
|
||||
kfree(pf);
|
||||
i40e_free_pf(pf);
|
||||
pci_release_mem_regions(pdev);
|
||||
|
||||
pci_disable_device(pdev);
|
||||
|
@ -341,8 +341,7 @@ i40e_aq_configure_partition_bw(struct i40e_hw *hw,
|
||||
struct i40e_aqc_configure_partition_bw_data *bw_data,
|
||||
struct i40e_asq_cmd_details *cmd_details);
|
||||
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,
|
||||
u32 pba_num_size);
|
||||
void i40e_get_pba_string(struct i40e_hw *hw);
|
||||
void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable);
|
||||
/* prototype for functions used for NVM access */
|
||||
int i40e_init_nvm(struct i40e_hw *hw);
|
||||
|
@ -493,6 +493,9 @@ struct i40e_hw {
|
||||
struct i40e_nvm_info nvm;
|
||||
struct i40e_fc_info fc;
|
||||
|
||||
/* PBA ID */
|
||||
const char *pba_id;
|
||||
|
||||
/* pci info */
|
||||
u16 device_id;
|
||||
u16 vendor_id;
|
||||
|
Loading…
x
Reference in New Issue
Block a user