Support WOL and NCSI capability for devices. And there is one OEM
NCSI NIC which can not be identified from sub-system ID, it needs
to check NCSI pin status in firmware.

Signed-off-by: Jiawen Wu <jiawe...@trustnetic.com>
---
 drivers/net/ngbe/base/ngbe_hw.c      | 30 ++++++++++++++++++++++++++--
 drivers/net/ngbe/base/ngbe_hw.h      |  1 +
 drivers/net/ngbe/base/ngbe_mng.h     |  1 +
 drivers/net/ngbe/base/ngbe_phy.c     |  6 ++++++
 drivers/net/ngbe/base/ngbe_phy_rtl.c |  5 ++++-
 drivers/net/ngbe/base/ngbe_phy_yt.c  |  3 +++
 drivers/net/ngbe/base/ngbe_type.h    |  2 ++
 drivers/net/ngbe/ngbe_ethdev.c       | 20 ++++++++++++-------
 drivers/net/ngbe/ngbe_rxtx.c         |  5 ++++-
 9 files changed, 62 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c
index 4dced0d328..0f1a5b9f8d 100644
--- a/drivers/net/ngbe/base/ngbe_hw.c
+++ b/drivers/net/ngbe/base/ngbe_hw.c
@@ -173,7 +173,8 @@ s32 ngbe_reset_hw_em(struct ngbe_hw *hw)
        ngbe_reset_misc_em(hw);
        hw->mac.clear_hw_cntrs(hw);
 
-       if (!((hw->sub_device_id & NGBE_OEM_MASK) == NGBE_RGMII_FPGA))
+       if (!(((hw->sub_device_id & NGBE_OEM_MASK) == NGBE_RGMII_FPGA) ||
+                       hw->ncsi_enabled || hw->wol_enabled))
                hw->phy.set_phy_power(hw, false);
 
        msec_delay(50);
@@ -1709,7 +1710,8 @@ void ngbe_disable_rx(struct ngbe_hw *hw)
        }
 
        wr32m(hw, NGBE_PBRXCTL, NGBE_PBRXCTL_ENA, 0);
-       wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, 0);
+       if (!(hw->ncsi_enabled || hw->wol_enabled))
+               wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, 0);
 }
 
 void ngbe_enable_rx(struct ngbe_hw *hw)
@@ -1925,6 +1927,10 @@ void ngbe_map_device_id(struct ngbe_hw *hw)
                        oem == NGBE_INTERNAL_YT8521S_SFP_GPIO ||
                        oem == NGBE_LY_YT8521S_SFP)
                hw->gpio_ctl = true;
+
+       hw->wol_enabled = (hw->sub_system_id & NGBE_WOL_SUP_MASK) ? true : 
false;
+       hw->ncsi_enabled = (hw->sub_system_id & NGBE_NCSI_SUP_MASK ||
+                           hw->sub_system_id & NGBE_OCP_CARD) ? true : false;
 }
 
 /**
@@ -2065,3 +2071,23 @@ s32 ngbe_init_shared_code(struct ngbe_hw *hw)
        return status;
 }
 
+void ngbe_set_ncsi_status(struct ngbe_hw *hw)
+{
+       u16 ncsi_pin = 0;
+       s32 err = 0;
+
+       /* need to check ncsi pin status for oem ncsi card */
+       if (hw->ncsi_enabled || hw->wol_enabled)
+               return;
+
+       err = hw->rom.readw_buffer(hw, FW_READ_SHADOW_RAM_GPIO, 1, &ncsi_pin);
+       if (err) {
+               DEBUGOUT("get ncsi pin status failed");
+               return;
+       }
+
+       if (ncsi_pin == 1) {
+               hw->ncsi_enabled = true;
+               hw->wol_enabled = true;
+       }
+}
diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h
index b92a691fa0..b9805af499 100644
--- a/drivers/net/ngbe/base/ngbe_hw.h
+++ b/drivers/net/ngbe/base/ngbe_hw.h
@@ -86,5 +86,6 @@ 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);
+void ngbe_set_ncsi_status(struct ngbe_hw *hw);
 
 #endif /* _NGBE_HW_H_ */
diff --git a/drivers/net/ngbe/base/ngbe_mng.h b/drivers/net/ngbe/base/ngbe_mng.h
index 36257d6e5e..7dee6053f9 100644
--- a/drivers/net/ngbe/base/ngbe_mng.h
+++ b/drivers/net/ngbe/base/ngbe_mng.h
@@ -27,6 +27,7 @@
 #define FW_NVM_DATA_OFFSET              3
 #define FW_EEPROM_CHECK_STATUS         0xE9
 #define FW_PHY_LED_CONF                        0xF1
+#define FW_READ_SHADOW_RAM_GPIO         0xB4
 
 #define FW_CHECKSUM_CAP_ST_PASS        0x80658383
 #define FW_CHECKSUM_CAP_ST_FAIL        0x70657376
diff --git a/drivers/net/ngbe/base/ngbe_phy.c b/drivers/net/ngbe/base/ngbe_phy.c
index acff7bfebf..6b5c1e47df 100644
--- a/drivers/net/ngbe/base/ngbe_phy.c
+++ b/drivers/net/ngbe/base/ngbe_phy.c
@@ -210,6 +210,9 @@ s32 ngbe_reset_phy(struct ngbe_hw *hw)
        if (err != 0 || hw->phy.type == ngbe_phy_none)
                return err;
 
+       if (hw->ncsi_enabled)
+               return err;
+
        /* Don't reset PHY if it's shut down due to overtemp. */
        if (hw->mac.check_overtemp(hw) == NGBE_ERR_OVERTEMP)
                return err;
