From: Jiawen Wu Date: Wed, 9 Feb 2022 10:42:08 +0000 (+0800) Subject: net/ngbe: support OEM customized LED X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=fbd5ceb0eff0dbb67127caddddd40d35dd7e926c;p=dpdk.git 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 --- diff --git a/doc/guides/rel_notes/release_22_03.rst b/doc/guides/rel_notes/release_22_03.rst index 5e0254e4a0..bdee13929c 100644 --- a/doc/guides/rel_notes/release_22_03.rst +++ b/doc/guides/rel_notes/release_22_03.rst @@ -109,6 +109,7 @@ New Features - M88E1512 PHY connects to RJ45 - M88E1512 PHY connects to RGMII combo - YT8521S PHY connects to SFP + * Added LED OEM support. * **Updated Marvell cnxk crypto PMD.** diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h index d74c9f7b54..836206e325 100644 --- a/drivers/net/ngbe/base/ngbe_dummy.h +++ b/drivers/net/ngbe/base/ngbe_dummy.h @@ -251,6 +251,10 @@ static inline s32 ngbe_set_phy_pause_adv_dummy(struct ngbe_hw *TUP0, u16 TUP1) { 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 */ 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_lp_adv_pause = ngbe_get_phy_lp_advertised_pause_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.read = ngbe_mbx_read_dummy; hw->mbx.write = ngbe_mbx_write_dummy; diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index 67e4b4a6fd..931fe8c8cb 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -1972,6 +1972,7 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) phy->read_reg_unlocked = ngbe_read_phy_reg_mdi; phy->write_reg_unlocked = ngbe_write_phy_reg_mdi; phy->reset_hw = ngbe_reset_phy; + phy->led_oem_chk = ngbe_phy_led_oem_chk; /* MAC */ mac->init_hw = ngbe_init_hw; diff --git a/drivers/net/ngbe/base/ngbe_mng.c b/drivers/net/ngbe/base/ngbe_mng.c index 68e06e2c24..c6f4dc2e0b 100644 --- a/drivers/net/ngbe/base/ngbe_mng.c +++ b/drivers/net/ngbe/base/ngbe_mng.c @@ -338,3 +338,52 @@ s32 ngbe_hic_check_cap(struct ngbe_hw *hw) 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; +} diff --git a/drivers/net/ngbe/base/ngbe_mng.h b/drivers/net/ngbe/base/ngbe_mng.h index 321338a051..36257d6e5e 100644 --- a/drivers/net/ngbe/base/ngbe_mng.h +++ b/drivers/net/ngbe/base/ngbe_mng.h @@ -26,6 +26,7 @@ #define FW_DEFAULT_CHECKSUM 0xFF /* checksum always 0xFF */ #define FW_NVM_DATA_OFFSET 3 #define FW_EEPROM_CHECK_STATUS 0xE9 +#define FW_PHY_LED_CONF 0xF1 #define FW_CHECKSUM_CAP_ST_PASS 0x80658383 #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_check_cap(struct ngbe_hw *hw); +s32 ngbe_phy_led_oem_chk(struct ngbe_hw *hw, u32 *data); + #endif /* _NGBE_MNG_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.c b/drivers/net/ngbe/base/ngbe_phy_mvl.c index 8a4df90a42..01cb6b9bb3 100644 --- a/drivers/net/ngbe/base/ngbe_phy_mvl.c +++ b/drivers/net/ngbe/base/ngbe_phy_mvl.c @@ -123,16 +123,9 @@ s32 ngbe_init_phy_mvl(struct ngbe_hw *hw) value = MVL_INTR_EN_ANC | MVL_INTR_EN_LSC; hw->phy.write_reg(hw, MVL_INTR_EN, 0, value); - /* 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); + ngbe_read_phy_reg_mdi(hw, MVL_CTRL, 0, &value); + value |= MVL_CTRL_PWDN; + ngbe_write_phy_reg_mdi(hw, MVL_CTRL, 0, value); 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"); 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; if (hw->phy.type == ngbe_phy_mvl) { diff --git a/drivers/net/ngbe/base/ngbe_phy_rtl.c b/drivers/net/ngbe/base/ngbe_phy_rtl.c index c59efe3153..f49d829dff 100644 --- a/drivers/net/ngbe/base/ngbe_phy_rtl.c +++ b/drivers/net/ngbe/base/ngbe_phy_rtl.c @@ -36,6 +36,30 @@ s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw, 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) { 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); skip_an: - autoneg_reg = 0x205B; - 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); + ngbe_phy_led_ctrl_rtl(hw); return 0; } diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index cb8d65ff27..666562bf22 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -355,6 +355,7 @@ struct ngbe_phy_info { bool autoneg_wait_to_complete); s32 (*check_link)(struct ngbe_hw *hw, u32 *speed, bool *link_up); 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_lp_adv_pause)(struct ngbe_hw *hw, u8 *pause_bit); s32 (*set_pause_adv)(struct ngbe_hw *hw, u16 pause_bit); @@ -430,6 +431,7 @@ struct ngbe_hw { bool offset_loaded; bool is_pf; bool gpio_ctl; + u32 led_conf; struct { u64 rx_qp_packets; u64 tx_qp_packets; diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index 9f42c26f9b..4a2a9dde10 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -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; const struct rte_memzone *mz; uint32_t ctrl_ext; + u32 led_conf = 0; int err, ret; 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; } + 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); if (err != 0) { PMD_INIT_LOG(ERR, "Hardware Initialization Failure: %d", err);