net/ngbe: support OEM customized LED

Support to get OEM customized LED configuration information from firmware.
And driver needs to adjust the process of PHY setup link, based on this
LED configuration.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
This commit is contained in:
Jiawen Wu 2022-02-09 18:42:08 +08:00 committed by Ferruh Yigit
parent 1c44384fce
commit fbd5ceb0ef
9 changed files with 109 additions and 19 deletions

View File

@ -109,6 +109,7 @@ New Features
- M88E1512 PHY connects to RJ45 - M88E1512 PHY connects to RJ45
- M88E1512 PHY connects to RGMII combo - M88E1512 PHY connects to RGMII combo
- YT8521S PHY connects to SFP - YT8521S PHY connects to SFP
* Added LED OEM support.
* **Updated Marvell cnxk crypto PMD.** * **Updated Marvell cnxk crypto PMD.**

View File

@ -251,6 +251,10 @@ static inline s32 ngbe_set_phy_pause_adv_dummy(struct ngbe_hw *TUP0, u16 TUP1)
{ {
return NGBE_ERR_OPS_DUMMY; return NGBE_ERR_OPS_DUMMY;
} }
static inline s32 ngbe_phy_led_oem_chk_dummy(struct ngbe_hw *TUP0, u32 *TUP1)
{
return NGBE_ERR_OPS_DUMMY;
}
/* struct ngbe_mbx_operations */ /* struct ngbe_mbx_operations */
static inline void ngbe_mbx_init_params_dummy(struct ngbe_hw *TUP0) static inline void ngbe_mbx_init_params_dummy(struct ngbe_hw *TUP0)
@ -332,6 +336,7 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw)
hw->phy.get_adv_pause = ngbe_get_phy_advertised_pause_dummy; hw->phy.get_adv_pause = ngbe_get_phy_advertised_pause_dummy;
hw->phy.get_lp_adv_pause = ngbe_get_phy_lp_advertised_pause_dummy; hw->phy.get_lp_adv_pause = ngbe_get_phy_lp_advertised_pause_dummy;
hw->phy.set_pause_adv = ngbe_set_phy_pause_adv_dummy; hw->phy.set_pause_adv = ngbe_set_phy_pause_adv_dummy;
hw->phy.led_oem_chk = ngbe_phy_led_oem_chk_dummy;
hw->mbx.init_params = ngbe_mbx_init_params_dummy; hw->mbx.init_params = ngbe_mbx_init_params_dummy;
hw->mbx.read = ngbe_mbx_read_dummy; hw->mbx.read = ngbe_mbx_read_dummy;
hw->mbx.write = ngbe_mbx_write_dummy; hw->mbx.write = ngbe_mbx_write_dummy;

View File

@ -1972,6 +1972,7 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw)
phy->read_reg_unlocked = ngbe_read_phy_reg_mdi; phy->read_reg_unlocked = ngbe_read_phy_reg_mdi;
phy->write_reg_unlocked = ngbe_write_phy_reg_mdi; phy->write_reg_unlocked = ngbe_write_phy_reg_mdi;
phy->reset_hw = ngbe_reset_phy; phy->reset_hw = ngbe_reset_phy;
phy->led_oem_chk = ngbe_phy_led_oem_chk;
/* MAC */ /* MAC */
mac->init_hw = ngbe_init_hw; mac->init_hw = ngbe_init_hw;

View File

@ -338,3 +338,52 @@ s32 ngbe_hic_check_cap(struct ngbe_hw *hw)
return err; return err;
} }
s32 ngbe_phy_led_oem_chk(struct ngbe_hw *hw, u32 *data)
{
struct ngbe_hic_read_shadow_ram command;
s32 err;
int i;
DEBUGFUNC("\n");
command.hdr.req.cmd = FW_PHY_LED_CONF;
command.hdr.req.buf_lenh = 0;
command.hdr.req.buf_lenl = 0;
command.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
/* convert offset from words to bytes */
command.address = 0;
/* one word */
command.length = 0;
for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
err = ngbe_host_interface_command(hw, (u32 *)&command,
sizeof(command),
NGBE_HI_COMMAND_TIMEOUT, true);
if (err)
continue;
command.hdr.rsp.ret_status &= 0x1F;
if (command.hdr.rsp.ret_status !=
FW_CEM_RESP_STATUS_SUCCESS)
err = NGBE_ERR_HOST_INTERFACE_COMMAND;
break;
}
if (err)
return err;
if (command.address == FW_CHECKSUM_CAP_ST_PASS) {
*data = ((u32 *)&command)[2];
err = 0;
} else if (command.address == FW_CHECKSUM_CAP_ST_FAIL) {
*data = FW_CHECKSUM_CAP_ST_FAIL;
err = -1;
} else {
err = NGBE_ERR_EEPROM_CHECKSUM;
}
return err;
}

