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
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;
}
/**
......
// 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,
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 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
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 @@ static int i40e_init_recovery_mode(struct i40e_pf *pf, struct i40e_hw *hw)
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 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
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 @@ static void i40e_remove(struct pci_dev *pdev)
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;
......
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