Skip to content

Commit cc30c63

Browse files
committed
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 <[email protected]>
2 parents b22f21f + 3e02480 commit cc30c63

File tree

10 files changed

+414
-76
lines changed

10 files changed

+414
-76
lines changed

drivers/net/ethernet/intel/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ config I40E
225225
depends on PTP_1588_CLOCK_OPTIONAL
226226
depends on PCI
227227
select AUXILIARY_BUS
228+
select NET_DEVLINK
228229
help
229230
This driver supports Intel(R) Ethernet Controller XL710 Family of
230231
devices. For more information on how to identify your adapter, go

drivers/net/ethernet/intel/i40e/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ i40e-objs := i40e_main.o \
2424
i40e_ddp.o \
2525
i40e_client.o \
2626
i40e_virtchnl_pf.o \
27-
i40e_xsk.o
27+
i40e_xsk.o \
28+
i40e_devlink.o
2829

2930
i40e-$(CONFIG_I40E_DCB) += i40e_dcb.o i40e_dcb_nl.o

drivers/net/ethernet/intel/i40e/i40e.h

Lines changed: 98 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
#include <linux/types.h>
1010
#include <linux/avf/virtchnl.h>
1111
#include <linux/net/intel/i40e_client.h>
12+
#include <net/devlink.h>
1213
#include <net/pkt_cls.h>
1314
#include <net/udp_tunnel.h>
1415
#include "i40e_dcb.h"
1516
#include "i40e_debug.h"
17+
#include "i40e_devlink.h"
1618
#include "i40e_io.h"
1719
#include "i40e_prototype.h"
1820
#include "i40e_register.h"
@@ -47,23 +49,19 @@
4749
#define I40E_QUEUE_WAIT_RETRY_LIMIT 10
4850
#define I40E_INT_NAME_STR_LEN (IFNAMSIZ + 16)
4951

50-
#define I40E_NVM_VERSION_LO_SHIFT 0
51-
#define I40E_NVM_VERSION_LO_MASK (0xff << I40E_NVM_VERSION_LO_SHIFT)
52-
#define I40E_NVM_VERSION_HI_SHIFT 12
53-
#define I40E_NVM_VERSION_HI_MASK (0xf << I40E_NVM_VERSION_HI_SHIFT)
54-
#define I40E_OEM_VER_BUILD_MASK 0xffff
55-
#define I40E_OEM_VER_PATCH_MASK 0xff
56-
#define I40E_OEM_VER_BUILD_SHIFT 8
57-
#define I40E_OEM_VER_SHIFT 24
5852
#define I40E_PHY_DEBUG_ALL \
5953
(I40E_AQ_PHY_DEBUG_DISABLE_LINK_FW | \
6054
I40E_AQ_PHY_DEBUG_DISABLE_ALL_LINK_FW)
6155

6256
#define I40E_OEM_EETRACK_ID 0xffffffff
63-
#define I40E_OEM_GEN_SHIFT 24
64-
#define I40E_OEM_SNAP_MASK 0x00ff0000
65-
#define I40E_OEM_SNAP_SHIFT 16
66-
#define I40E_OEM_RELEASE_MASK 0x0000ffff
57+
#define I40E_NVM_VERSION_LO_MASK GENMASK(7, 0)
58+
#define I40E_NVM_VERSION_HI_MASK GENMASK(15, 12)
59+
#define I40E_OEM_VER_BUILD_MASK GENMASK(23, 8)
60+
#define I40E_OEM_VER_PATCH_MASK GENMASK(7, 0)
61+
#define I40E_OEM_VER_MASK GENMASK(31, 24)
62+
#define I40E_OEM_GEN_MASK GENMASK(31, 24)
63+
#define I40E_OEM_SNAP_MASK GENMASK(23, 16)
64+
#define I40E_OEM_RELEASE_MASK GENMASK(15, 0)
6765

