Skip to content

Commit

Permalink
net/ngbe: disable LLDP by default
Browse files Browse the repository at this point in the history
In the new firmware versions, LLDP is enabled by default to implement
new features in other drivers. But it is useless in DPDK. So disable
it in device initialization to prevent it from affecting hardware
default behavior.

Build errors on some ARM platforms are introduced by this patch:

../drivers/net/ngbe/base/ngbe_mng.c: In function 'ngbe_hic_get_lldp':
../drivers/net/ngbe/base/ngbe_mng.c:127:36: error: array subscript 2
is outside array bounds of 'struct ngbe_hic_write_lldp[1]' [-Werror=
array-bounds]
127 |                         buffer[bi] = rd32a(hw, NGBE_MNGMBX, bi);
../drivers/net/ngbe/base/ngbe_mng.c:385:36: note: while referencing
'buffer'
385 |         struct ngbe_hic_write_lldp buffer;

So remove the redundant code 'resp->cmd == 0x30' to fix this issue.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
  • Loading branch information
Jiawen Wu authored and ferruhy committed Jul 17, 2024
1 parent 3bf7715 commit d32d6c8
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 32 deletions.
4 changes: 4 additions & 0 deletions drivers/net/ngbe/base/ngbe_eeprom.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#define NGBE_CALSUM_CAP_STATUS 0x10224
#define NGBE_EEPROM_VERSION_STORE_REG 0x1022C

#define NGBE_FW_SUPPORT_LLDP 0x19
#define NGBE_FW_GET_LLDP 0x1B
#define NGBE_FW_MASK 0xFF

s32 ngbe_init_eeprom_params(struct ngbe_hw *hw);
s32 ngbe_validate_eeprom_checksum_em(struct ngbe_hw *hw, u16 *checksum_val);
s32 ngbe_get_eeprom_semaphore(struct ngbe_hw *hw);
Expand Down
75 changes: 64 additions & 11 deletions drivers/net/ngbe/base/ngbe_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,56 @@
#include "ngbe_mng.h"
#include "ngbe_hw.h"

static s32 ngbe_is_lldp(struct ngbe_hw *hw)
{
u32 tmp = 0, lldp_flash_data = 0, i;
s32 err = 0;

if ((hw->eeprom_id & NGBE_FW_MASK) >= NGBE_FW_GET_LLDP) {
err = ngbe_hic_get_lldp(hw);
if (err == 0)
return 0;
}

for (i = 0; i < 1024; i++) {
err = ngbe_flash_read_dword(hw, NGBE_LLDP_REG + i * 4, &tmp);
if (err)
return err;

if (tmp == BIT_MASK32)
break;
lldp_flash_data = tmp;
}

if (lldp_flash_data & MS(hw->bus.lan_id, 1))
hw->lldp_enabled = true;
else
hw->lldp_enabled = false;

return 0;
}

static void ngbe_disable_lldp(struct ngbe_hw *hw)
{
s32 err = 0;

if ((hw->eeprom_id & NGBE_FW_MASK) < NGBE_FW_SUPPORT_LLDP)
return;

err = ngbe_is_lldp(hw);
if (err) {
PMD_INIT_LOG(INFO, "Can not get LLDP status.");
} else if (hw->lldp_enabled) {
err = ngbe_hic_set_lldp(hw, false);
if (!err)
PMD_INIT_LOG(INFO,
"LLDP detected on port %d, turn it off by default.",
hw->port_id);
else
PMD_INIT_LOG(INFO, "Can not set LLDP status.");
}
}

/**
* ngbe_start_hw - Prepare hardware for Tx/Rx
* @hw: pointer to hardware structure
Expand Down Expand Up @@ -55,6 +105,7 @@ s32 ngbe_init_hw(struct ngbe_hw *hw)

ngbe_read_efuse(hw);
ngbe_save_eeprom_version(hw);
ngbe_disable_lldp(hw);

/* Reset the hardware */
status = hw->mac.reset_hw(hw);
Expand Down Expand Up @@ -1816,9 +1867,9 @@ s32 ngbe_enable_rx_dma(struct ngbe_hw *hw, u32 regval)
* 1. to be sector address, when implemented erase sector command
* 2. to be flash address when implemented read, write flash address
*
* Return 0 on success, return 1 on failure.
* Return 0 on success, return NGBE_ERR_TIMEOUT on failure.
*/
u32 ngbe_fmgr_cmd_op(struct ngbe_hw *hw, u32 cmd, u32 cmd_addr)
s32 ngbe_fmgr_cmd_op(struct ngbe_hw *hw, u32 cmd, u32 cmd_addr)
{
u32 cmd_val, i;

Expand All @@ -1832,33 +1883,35 @@ u32 ngbe_fmgr_cmd_op(struct ngbe_hw *hw, u32 cmd, u32 cmd_addr)
usec_delay(10);
}
if (i == NGBE_SPI_TIMEOUT)
return 1;
return NGBE_ERR_TIMEOUT;

