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);