6866
#define I40E_RX_DESC(R, i) \
6967
(&(((union i40e_rx_desc *)((R)->desc))[i]))
@@ -411,6 +409,7 @@ static inline const u8 *i40e_channel_mac(struct i40e_channel *ch)
411409
/* struct that defines the Ethernet device */
412410
struct i40e_pf {
413411
struct pci_dev *pdev;
412+
struct devlink_port devlink_port;
414413
struct i40e_hw hw;
415414
DECLARE_BITMAP(state, __I40E_STATE_SIZE__);
416415
struct msix_entry *msix_entries;
@@ -951,43 +950,104 @@ struct i40e_device {
951950
};
952951

953952
/**
954-
* i40e_nvm_version_str - format the NVM version strings
953+
* i40e_info_nvm_ver - format the NVM version string
955954
* @hw: ptr to the hardware info
955+
* @buf: string buffer to store
956+
* @len: buffer size
957+
*
958+
* Formats NVM version string as:
959+
* <gen>.<snap>.<release> when eetrackid == I40E_OEM_EETRACK_ID
960+
* <nvm_major>.<nvm_minor> otherwise
956961
**/
957-
static inline char *i40e_nvm_version_str(struct i40e_hw *hw)
962+
static inline void i40e_info_nvm_ver(struct i40e_hw *hw, char *buf, size_t len)
958963
{
959-
static char buf[32];
960-
u32 full_ver;
964+
struct i40e_nvm_info *nvm = &hw->nvm;
961965

962-
full_ver = hw->nvm.oem_ver;
963-
964-
if (hw->nvm.eetrack == I40E_OEM_EETRACK_ID) {
966+
if (nvm->eetrack == I40E_OEM_EETRACK_ID) {
967+
u32 full_ver = nvm->oem_ver;
965968
u8 gen, snap;
966969
u16 release;
967970

968-
gen = (u8)(full_ver >> I40E_OEM_GEN_SHIFT);
969-
snap = (u8)((full_ver & I40E_OEM_SNAP_MASK) >>
970-
I40E_OEM_SNAP_SHIFT);
971-
release = (u16)(full_ver & I40E_OEM_RELEASE_MASK);
972-
973-
snprintf(buf, sizeof(buf), "%x.%x.%x", gen, snap, release);
971+
gen = FIELD_GET(I40E_OEM_GEN_MASK, full_ver);
972+
snap = FIELD_GET(I40E_OEM_SNAP_MASK, full_ver);
973+
release = FIELD_GET(I40E_OEM_RELEASE_MASK, full_ver);
974+
snprintf(buf, len, "%x.%x.%x", gen, snap, release);
974975
} else {
975-
u8 ver, patch;
976+
u8 major, minor;
977+
978+
major = FIELD_GET(I40E_NVM_VERSION_HI_MASK, nvm->version);
979+
minor = FIELD_GET(I40E_NVM_VERSION_LO_MASK, nvm->version);
980+
snprintf(buf, len, "%x.%02x", major, minor);
981+
}
982+
}
983+
984+
/**
985+
* i40e_info_eetrack - format the EETrackID string
986+
* @hw: ptr to the hardware info
987+
* @buf: string buffer to store
988+
* @len: buffer size
989+
*
990+
* Returns hexadecimally formated EETrackID if it is
991+
* different from I40E_OEM_EETRACK_ID or empty string.
992+
**/
993+
static inline void i40e_info_eetrack(struct i40e_hw *hw, char *buf, size_t len)
994+
{
995+
struct i40e_nvm_info *nvm = &hw->nvm;
996+
997+
buf[0] = '\0';
998+
if (nvm->eetrack != I40E_OEM_EETRACK_ID)
999+
snprintf(buf, len, "0x%08x", nvm->eetrack);
1000+
}
1001+
1002+
/**
1003+
* i40e_info_civd_ver - format the NVM version strings
1004+
* @hw: ptr to the hardware info
1005+
* @buf: string buffer to store
1006+
* @len: buffer size
1007+
*
1008+
* Returns formated combo image version if adapter's EETrackID is
1009+
* different from I40E_OEM_EETRACK_ID or empty string.
1010+
**/
1011+
static inline void i40e_info_civd_ver(struct i40e_hw *hw, char *buf, size_t len)
1012+
{
1013+
struct i40e_nvm_info *nvm = &hw->nvm;
1014+
1015+
buf[0] = '\0';
1016+
if (nvm->eetrack != I40E_OEM_EETRACK_ID) {
1017+
u32 full_ver = nvm->oem_ver;
1018+
u8 major, minor;
9761019
u16 build;
9771020

978-
ver = (u8)(full_ver >> I40E_OEM_VER_SHIFT);
979-
build = (u16)((full_ver >> I40E_OEM_VER_BUILD_SHIFT) &
980-
I40E_OEM_VER_BUILD_MASK);
981-
patch = (u8)(full_ver & I40E_OEM_VER_PATCH_MASK);
982-
983-
snprintf(buf, sizeof(buf),
984-
"%x.%02x 0x%x %d.%d.%d",
985-
(hw->nvm.version & I40E_NVM_VERSION_HI_MASK) >>
986-
I40E_NVM_VERSION_HI_SHIFT,
987-
(hw->nvm.version & I40E_NVM_VERSION_LO_MASK) >>
988-
I40E_NVM_VERSION_LO_SHIFT,
989-
hw->nvm.eetrack, ver, build, patch);
1021+
major = FIELD_GET(I40E_OEM_VER_MASK, full_ver);
1022+
build = FIELD_GET(I40E_OEM_VER_BUILD_MASK, full_ver);
1023+
minor = FIELD_GET(I40E_OEM_VER_PATCH_MASK, full_ver);
1024+
snprintf(buf, len, "%d.%d.%d", major, build, minor);
9901025
}
1026+
}
1027+
1028+
/**
1029+
* i40e_nvm_version_str - format the NVM version strings
1030+
* @hw: ptr to the hardware info
1031+
* @buf: string buffer to store
1032+
* @len: buffer size
1033+
**/
1034+
static inline char *i40e_nvm_version_str(struct i40e_hw *hw, char *buf,
1035+
size_t len)
1036+
{
1037+
char ver[16] = " ";
1038+
1039+
/* Get NVM version */
1040+
i40e_info_nvm_ver(hw, buf, len);
1041+
1042+
/* Append EETrackID if provided */
1043+
i40e_info_eetrack(hw, &ver[1], sizeof(ver) - 1);
1044+
if (strlen(ver) > 1)
1045+
strlcat(buf, ver, len);
1046+
1047+
/* Append combo image version if provided */
1048+
i40e_info_civd_ver(hw, &ver[1], sizeof(ver) - 1);
1049+
if (strlen(ver) > 1)
1050+
strlcat(buf, ver, len);
9911051

9921052
return buf;
9931053
}

drivers/net/ethernet/intel/i40e/i40e_common.c

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -821,62 +821,72 @@ void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable)
821821
}
822822