return 0;
}

u32 ngbe_flash_read_dword(struct ngbe_hw *hw, u32 addr)
s32 ngbe_flash_read_dword(struct ngbe_hw *hw, u32 addr, u32 *data)
{
u32 status;
s32 status;

status = ngbe_fmgr_cmd_op(hw, 1, addr);
if (status == 0x1) {
if (status < 0) {
DEBUGOUT("Read flash timeout.");
return status;
}

return rd32(hw, NGBE_SPIDAT);
*data = rd32(hw, NGBE_SPIDAT);

return 0;
}

void ngbe_read_efuse(struct ngbe_hw *hw)
{
u32 efuse[2];
u32 efuse[2] = {0, 0};
u8 lan_id = hw->bus.lan_id;

efuse[0] = ngbe_flash_read_dword(hw, 0xfe010 + lan_id * 8);
efuse[1] = ngbe_flash_read_dword(hw, 0xfe010 + lan_id * 8 + 4);
ngbe_flash_read_dword(hw, 0xfe010 + lan_id * 8, &efuse[0]);
ngbe_flash_read_dword(hw, 0xfe010 + lan_id * 8 + 4, &efuse[1]);

DEBUGOUT("port %d efuse[0] = %08x, efuse[1] = %08x\n",
DEBUGOUT("port %d efuse[0] = %08x, efuse[1] = %08x",
lan_id, efuse[0], efuse[1]);

hw->gphy_efuse[0] = efuse[0];
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ngbe/base/ngbe_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ s32 ngbe_enable_rx_dma(struct ngbe_hw *hw, u32 regval);
void ngbe_map_device_id(struct ngbe_hw *hw);

void ngbe_read_efuse(struct ngbe_hw *hw);
u32 ngbe_fmgr_cmd_op(struct ngbe_hw *hw, u32 cmd, u32 cmd_addr);
u32 ngbe_flash_read_dword(struct ngbe_hw *hw, u32 addr);
s32 ngbe_fmgr_cmd_op(struct ngbe_hw *hw, u32 cmd, u32 cmd_addr);
s32 ngbe_flash_read_dword(struct ngbe_hw *hw, u32 addr, u32 *data);
void ngbe_set_ncsi_status(struct ngbe_hw *hw);

#endif /* _NGBE_HW_H_ */
62 changes: 47 additions & 15 deletions drivers/net/ngbe/base/ngbe_mng.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,21 +117,7 @@ ngbe_host_interface_command(struct ngbe_hw *hw, u32 *buffer,
for (bi = 0; bi < dword_len; bi++)
buffer[bi] = rd32a(hw, NGBE_MNGMBX, bi);

/*
* If there is any thing in data position pull it in
* Read Flash command requires reading buffer length from
* two byes instead of one byte
*/
if (resp->cmd == 0x30) {
for (; bi < dword_len + 2; bi++)
buffer[bi] = rd32a(hw, NGBE_MNGMBX, bi);

buf_len = (((u16)(resp->cmd_or_resp.ret_status) << 3)
& 0xF00) | resp->buf_len;
hdr_size += (2 << 2);
} else {
buf_len = resp->buf_len;
}
buf_len = resp->buf_len;
if (!buf_len)
goto rel_out;

Expand Down Expand Up @@ -379,3 +365,49 @@ s32 ngbe_phy_led_oem_chk(struct ngbe_hw *hw, u32 *data)

return err;
}

s32 ngbe_hic_get_lldp(struct ngbe_hw *hw)
{
struct ngbe_hic_write_lldp buffer;
s32 err = 0;

buffer.hdr.cmd = FW_LLDP_GET_CMD;
buffer.hdr.buf_len = 0x1;
buffer.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
buffer.hdr.checksum = FW_DEFAULT_CHECKSUM;
buffer.func = hw->bus.lan_id;

err = ngbe_host_interface_command(hw, (u32 *)&buffer, sizeof(buffer),
NGBE_HI_COMMAND_TIMEOUT, true);
if (err)
return err;

if (buffer.hdr.cmd_or_resp.ret_status == FW_CEM_RESP_STATUS_SUCCESS) {
/* this field returns the status of LLDP */
if (buffer.func)
hw->lldp_enabled = true;
else
hw->lldp_enabled = false;
} else {
err = NGBE_ERR_HOST_INTERFACE_COMMAND;
}

return err;
}

s32 ngbe_hic_set_lldp(struct ngbe_hw *hw, bool on)
{
struct ngbe_hic_write_lldp buffer;

if (on)
buffer.hdr.cmd = FW_LLDP_SET_CMD_ON;
else
buffer.hdr.cmd = FW_LLDP_SET_CMD_OFF;
buffer.hdr.buf_len = 0x1;
buffer.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
buffer.hdr.checksum = FW_DEFAULT_CHECKSUM;
buffer.func = hw->bus.lan_id;

return ngbe_host_interface_command(hw, (u32 *)&buffer, sizeof(buffer),
NGBE_HI_COMMAND_TIMEOUT, false);
}
13 changes: 13 additions & 0 deletions drivers/net/ngbe/base/ngbe_mng.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
#define FW_EEPROM_CHECK_STATUS 0xE9
#define FW_PHY_LED_CONF 0xF1
#define FW_READ_SHADOW_RAM_GPIO 0xB4
#define FW_LLDP_GET_CMD 0xF5
#define FW_LLDP_SET_CMD_OFF 0xF3
#define FW_LLDP_SET_CMD_ON 0xF2
#define FW_CEM_CMD_RESERVED 0X0

#define FW_CHECKSUM_CAP_ST_PASS 0x80658383
#define FW_CHECKSUM_CAP_ST_FAIL 0x70657376
Expand Down Expand Up @@ -97,12 +101,21 @@ struct ngbe_hic_write_pcie {
u32 data;
};

struct ngbe_hic_write_lldp {
struct ngbe_hic_hdr hdr;
u8 func;
u8 pad2;
u16 pad3;
};

s32 ngbe_hic_sr_read(struct ngbe_hw *hw, u32 addr, u8 *buf, int len);
s32 ngbe_hic_sr_write(struct ngbe_hw *hw, u32 addr, u8 *buf, int len);
s32 ngbe_hic_pcie_read(struct ngbe_hw *hw, u16 addr, u32 *buf, int len);
s32 ngbe_hic_pcie_write(struct ngbe_hw *hw, u16 addr, u32 *buf, int len);

s32 ngbe_hic_check_cap(struct ngbe_hw *hw);
s32 ngbe_phy_led_oem_chk(struct ngbe_hw *hw, u32 *data);
s32 ngbe_hic_get_lldp(struct ngbe_hw *hw);
s32 ngbe_hic_set_lldp(struct ngbe_hw *hw, bool on);

#endif /* _NGBE_MNG_H_ */
2 changes: 1 addition & 1 deletion drivers/net/ngbe/base/ngbe_phy_mvl.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ s32 ngbe_check_phy_mode_mvl(struct ngbe_hw *hw)
u8 value = 0;
u32 phy_mode = 0;

phy_mode = ngbe_flash_read_dword(hw, 0xFF010);
ngbe_flash_read_dword(hw, 0xFF010, &phy_mode);
value = (u8)(phy_mode >> (hw->bus.lan_id * 8));

if (MVL_GEN_CTL_MODE(value) == MVL_GEN_CTL_MODE_COPPER) {
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ngbe/base/ngbe_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,8 @@ enum ngbe_5tuple_protocol {
#define NGBE_MDIOMODE_PRT1CL22 MS(1, 0x1)
#define NGBE_MDIOMODE_PRT0CL22 MS(0, 0x1)

#define NGBE_LLDP_REG 0x0F1000

#define NVM_OROM_OFFSET 0x17
#define NVM_OROM_BLK_LOW 0x83
#define NVM_OROM_BLK_HI 0x84
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ngbe/base/ngbe_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,10 +455,12 @@ struct ngbe_hw {
u16 sub_device_id;
u16 sub_system_id;
u32 eeprom_id;
u8 port_id;
u8 revision_id;
bool adapter_stopped;
bool wol_enabled;
bool ncsi_enabled;
bool lldp_enabled;

uint64_t isb_dma;
void IOMEM *isb_mem;
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/ngbe/ngbe_ethdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,15 +371,16 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)

/* Vendor and Device ID need to be set before init of shared code */
hw->back = pci_dev;
hw->port_id = eth_dev->data->port_id;
hw->device_id = pci_dev->id.device_id;
hw->vendor_id = pci_dev->id.vendor_id;
if (pci_dev->id.subsystem_vendor_id == PCI_VENDOR_ID_WANGXUN) {
hw->sub_system_id = pci_dev->id.subsystem_device_id;
} else {
u32 ssid;
u32 ssid = 0;

ssid = ngbe_flash_read_dword(hw, 0xFFFDC);
if (ssid == 0x1) {
err = ngbe_flash_read_dword(hw, 0xFFFDC, &ssid);
if (err) {
PMD_INIT_LOG(ERR,
"Read of internal subsystem device id failed\n");
return -ENODEV;
Expand Down

0 comments on commit d32d6c8

Please sign in to comment.