View File

@ -26,6 +26,7 @@
#define FW_DEFAULT_CHECKSUM 0xFF /* checksum always 0xFF */ #define FW_DEFAULT_CHECKSUM 0xFF /* checksum always 0xFF */
#define FW_NVM_DATA_OFFSET 3 #define FW_NVM_DATA_OFFSET 3
#define FW_EEPROM_CHECK_STATUS 0xE9 #define FW_EEPROM_CHECK_STATUS 0xE9
#define FW_PHY_LED_CONF 0xF1
#define FW_CHECKSUM_CAP_ST_PASS 0x80658383 #define FW_CHECKSUM_CAP_ST_PASS 0x80658383
#define FW_CHECKSUM_CAP_ST_FAIL 0x70657376 #define FW_CHECKSUM_CAP_ST_FAIL 0x70657376
@ -101,4 +102,6 @@ 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_pcie_write(struct ngbe_hw *hw, u16 addr, u32 *buf, int len);
s32 ngbe_hic_check_cap(struct ngbe_hw *hw); s32 ngbe_hic_check_cap(struct ngbe_hw *hw);
s32 ngbe_phy_led_oem_chk(struct ngbe_hw *hw, u32 *data);
#endif /* _NGBE_MNG_H_ */ #endif /* _NGBE_MNG_H_ */

View File