@@ -428,6 +431,9 @@ s32 ngbe_init_phy(struct ngbe_hw *hw)
                break;
        }
 
+       if (hw->wol_enabled || hw->ncsi_enabled)
+               hw->phy.reset_disable = true;
+
 init_phy_ops_out:
        return err;
 }
diff --git a/drivers/net/ngbe/base/ngbe_phy_rtl.c 
b/drivers/net/ngbe/base/ngbe_phy_rtl.c
index ba63a8058a..9312bd300b 100644
--- a/drivers/net/ngbe/base/ngbe_phy_rtl.c
+++ b/drivers/net/ngbe/base/ngbe_phy_rtl.c
@@ -295,7 +295,10 @@ s32 ngbe_setup_phy_link_rtl(struct ngbe_hw *hw,
        }
 
        /* restart AN and wait AN done interrupt */
-       autoneg_reg = RTL_BMCR_RESTART_AN | RTL_BMCR_ANE;
+       if (!hw->ncsi_enabled)
+               autoneg_reg = RTL_BMCR_RESTART_AN | RTL_BMCR_ANE;
+       else
+               autoneg_reg = RTL_BMCR_ANE;
        hw->phy.write_reg(hw, RTL_BMCR, RTL_DEV_ZERO, autoneg_reg);
 
 skip_an:
diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.c 
b/drivers/net/ngbe/base/ngbe_phy_yt.c
index a374b015fd..d110fbc8b2 100644
--- a/drivers/net/ngbe/base/ngbe_phy_yt.c
+++ b/drivers/net/ngbe/base/ngbe_phy_yt.c
@@ -126,6 +126,9 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
 
        UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
 
+       if (hw->ncsi_enabled)
+               return 0;
+
        hw->phy.autoneg_advertised = 0;
 
        /* check chip_mode first */
diff --git a/drivers/net/ngbe/base/ngbe_type.h 
b/drivers/net/ngbe/base/ngbe_type.h
index 8a7d2cd331..1b74b7a61f 100644
--- a/drivers/net/ngbe/base/ngbe_type.h
+++ b/drivers/net/ngbe/base/ngbe_type.h
@@ -457,6 +457,8 @@ struct ngbe_hw {
        u32 eeprom_id;
        u8 revision_id;
        bool adapter_stopped;
+       bool wol_enabled;
+       bool ncsi_enabled;
 
        uint64_t isb_dma;
        void IOMEM *isb_mem;
diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c
index c2e186c3d6..2a858b76d0 100644
--- a/drivers/net/ngbe/ngbe_ethdev.c
+++ b/drivers/net/ngbe/ngbe_ethdev.c
@@ -406,6 +406,7 @@ eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void 
*init_params __rte_unused)
 
        /* Unlock any pending hardware semaphore */
        ngbe_swfw_lock_reset(hw);
+       ngbe_set_ncsi_status(hw);
 
        /* Get Hardware Flow Control setting */
        hw->fc.requested_mode = ngbe_fc_full;
@@ -1092,10 +1093,12 @@ ngbe_dev_start(struct rte_eth_dev *dev)
                        speed |= NGBE_LINK_SPEED_10M_FULL;
        }
 
-       err = hw->phy.init_hw(hw);
-       if (err != 0) {
-               PMD_INIT_LOG(ERR, "PHY init failed");
-               goto error;
+       if (!hw->ncsi_enabled) {
+               err = hw->phy.init_hw(hw);
+               if (err != 0) {
+                       PMD_INIT_LOG(ERR, "PHY init failed");
+                       goto error;
+               }
        }
        err = hw->mac.setup_link(hw, speed, link_up);
        if (err != 0)
@@ -1218,7 +1221,8 @@ ngbe_dev_stop(struct rte_eth_dev *dev)
 
 out:
        /* close phy to prevent reset in dev_close from restarting physical 
link */
-       hw->phy.set_phy_power(hw, false);
+       if (!(hw->wol_enabled || hw->ncsi_enabled))
+               hw->phy.set_phy_power(hw, false);
 
        return 0;
 }
@@ -1231,7 +1235,8 @@ ngbe_dev_set_link_up(struct rte_eth_dev *dev)
 {
        struct ngbe_hw *hw = ngbe_dev_hw(dev);
 
-       hw->phy.set_phy_power(hw, true);
+       if (!(hw->ncsi_enabled || hw->wol_enabled))
+               hw->phy.set_phy_power(hw, true);
 
        return 0;
 }
@@ -1244,7 +1249,8 @@ ngbe_dev_set_link_down(struct rte_eth_dev *dev)
 {
        struct ngbe_hw *hw = ngbe_dev_hw(dev);
 
-       hw->phy.set_phy_power(hw, false);
+       if (!(hw->ncsi_enabled || hw->wol_enabled))
+               hw->phy.set_phy_power(hw, false);
 
        return 0;
 }
diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c
index 9de12767df..c54c67f7ee 100644
--- a/drivers/net/ngbe/ngbe_rxtx.c
+++ b/drivers/net/ngbe/ngbe_rxtx.c
@@ -2943,7 +2943,10 @@ ngbe_dev_rx_init(struct rte_eth_dev *dev)
         * Make sure receives are disabled while setting
         * up the Rx context (registers, descriptor rings, etc.).
         */
-       wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, 0);
+
+       if (!(hw->ncsi_enabled || hw->wol_enabled))
+               wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, 0);
+
        wr32m(hw, NGBE_PBRXCTL, NGBE_PBRXCTL_ENA, 0);
 
        /* Enable receipt of broadcasted frames */
-- 
2.27.0

Reply via email to