]> git.droids-corp.org - dpdk.git/commitdiff
net/ngbe: support OEM customized LED
authorJiawen Wu <jiawenwu@trustnetic.com>
Wed, 9 Feb 2022 10:42:08 +0000 (18:42 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 11 Feb 2022 12:49:12 +0000 (13:49 +0100)
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>
doc/guides/rel_notes/release_22_03.rst
drivers/net/ngbe/base/ngbe_dummy.h
drivers/net/ngbe/base/ngbe_hw.c
drivers/net/ngbe/base/ngbe_mng.c
drivers/net/ngbe/base/ngbe_mng.h
drivers/net/ngbe/base/ngbe_phy_mvl.c
drivers/net/ngbe/base/ngbe_phy_rtl.c
drivers/net/ngbe/base/ngbe_type.h
drivers/net/ngbe/ngbe_ethdev.c

index 5e0254e4a08fdf4e87a6feff7ee77e1d5093fe87..bdee13929c81321f1c139d531b87d6b99839b5d2 100644 (file)
@@ -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.**
 
index d74c9f7b54c0cd8319e8833bb7907aacdd9ec880..836206e32535e3c9e6ecdfdd69c2f1637abf9af8 100644 (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;
 }
+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;
index 67e4b4a6fdbac9fbe3eaf4a6224f130978155855..931fe8c8cbafc486cf2ad02e97e60461a902ab40 100644 (file)
@@ -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;
index 68e06e2c246bbf59b623e3f213a39db59f2fb827..c6f4dc2e0b024b82eafee51a6c1d2803d15d12d0 100644 (file)
@@ -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;
+}
index 321338a0515036b9c24283061ea63ff64a5d256c..36257d6e5e9467f21071bab2afa2a785fccde92c 100644 (file)
@@ -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_ */
index 8a4df90a42676825d7de39bc52b43e53a44ffca3..01cb6b9bb354ae7c268675f4ad31f9b961b53025 100644 (file)
@@ -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) {
index c59efe3153fea110f253261498888f65a6371ad3..f49d829dff356ea797d0465cd5189705e05e5b44 100644 (file)
@@ -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;
 }
index cb8d65ff274ec743b07ad53256413b615d776a1a..666562bf22d3db34aedd97a901fec169f65ee5df 100644 (file)
@@ -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;
index 9f42c26f9b16e4f90b8f5f05a96d146b6174fdec..4a2a9dde10b215afc77a462baece2a1c68ac67ce 100644 (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;
        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);