@ -123,16 +123,9 @@ s32 ngbe_init_phy_mvl(struct ngbe_hw *hw)
value = MVL_INTR_EN_ANC | MVL_INTR_EN_LSC; value = MVL_INTR_EN_ANC | MVL_INTR_EN_LSC;
hw->phy.write_reg(hw, MVL_INTR_EN, 0, value); hw->phy.write_reg(hw, MVL_INTR_EN, 0, value);
/* LED control */ ngbe_read_phy_reg_mdi(hw, MVL_CTRL, 0, &value);
ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 3); value |= MVL_CTRL_PWDN;
ngbe_read_phy_reg_mdi(hw, MVL_LEDFCR, 0, &value); ngbe_write_phy_reg_mdi(hw, MVL_CTRL, 0, value);
value &= ~(MVL_LEDFCR_CTL0 | MVL_LEDFCR_CTL1);
value |= MVL_LEDFCR_CTL0_CONF | MVL_LEDFCR_CTL1_CONF;
ngbe_write_phy_reg_mdi(hw, MVL_LEDFCR, 0, value);
ngbe_read_phy_reg_mdi(hw, MVL_LEDPCR, 0, &value);
value &= ~(MVL_LEDPCR_CTL0 | MVL_LEDPCR_CTL1);
value |= MVL_LEDPCR_CTL0_CONF | MVL_LEDPCR_CTL1_CONF;
ngbe_write_phy_reg_mdi(hw, MVL_LEDPCR, 0, value);
return ret_val; return ret_val;
} }
@ -147,6 +140,19 @@ s32 ngbe_setup_phy_link_mvl(struct ngbe_hw *hw, u32 speed,
DEBUGFUNC("ngbe_setup_phy_link_mvl"); DEBUGFUNC("ngbe_setup_phy_link_mvl");
UNREFERENCED_PARAMETER(autoneg_wait_to_complete); UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
if (hw->led_conf == 0xFFFF) {
/* LED control */
ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 3);
ngbe_read_phy_reg_mdi(hw, MVL_LEDFCR, 0, &value);
value &= ~(MVL_LEDFCR_CTL0 | MVL_LEDFCR_CTL1);
value |= MVL_LEDFCR_CTL0_CONF | MVL_LEDFCR_CTL1_CONF;
ngbe_write_phy_reg_mdi(hw, MVL_LEDFCR, 0, value);
ngbe_read_phy_reg_mdi(hw, MVL_LEDPCR, 0, &value);
value &= ~(MVL_LEDPCR_CTL0 | MVL_LEDPCR_CTL1);
value |= MVL_LEDPCR_CTL0_CONF | MVL_LEDPCR_CTL1_CONF;
ngbe_write_phy_reg_mdi(hw, MVL_LEDPCR, 0, value);
}
hw->phy.autoneg_advertised = 0; hw->phy.autoneg_advertised = 0;
if (hw->phy.type == ngbe_phy_mvl) { if (hw->phy.type == ngbe_phy_mvl) {

View File

@ -36,6 +36,30 @@ s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw,
return 0; return 0;
} }
static void ngbe_phy_led_ctrl_rtl(struct ngbe_hw *hw)
{
u16 value = 0;
if (hw->led_conf != 0xFFFF)
value = hw->led_conf & 0xFFFF;
else
value = 0x205B;
hw->phy.write_reg(hw, RTL_LCR, 0xd04, value);
hw->phy.write_reg(hw, RTL_EEELCR, 0xd04, 0);
hw->phy.read_reg(hw, RTL_LPCR, 0xd04, &value);
if (hw->led_conf != 0xFFFF) {
value &= ~0x73;
value |= hw->led_conf >> 16;
} else {
value &= 0xFFFC;
/*act led blinking mode set to 60ms*/
value |= 0x2;
}
hw->phy.write_reg(hw, RTL_LPCR, 0xd04, value);
}
s32 ngbe_init_phy_rtl(struct ngbe_hw *hw) s32 ngbe_init_phy_rtl(struct ngbe_hw *hw)
{ {
int i; int i;
@ -219,15 +243,7 @@ s32 ngbe_setup_phy_link_rtl(struct ngbe_hw *hw,
hw->phy.write_reg(hw, RTL_BMCR, RTL_DEV_ZERO, autoneg_reg); hw->phy.write_reg(hw, RTL_BMCR, RTL_DEV_ZERO, autoneg_reg);
skip_an: skip_an:
autoneg_reg = 0x205B; ngbe_phy_led_ctrl_rtl(hw);
hw->phy.write_reg(hw, RTL_LCR, 0xd04, autoneg_reg);
hw->phy.write_reg(hw, RTL_EEELCR, 0xd04, 0);
hw->phy.read_reg(hw, RTL_LPCR, 0xd04, &autoneg_reg);
autoneg_reg = autoneg_reg & 0xFFFC;
/* act led blinking mode set to 60ms */
autoneg_reg |= 0x2;
hw->phy.write_reg(hw, RTL_LPCR, 0xd04, autoneg_reg);
return 0; return 0;
} }

View File

@ -355,6 +355,7 @@ struct ngbe_phy_info {
bool autoneg_wait_to_complete); bool autoneg_wait_to_complete);
s32 (*check_link)(struct ngbe_hw *hw, u32 *speed, bool *link_up); s32 (*check_link)(struct ngbe_hw *hw, u32 *speed, bool *link_up);
s32 (*set_phy_power)(struct ngbe_hw *hw, bool on); s32 (*set_phy_power)(struct ngbe_hw *hw, bool on);
s32 (*led_oem_chk)(struct ngbe_hw *hw, u32 *data);
s32 (*get_adv_pause)(struct ngbe_hw *hw, u8 *pause_bit); s32 (*get_adv_pause)(struct ngbe_hw *hw, u8 *pause_bit);
s32 (*get_lp_adv_pause)(struct ngbe_hw *hw, u8 *pause_bit); s32 (*get_lp_adv_pause)(struct ngbe_hw *hw, u8 *pause_bit);
s32 (*set_pause_adv)(struct ngbe_hw *hw, u16 pause_bit); s32 (*set_pause_adv)(struct ngbe_hw *hw, u16 pause_bit);
@ -430,6 +431,7 @@ struct ngbe_hw {
bool offset_loaded; bool offset_loaded;
bool is_pf; bool is_pf;
bool gpio_ctl; bool gpio_ctl;
u32 led_conf;
struct { struct {
u64 rx_qp_packets; u64 rx_qp_packets;
u64 tx_qp_packets; u64 tx_qp_packets;

View File

@ -314,6 +314,7 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
struct rte_intr_handle *intr_handle = pci_dev->intr_handle; struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
const struct rte_memzone *mz; const struct rte_memzone *mz;
uint32_t ctrl_ext; uint32_t ctrl_ext;
u32 led_conf = 0;
int err, ret; int err, ret;
PMD_INIT_FUNC_TRACE(); PMD_INIT_FUNC_TRACE();
@ -401,6 +402,12 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
return -EIO; return -EIO;
} }
err = hw->phy.led_oem_chk(hw, &led_conf);
if (err == 0)
hw->led_conf = led_conf;
else
hw->led_conf = 0xFFFF;
err = hw->mac.init_hw(hw); err = hw->mac.init_hw(hw);
if (err != 0) { if (err != 0) {
PMD_INIT_LOG(ERR, "Hardware Initialization Failure: %d", err); PMD_INIT_LOG(ERR, "Hardware Initialization Failure: %d", err);