823823
/**
824-
* i40e_read_pba_string - Reads part number string from EEPROM
824+
* i40e_get_pba_string - Reads part number string from EEPROM
825825
* @hw: pointer to hardware structure
826-
* @pba_num: stores the part number string from the EEPROM
827-
* @pba_num_size: part number string buffer length
828826
*
829-
* Reads the part number string from the EEPROM.
827+
* Reads the part number string from the EEPROM and stores it
828+
* into newly allocated buffer and saves resulting pointer
829+
* to i40e_hw->pba_id field.
830830
**/
831-
int i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num,
832-
u32 pba_num_size)
831+
void i40e_get_pba_string(struct i40e_hw *hw)
833832
{
833+
#define I40E_NVM_PBA_FLAGS_BLK_PRESENT 0xFAFA
834834
u16 pba_word = 0;
835835
u16 pba_size = 0;
836836
u16 pba_ptr = 0;
837-
int status = 0;
838-
u16 i = 0;
837+
int status;
838+
char *ptr;
839+
u16 i;
839840

840841
status = i40e_read_nvm_word(hw, I40E_SR_PBA_FLAGS, &pba_word);
841-
if (status || (pba_word != 0xFAFA)) {
842-
hw_dbg(hw, "Failed to read PBA flags or flag is invalid.\n");
843-
return status;
842+
if (status) {
843+
hw_dbg(hw, "Failed to read PBA flags.\n");
844+
return;
845+
}
846+
if (pba_word != I40E_NVM_PBA_FLAGS_BLK_PRESENT) {
847+
hw_dbg(hw, "PBA block is not present.\n");
848+
return;
844849
}
845850

846851
status = i40e_read_nvm_word(hw, I40E_SR_PBA_BLOCK_PTR, &pba_ptr);
847852
if (status) {
848853
hw_dbg(hw, "Failed to read PBA Block pointer.\n");
849-
return status;
854+
return;
850855
}
851856

852857
status = i40e_read_nvm_word(hw, pba_ptr, &pba_size);
853858
if (status) {
854859
hw_dbg(hw, "Failed to read PBA Block size.\n");
855-
return status;
860+
return;
856861
}
857862

858863
/* Subtract one to get PBA word count (PBA Size word is included in
859-
* total size)
864+
* total size) and advance pointer to first PBA word.
860865
*/
861866
pba_size--;
862-
if (pba_num_size < (((u32)pba_size * 2) + 1)) {
863-
hw_dbg(hw, "Buffer too small for PBA data.\n");
864-
return -EINVAL;
867+
pba_ptr++;
868+
if (!pba_size) {
869+
hw_dbg(hw, "PBA ID is empty.\n");
870+
return;
865871
}
866872

873+
ptr = devm_kzalloc(i40e_hw_to_dev(hw), pba_size * 2 + 1, GFP_KERNEL);
874+
if (!ptr)
875+
return;
876+
hw->pba_id = ptr;
877+
867878
for (i = 0; i < pba_size; i++) {
868-
status = i40e_read_nvm_word(hw, (pba_ptr + 1) + i, &pba_word);
879+
status = i40e_read_nvm_word(hw, pba_ptr + i, &pba_word);
869880
if (status) {
870881
hw_dbg(hw, "Failed to read PBA Block word %d.\n", i);
871-
return status;
882+
devm_kfree(i40e_hw_to_dev(hw), hw->pba_id);
883+
hw->pba_id = NULL;
884+
return;
872885
}
873886

874-
pba_num[(i * 2)] = (pba_word >> 8) & 0xFF;
875-
pba_num[(i * 2) + 1] = pba_word & 0xFF;
887+
*ptr++ = (pba_word >> 8) & 0xFF;
888+
*ptr++ = pba_word & 0xFF;
876889
}
877-
pba_num[(pba_size * 2)] = '\0';
878-
879-
return status;
880890
}
881891

882892
/**

0 commit comments

Comments
 (0)