From: Jiawen Wu <jiawenwu@trustnetic.com>
To: dev@dpdk.org
Cc: Jiawen Wu <jiawenwu@trustnetic.com>
Subject: [dpdk-dev] [PATCH v8 08/19] net/ngbe: identify PHY and reset PHY
Date: Thu, 8 Jul 2021 17:32:28 +0800 [thread overview]
Message-ID: <20210708093239.13896-9-jiawenwu@trustnetic.com> (raw)
In-Reply-To: <20210708093239.13896-1-jiawenwu@trustnetic.com>
Identify PHY to get the PHY type, and perform a PHY reset.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ngbe/base/meson.build | 4 +
drivers/net/ngbe/base/ngbe_dummy.h | 40 +++
drivers/net/ngbe/base/ngbe_hw.c | 38 +++
drivers/net/ngbe/base/ngbe_hw.h | 2 +
drivers/net/ngbe/base/ngbe_phy.c | 426 +++++++++++++++++++++++++++
drivers/net/ngbe/base/ngbe_phy.h | 60 ++++
drivers/net/ngbe/base/ngbe_phy_mvl.c | 89 ++++++
drivers/net/ngbe/base/ngbe_phy_mvl.h | 92 ++++++
drivers/net/ngbe/base/ngbe_phy_rtl.c | 65 ++++
drivers/net/ngbe/base/ngbe_phy_rtl.h | 83 ++++++
drivers/net/ngbe/base/ngbe_phy_yt.c | 112 +++++++
drivers/net/ngbe/base/ngbe_phy_yt.h | 67 +++++
drivers/net/ngbe/base/ngbe_type.h | 17 ++
13 files changed, 1095 insertions(+)
create mode 100644 drivers/net/ngbe/base/ngbe_phy.c
create mode 100644 drivers/net/ngbe/base/ngbe_phy.h
create mode 100644 drivers/net/ngbe/base/ngbe_phy_mvl.c
create mode 100644 drivers/net/ngbe/base/ngbe_phy_mvl.h
create mode 100644 drivers/net/ngbe/base/ngbe_phy_rtl.c
create mode 100644 drivers/net/ngbe/base/ngbe_phy_rtl.h
create mode 100644 drivers/net/ngbe/base/ngbe_phy_yt.c
create mode 100644 drivers/net/ngbe/base/ngbe_phy_yt.h
diff --git a/drivers/net/ngbe/base/meson.build b/drivers/net/ngbe/base/meson.build
index 34f7556e3e..a1a9c2ff65 100644
--- a/drivers/net/ngbe/base/meson.build
+++ b/drivers/net/ngbe/base/meson.build
@@ -5,6 +5,10 @@ sources = [
'ngbe_eeprom.c',
'ngbe_hw.c',
'ngbe_mng.c',
+ 'ngbe_phy.c',
+ 'ngbe_phy_rtl.c',
+ 'ngbe_phy_mvl.c',
+ 'ngbe_phy_yt.c',
]
error_cflags = []
diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h
index 3445e7475a..51ae0acd2c 100644
--- a/drivers/net/ngbe/base/ngbe_dummy.h
+++ b/drivers/net/ngbe/base/ngbe_dummy.h
@@ -64,6 +64,39 @@ static inline s32 ngbe_mac_init_thermal_ssth_dummy(struct ngbe_hw *TUP0)
{
return NGBE_ERR_OPS_DUMMY;
}
+static inline s32 ngbe_mac_check_overtemp_dummy(struct ngbe_hw *TUP0)
+{
+ return NGBE_ERR_OPS_DUMMY;
+}
+/* struct ngbe_phy_operations */
+static inline s32 ngbe_phy_identify_dummy(struct ngbe_hw *TUP0)
+{
+ return NGBE_ERR_OPS_DUMMY;
+}
+static inline s32 ngbe_phy_reset_hw_dummy(struct ngbe_hw *TUP0)
+{
+ return NGBE_ERR_OPS_DUMMY;
+}
+static inline s32 ngbe_phy_read_reg_dummy(struct ngbe_hw *TUP0, u32 TUP1,
+ u32 TUP2, u16 *TUP3)
+{
+ return NGBE_ERR_OPS_DUMMY;
+}
+static inline s32 ngbe_phy_write_reg_dummy(struct ngbe_hw *TUP0, u32 TUP1,
+ u32 TUP2, u16 TUP3)
+{
+ return NGBE_ERR_OPS_DUMMY;
+}
+static inline s32 ngbe_phy_read_reg_unlocked_dummy(struct ngbe_hw *TUP0,
+ u32 TUP1, u32 TUP2, u16 *TUP3)
+{
+ return NGBE_ERR_OPS_DUMMY;
+}
+static inline s32 ngbe_phy_write_reg_unlocked_dummy(struct ngbe_hw *TUP0,
+ u32 TUP1, u32 TUP2, u16 TUP3)
+{
+ return NGBE_ERR_OPS_DUMMY;
+}
static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw)
{
hw->bus.set_lan_id = ngbe_bus_set_lan_id_dummy;
@@ -75,6 +108,13 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw)
hw->mac.acquire_swfw_sync = ngbe_mac_acquire_swfw_sync_dummy;
hw->mac.release_swfw_sync = ngbe_mac_release_swfw_sync_dummy;
hw->mac.init_thermal_sensor_thresh = ngbe_mac_init_thermal_ssth_dummy;
+ hw->mac.check_overtemp = ngbe_mac_check_overtemp_dummy;
+ hw->phy.identify = ngbe_phy_identify_dummy;
+ hw->phy.reset_hw = ngbe_phy_reset_hw_dummy;
+ hw->phy.read_reg = ngbe_phy_read_reg_dummy;
+ hw->phy.write_reg = ngbe_phy_write_reg_dummy;
+ hw->phy.read_reg_unlocked = ngbe_phy_read_reg_unlocked_dummy;
+ hw->phy.write_reg_unlocked = ngbe_phy_write_reg_unlocked_dummy;
}
#endif /* _NGBE_TYPE_DUMMY_H_ */
diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c
index 446f4b52b5..662fb17532 100644
--- a/drivers/net/ngbe/base/ngbe_hw.c
+++ b/drivers/net/ngbe/base/ngbe_hw.c
@@ -4,6 +4,7 @@
*/
#include "ngbe_type.h"
+#include "ngbe_phy.h"
#include "ngbe_eeprom.h"
#include "ngbe_mng.h"
#include "ngbe_hw.h"
@@ -124,6 +125,15 @@ s32 ngbe_reset_hw_em(struct ngbe_hw *hw)
if (status != 0)
return status;
+ /* Identify PHY and related function pointers */
+ status = ngbe_init_phy(hw);
+ if (status)
+ return status;
+
+ /* Reset PHY */
+ if (!hw->phy.reset_disable)
+ hw->phy.reset_hw(hw);
+
wr32(hw, NGBE_RST, NGBE_RST_LAN(hw->bus.lan_id));
ngbe_flush(hw);
msec_delay(50);
@@ -307,6 +317,24 @@ s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw)
return 0;
}
+s32 ngbe_mac_check_overtemp(struct ngbe_hw *hw)
+{
+ s32 status = 0;
+ u32 ts_state;
+
+ DEBUGFUNC("ngbe_mac_check_overtemp");
+
+ /* Check that the LASI temp alarm status was triggered */
+ ts_state = rd32(hw, NGBE_TSALM);
+
+ if (ts_state & NGBE_TSALM_HI)
+ status = NGBE_ERR_UNDERTEMP;
+ else if (ts_state & NGBE_TSALM_LO)
+ status = NGBE_ERR_OVERTEMP;
+
+ return status;
+}
+
void ngbe_disable_rx(struct ngbe_hw *hw)
{
u32 pfdtxgswc;
@@ -434,6 +462,7 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw)
{
struct ngbe_bus_info *bus = &hw->bus;
struct ngbe_mac_info *mac = &hw->mac;
+ struct ngbe_phy_info *phy = &hw->phy;
struct ngbe_rom_info *rom = &hw->rom;
DEBUGFUNC("ngbe_init_ops_pf");
@@ -441,6 +470,14 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw)
/* BUS */
bus->set_lan_id = ngbe_set_lan_id_multi_port;
+ /* PHY */
+ phy->identify = ngbe_identify_phy;
+ phy->read_reg = ngbe_read_phy_reg;
+ phy->write_reg = ngbe_write_phy_reg;
+ phy->read_reg_unlocked = ngbe_read_phy_reg_mdi;
+ phy->write_reg_unlocked = ngbe_write_phy_reg_mdi;
+ phy->reset_hw = ngbe_reset_phy;
+
/* MAC */
mac->init_hw = ngbe_init_hw;
mac->reset_hw = ngbe_reset_hw_em;
@@ -450,6 +487,7 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw)
/* Manageability interface */
mac->init_thermal_sensor_thresh = ngbe_init_thermal_sensor_thresh;
+ mac->check_overtemp = ngbe_mac_check_overtemp;
/* EEPROM */
rom->init_params = ngbe_init_eeprom_params;
diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h
index 207d4b269d..2205156eb9 100644
--- a/drivers/net/ngbe/base/ngbe_hw.h
+++ b/drivers/net/ngbe/base/ngbe_hw.h
@@ -21,10 +21,12 @@ s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask);
void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask);
s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw);
+s32 ngbe_mac_check_overtemp(struct ngbe_hw *hw);
void ngbe_disable_rx(struct ngbe_hw *hw);
s32 ngbe_init_shared_code(struct ngbe_hw *hw);
s32 ngbe_set_mac_type(struct ngbe_hw *hw);
s32 ngbe_init_ops_pf(struct ngbe_hw *hw);
+s32 ngbe_init_phy(struct ngbe_hw *hw);
void ngbe_map_device_id(struct ngbe_hw *hw);
#endif /* _NGBE_HW_H_ */
diff --git a/drivers/net/ngbe/base/ngbe_phy.c b/drivers/net/ngbe/base/ngbe_phy.c
new file mode 100644
index 0000000000..61bb953b6a
--- /dev/null
+++ b/drivers/net/ngbe/base/ngbe_phy.c
@@ -0,0 +1,426 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ * Copyright(c) 2010-2017 Intel Corporation
+ */
+
+#include "ngbe_hw.h"
+#include "ngbe_phy.h"
+
+s32 ngbe_mdi_map_register(mdi_reg_t *reg, mdi_reg_22_t *reg22)
+{
+ bool match = 1;
+ switch (reg->device_type) {
+ case NGBE_MD_DEV_PMA_PMD:
+ switch (reg->addr) {
+ case NGBE_MD_PHY_ID_HIGH:
+ case NGBE_MD_PHY_ID_LOW:
+ reg22->page = 0;
+ reg22->addr = reg->addr;
+ reg22->device_type = 0;
+ break;
+ default:
+ match = 0;
+ }
+ break;
+ default:
+ match = 0;
+ break;
+ }
+
+ if (!match) {
+ reg22->page = reg->device_type;
+ reg22->device_type = reg->device_type;
+ reg22->addr = reg->addr;
+ }
+
+ return 0;
+}
+
+/**
+ * ngbe_probe_phy - Identify a single address for a PHY
+ * @hw: pointer to hardware structure
+ * @phy_addr: PHY address to probe
+ *
+ * Returns true if PHY found
+ */
+static bool ngbe_probe_phy(struct ngbe_hw *hw, u16 phy_addr)
+{
+ if (!ngbe_validate_phy_addr(hw, phy_addr)) {
+ DEBUGOUT("Unable to validate PHY address 0x%04X\n",
+ phy_addr);
+ return false;
+ }
+
+ if (ngbe_get_phy_id(hw))
+ return false;
+
+ hw->phy.type = ngbe_get_phy_type_from_id(hw);
+ if (hw->phy.type == ngbe_phy_unknown)
+ return false;
+
+ return true;
+}
+
+/**
+ * ngbe_identify_phy - Get physical layer module
+ * @hw: pointer to hardware structure
+ *
+ * Determines the physical layer module found on the current adapter.
+ **/
+s32 ngbe_identify_phy(struct ngbe_hw *hw)
+{
+ s32 err = NGBE_ERR_PHY_ADDR_INVALID;
+ u16 phy_addr;
+
+ DEBUGFUNC("ngbe_identify_phy");
+
+ if (hw->phy.type != ngbe_phy_unknown)
+ return 0;
+
+ /* select clause22 */
+ wr32(hw, NGBE_MDIOMODE, NGBE_MDIOMODE_MASK);
+
+ for (phy_addr = 0; phy_addr < NGBE_MAX_PHY_ADDR; phy_addr++) {
+ if (ngbe_probe_phy(hw, phy_addr)) {
+ err = 0;
+ break;
+ }
+ }
+
+ return err;
+}
+
+/**
+ * ngbe_check_reset_blocked - check status of MNG FW veto bit
+ * @hw: pointer to the hardware structure
+ *
+ * This function checks the STAT.MNGVETO bit to see if there are
+ * any constraints on link from manageability. For MAC's that don't
+ * have this bit just return faluse since the link can not be blocked
+ * via this method.
+ **/
+s32 ngbe_check_reset_blocked(struct ngbe_hw *hw)
+{
+ u32 mmngc;
+
+ DEBUGFUNC("ngbe_check_reset_blocked");
+
+ mmngc = rd32(hw, NGBE_STAT);
+ if (mmngc & NGBE_STAT_MNGVETO) {
+ DEBUGOUT("MNG_VETO bit detected.\n");
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * ngbe_validate_phy_addr - Determines phy address is valid
+ * @hw: pointer to hardware structure
+ * @phy_addr: PHY address
+ *
+ **/
+bool ngbe_validate_phy_addr(struct ngbe_hw *hw, u32 phy_addr)
+{
+ u16 phy_id = 0;
+ bool valid = false;
+
+ DEBUGFUNC("ngbe_validate_phy_addr");
+
+ if (hw->sub_device_id == NGBE_SUB_DEV_ID_EM_YT8521S_SFP)
+ return true;
+
+ hw->phy.addr = phy_addr;
+ hw->phy.read_reg(hw, NGBE_MD_PHY_ID_HIGH,
+ NGBE_MD_DEV_PMA_PMD, &phy_id);
+
+ if (phy_id != 0xFFFF && phy_id != 0x0)
+ valid = true;
+
+ DEBUGOUT("PHY ID HIGH is 0x%04X\n", phy_id);
+
+ return valid;
+}
+
+/**
+ * ngbe_get_phy_id - Get the phy ID
+ * @hw: pointer to hardware structure
+ *
+ **/
+s32 ngbe_get_phy_id(struct ngbe_hw *hw)
+{
+ u32 err;
+ u16 phy_id_high = 0;
+ u16 phy_id_low = 0;
+
+ DEBUGFUNC("ngbe_get_phy_id");
+
+ err = hw->phy.read_reg(hw, NGBE_MD_PHY_ID_HIGH,
+ NGBE_MD_DEV_PMA_PMD,
+ &phy_id_high);
+ hw->phy.id = (u32)(phy_id_high << 16);
+
+ err = hw->phy.read_reg(hw, NGBE_MD_PHY_ID_LOW,
+ NGBE_MD_DEV_PMA_PMD,
+ &phy_id_low);
+ hw->phy.id |= (u32)(phy_id_low & NGBE_PHY_REVISION_MASK);
+ hw->phy.revision = (u32)(phy_id_low & ~NGBE_PHY_REVISION_MASK);
+
+ DEBUGOUT("PHY_ID_HIGH 0x%04X, PHY_ID_LOW 0x%04X\n",
+ phy_id_high, phy_id_low);
+
+ return err;
+}
+
+/**
+ * ngbe_get_phy_type_from_id - Get the phy type
+ * @phy_id: PHY ID information
+ *
+ **/
+enum ngbe_phy_type ngbe_get_phy_type_from_id(struct ngbe_hw *hw)
+{
+ enum ngbe_phy_type phy_type;
+
+ DEBUGFUNC("ngbe_get_phy_type_from_id");
+
+ switch (hw->phy.id) {
+ case NGBE_PHYID_RTL:
+ phy_type = ngbe_phy_rtl;
+ break;
+ case NGBE_PHYID_MVL:
+ if (hw->phy.media_type == ngbe_media_type_fiber)
+ phy_type = ngbe_phy_mvl_sfi;
+ else
+ phy_type = ngbe_phy_mvl;
+ break;
+ case NGBE_PHYID_YT:
+ if (hw->phy.media_type == ngbe_media_type_fiber)
+ phy_type = ngbe_phy_yt8521s_sfi;
+ else
+ phy_type = ngbe_phy_yt8521s;
+ break;
+ default:
+ phy_type = ngbe_phy_unknown;
+ break;
+ }
+
+ return phy_type;
+}
+
+/**
+ * ngbe_reset_phy - Performs a PHY reset
+ * @hw: pointer to hardware structure
+ **/
+s32 ngbe_reset_phy(struct ngbe_hw *hw)
+{
+ s32 err = 0;
+
+ DEBUGFUNC("ngbe_reset_phy");
+
+ if (hw->phy.type == ngbe_phy_unknown)
+ err = ngbe_identify_phy(hw);
+
+ if (err != 0 || hw->phy.type == ngbe_phy_none)
+ 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;
+
+ /* Blocked by MNG FW so bail */
+ if (ngbe_check_reset_blocked(hw))
+ return err;
+
+ switch (hw->phy.type) {
+ case ngbe_phy_rtl:
+ err = ngbe_reset_phy_rtl(hw);
+ break;
+ case ngbe_phy_mvl:
+ case ngbe_phy_mvl_sfi:
+ err = ngbe_reset_phy_mvl(hw);
+ break;
+ case ngbe_phy_yt8521s:
+ case ngbe_phy_yt8521s_sfi:
+ err = ngbe_reset_phy_yt(hw);
+ break;
+ default:
+ break;
+ }
+
+ return err;
+}
+
+/**
+ * ngbe_read_phy_mdi - Reads a value from a specified PHY register without
+ * the SWFW lock
+ * @hw: pointer to hardware structure
+ * @reg_addr: 32 bit address of PHY register to read
+ * @device_type: 5 bit device type
+ * @phy_data: Pointer to read data from PHY register
+ **/
+s32 ngbe_read_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+ u16 *phy_data)
+{
+ u32 command, data;
+
+ /* Setup and write the address cycle command */
+ command = NGBE_MDIOSCA_REG(reg_addr) |
+ NGBE_MDIOSCA_DEV(device_type) |
+ NGBE_MDIOSCA_PORT(hw->phy.addr);
+ wr32(hw, NGBE_MDIOSCA, command);
+
+ command = NGBE_MDIOSCD_CMD_READ |
+ NGBE_MDIOSCD_BUSY |
+ NGBE_MDIOSCD_CLOCK(6);
+ wr32(hw, NGBE_MDIOSCD, command);
+
+ /*
+ * Check every 10 usec to see if the address cycle completed.
+ * The MDI Command bit will clear when the operation is
+ * complete
+ */
+ if (!po32m(hw, NGBE_MDIOSCD, NGBE_MDIOSCD_BUSY,
+ 0, NULL, 100, 100)) {
+ DEBUGOUT("PHY address command did not complete\n");
+ return NGBE_ERR_PHY;
+ }
+
+ data = rd32(hw, NGBE_MDIOSCD);
+ *phy_data = (u16)NGBE_MDIOSCD_DAT_R(data);
+
+ return 0;
+}
+
+/**
+ * ngbe_read_phy_reg - Reads a value from a specified PHY register
+ * using the SWFW lock - this function is needed in most cases
+ * @hw: pointer to hardware structure
+ * @reg_addr: 32 bit address of PHY register to read
+ * @device_type: 5 bit device type
+ * @phy_data: Pointer to read data from PHY register
+ **/
+s32 ngbe_read_phy_reg(struct ngbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 *phy_data)
+{
+ s32 err;
+ u32 gssr = hw->phy.phy_semaphore_mask;
+
+ DEBUGFUNC("ngbe_read_phy_reg");
+
+ if (hw->mac.acquire_swfw_sync(hw, gssr))
+ return NGBE_ERR_SWFW_SYNC;
+
+ err = hw->phy.read_reg_unlocked(hw, reg_addr, device_type,
+ phy_data);
+
+ hw->mac.release_swfw_sync(hw, gssr);
+
+ return err;
+}
+
+/**
+ * ngbe_write_phy_reg_mdi - Writes a value to specified PHY register
+ * without SWFW lock
+ * @hw: pointer to hardware structure
+ * @reg_addr: 32 bit PHY register to write
+ * @device_type: 5 bit device type
+ * @phy_data: Data to write to the PHY register
+ **/
+s32 ngbe_write_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 phy_data)
+{
+ u32 command;
+
+ /* write command */
+ command = NGBE_MDIOSCA_REG(reg_addr) |
+ NGBE_MDIOSCA_DEV(device_type) |
+ NGBE_MDIOSCA_PORT(hw->phy.addr);
+ wr32(hw, NGBE_MDIOSCA, command);
+
+ command = NGBE_MDIOSCD_CMD_WRITE |
+ NGBE_MDIOSCD_DAT(phy_data) |
+ NGBE_MDIOSCD_BUSY |
+ NGBE_MDIOSCD_CLOCK(6);
+ wr32(hw, NGBE_MDIOSCD, command);
+
+ /* wait for completion */
+ if (!po32m(hw, NGBE_MDIOSCD, NGBE_MDIOSCD_BUSY,
+ 0, NULL, 100, 100)) {
+ TLOG_DEBUG("PHY write cmd didn't complete\n");
+ return NGBE_ERR_PHY;
+ }
+
+ return 0;
+}
+
+/**
+ * ngbe_write_phy_reg - Writes a value to specified PHY register
+ * using SWFW lock- this function is needed in most cases
+ * @hw: pointer to hardware structure
+ * @reg_addr: 32 bit PHY register to write
+ * @device_type: 5 bit device type
+ * @phy_data: Data to write to the PHY register
+ **/
+s32 ngbe_write_phy_reg(struct ngbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 phy_data)
+{
+ s32 err;
+ u32 gssr = hw->phy.phy_semaphore_mask;
+
+ DEBUGFUNC("ngbe_write_phy_reg");
+
+ if (hw->mac.acquire_swfw_sync(hw, gssr))
+ err = NGBE_ERR_SWFW_SYNC;
+
+ err = hw->phy.write_reg_unlocked(hw, reg_addr, device_type,
+ phy_data);
+
+ hw->mac.release_swfw_sync(hw, gssr);
+
+ return err;
+}
+
+/**
+ * ngbe_init_phy - PHY specific init
+ * @hw: pointer to hardware structure
+ *
+ * Initialize any function pointers that were not able to be
+ * set during init_shared_code because the PHY type was
+ * not known.
+ *
+ **/
+s32 ngbe_init_phy(struct ngbe_hw *hw)
+{
+ struct ngbe_phy_info *phy = &hw->phy;
+ s32 err = 0;
+
+ DEBUGFUNC("ngbe_init_phy");
+
+ hw->phy.addr = 0;
+
+ switch (hw->sub_device_id) {
+ case NGBE_SUB_DEV_ID_EM_RTL_SGMII:
+ hw->phy.read_reg_unlocked = ngbe_read_phy_reg_rtl;
+ hw->phy.write_reg_unlocked = ngbe_write_phy_reg_rtl;
+ break;
+ case NGBE_SUB_DEV_ID_EM_MVL_RGMII:
+ case NGBE_SUB_DEV_ID_EM_MVL_SFP:
+ hw->phy.read_reg_unlocked = ngbe_read_phy_reg_mvl;
+ hw->phy.write_reg_unlocked = ngbe_write_phy_reg_mvl;
+ break;
+ case NGBE_SUB_DEV_ID_EM_YT8521S_SFP:
+ hw->phy.read_reg_unlocked = ngbe_read_phy_reg_yt;
+ hw->phy.write_reg_unlocked = ngbe_write_phy_reg_yt;
+ break;
+ default:
+ break;
+ }
+
+ hw->phy.phy_semaphore_mask = NGBE_MNGSEM_SWPHY;
+
+ /* Identify the PHY */
+ err = phy->identify(hw);
+
+ return err;
+}
+
diff --git a/drivers/net/ngbe/base/ngbe_phy.h b/drivers/net/ngbe/base/ngbe_phy.h
new file mode 100644
index 0000000000..226e0189ec
--- /dev/null
+++ b/drivers/net/ngbe/base/ngbe_phy.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ * Copyright(c) 2010-2017 Intel Corporation
+ */
+
+#ifndef _NGBE_PHY_H_
+#define _NGBE_PHY_H_
+
+#include "ngbe_type.h"
+#include "ngbe_phy_rtl.h"
+#include "ngbe_phy_mvl.h"
+#include "ngbe_phy_yt.h"
+
+/******************************************************************************
+ * PHY MDIO Registers:
+ ******************************************************************************/
+#define NGBE_MAX_PHY_ADDR 32
+
+/* (dev_type = 1) */
+#define NGBE_MD_DEV_PMA_PMD 0x1
+#define NGBE_MD_PHY_ID_HIGH 0x2 /* PHY ID High Reg*/
+#define NGBE_MD_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/
+#define NGBE_PHY_REVISION_MASK 0xFFFFFFF0
+
+/* IEEE 802.3 Clause 22 */
+struct mdi_reg_22 {
+ u16 page;
+ u16 addr;
+ u16 device_type;
+};
+typedef struct mdi_reg_22 mdi_reg_22_t;
+
+/* IEEE 802.3ae Clause 45 */
+struct mdi_reg {
+ u16 device_type;
+ u16 addr;
+};
+typedef struct mdi_reg mdi_reg_t;
+
+#define NGBE_MD22_PHY_ID_HIGH 0x2 /* PHY ID High Reg*/
+#define NGBE_MD22_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/
+
+s32 ngbe_mdi_map_register(mdi_reg_t *reg, mdi_reg_22_t *reg22);
+
+bool ngbe_validate_phy_addr(struct ngbe_hw *hw, u32 phy_addr);
+enum ngbe_phy_type ngbe_get_phy_type_from_id(struct ngbe_hw *hw);
+s32 ngbe_get_phy_id(struct ngbe_hw *hw);
+s32 ngbe_identify_phy(struct ngbe_hw *hw);
+s32 ngbe_reset_phy(struct ngbe_hw *hw);
+s32 ngbe_read_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+ u16 *phy_data);
+s32 ngbe_write_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+ u16 phy_data);
+s32 ngbe_read_phy_reg(struct ngbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 *phy_data);
+s32 ngbe_write_phy_reg(struct ngbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 phy_data);
+s32 ngbe_check_reset_blocked(struct ngbe_hw *hw);
+
+#endif /* _NGBE_PHY_H_ */
diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.c b/drivers/net/ngbe/base/ngbe_phy_mvl.c
new file mode 100644
index 0000000000..1248478252
--- /dev/null
+++ b/drivers/net/ngbe/base/ngbe_phy_mvl.c
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ */
+
+#include "ngbe_phy_mvl.h"
+
+#define MVL_PHY_RST_WAIT_PERIOD 5
+
+s32 ngbe_read_phy_reg_mvl(struct ngbe_hw *hw,
+ u32 reg_addr, u32 device_type, u16 *phy_data)
+{
+ mdi_reg_t reg;
+ mdi_reg_22_t reg22;
+
+ reg.device_type = device_type;
+ reg.addr = reg_addr;
+
+ if (hw->phy.media_type == ngbe_media_type_fiber)
+ ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 1);
+ else
+ ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 0);
+
+ ngbe_mdi_map_register(®, ®22);
+
+ ngbe_read_phy_reg_mdi(hw, reg22.addr, reg22.device_type, phy_data);
+
+ return 0;
+}
+
+s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw,
+ u32 reg_addr, u32 device_type, u16 phy_data)
+{
+ mdi_reg_t reg;
+ mdi_reg_22_t reg22;
+
+ reg.device_type = device_type;
+ reg.addr = reg_addr;
+
+ if (hw->phy.media_type == ngbe_media_type_fiber)
+ ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 1);
+ else
+ ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 0);
+
+ ngbe_mdi_map_register(®, ®22);
+
+ ngbe_write_phy_reg_mdi(hw, reg22.addr, reg22.device_type, phy_data);
+
+ return 0;
+}
+
+s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw)
+{
+ u32 i;
+ u16 ctrl = 0;
+ s32 status = 0;
+
+ DEBUGFUNC("ngbe_reset_phy_mvl");
+
+ if (hw->phy.type != ngbe_phy_mvl && hw->phy.type != ngbe_phy_mvl_sfi)
+ return NGBE_ERR_PHY_TYPE;
+
+ /* select page 18 reg 20 */
+ status = ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 18);
+
+ /* mode select to RGMII-to-copper or RGMII-to-sfi*/
+ if (hw->phy.type == ngbe_phy_mvl)
+ ctrl = MVL_GEN_CTL_MODE_COPPER;
+ else
+ ctrl = MVL_GEN_CTL_MODE_FIBER;
+ status = ngbe_write_phy_reg_mdi(hw, MVL_GEN_CTL, 0, ctrl);
+ /* mode reset */
+ ctrl |= MVL_GEN_CTL_RESET;
+ status = ngbe_write_phy_reg_mdi(hw, MVL_GEN_CTL, 0, ctrl);
+
+ for (i = 0; i < MVL_PHY_RST_WAIT_PERIOD; i++) {
+ status = ngbe_read_phy_reg_mdi(hw, MVL_GEN_CTL, 0, &ctrl);
+ if (!(ctrl & MVL_GEN_CTL_RESET))
+ break;
+ msleep(1);
+ }
+
+ if (i == MVL_PHY_RST_WAIT_PERIOD) {
+ DEBUGOUT("PHY reset polling failed to complete.\n");
+ return NGBE_ERR_RESET_FAILED;
+ }
+
+ return status;
+}
+
diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.h b/drivers/net/ngbe/base/ngbe_phy_mvl.h
new file mode 100644
index 0000000000..ca39f3cd58
--- /dev/null
+++ b/drivers/net/ngbe/base/ngbe_phy_mvl.h
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ */
+
+#include "ngbe_phy.h"
+
+#ifndef _NGBE_PHY_MVL_H_
+#define _NGBE_PHY_MVL_H_
+
+#define NGBE_PHYID_MVL 0x01410DD0U
+
+/* Page 0 for Copper, Page 1 for Fiber */
+#define MVL_CTRL 0x0
+#define MVL_CTRL_RESET MS16(15, 0x1)
+#define MVL_CTRL_ANE MS16(12, 0x1)
+#define MVL_CTRL_RESTART_AN MS16(9, 0x1)
+#define MVL_ANA 0x4
+/* copper */
+#define MVL_CANA_ASM_PAUSE MS16(11, 0x1)
+#define MVL_CANA_PAUSE MS16(10, 0x1)
+#define MVL_PHY_100BASET_FULL MS16(8, 0x1)
+#define MVL_PHY_100BASET_HALF MS16(7, 0x1)
+#define MVL_PHY_10BASET_FULL MS16(6, 0x1)
+#define MVL_PHY_10BASET_HALF MS16(5, 0x1)
+/* fiber */
+#define MVL_FANA_PAUSE_MASK MS16(7, 0x3)
+#define MVL_FANA_SYM_PAUSE LS16(1, 7, 0x3)
+#define MVL_FANA_ASM_PAUSE LS16(2, 7, 0x3)
+#define MVL_PHY_1000BASEX_HALF MS16(6, 0x1)
+#define MVL_PHY_1000BASEX_FULL MS16(5, 0x1)
+#define MVL_LPAR 0x5
+#define MVL_CLPAR_ASM_PAUSE MS(11, 0x1)
+#define MVL_CLPAR_PAUSE MS(10, 0x1)
+#define MVL_FLPAR_PAUSE_MASK MS(7, 0x3)
+#define MVL_PHY_1000BASET 0x9
+#define MVL_PHY_1000BASET_FULL MS16(9, 0x1)
+#define MVL_PHY_1000BASET_HALF MS16(8, 0x1)
+#define MVL_CTRL1 0x10
+#define MVL_CTRL1_INTR_POL MS16(2, 0x1)
+#define MVL_PHYSR 0x11
+#define MVL_PHYSR_SPEED_MASK MS16(14, 0x3)
+#define MVL_PHYSR_SPEED_1000M LS16(2, 14, 0x3)
+#define MVL_PHYSR_SPEED_100M LS16(1, 14, 0x3)
+#define MVL_PHYSR_SPEED_10M LS16(0, 14, 0x3)
+#define MVL_PHYSR_LINK MS16(10, 0x1)
+#define MVL_INTR_EN 0x12
+#define MVL_INTR_EN_ANC MS16(11, 0x1)
+#define MVL_INTR_EN_LSC MS16(10, 0x1)
+#define MVL_INTR 0x13
+#define MVL_INTR_ANC MS16(11, 0x1)
+#define MVL_INTR_LSC MS16(10, 0x1)
+
+/* Page 2 */
+#define MVL_RGM_CTL2 0x15
+#define MVL_RGM_CTL2_TTC MS16(4, 0x1)
+#define MVL_RGM_CTL2_RTC MS16(5, 0x1)
+/* Page 3 */
+#define MVL_LEDFCR 0x10
+#define MVL_LEDFCR_CTL1 MS16(4, 0xF)
+#define MVL_LEDFCR_CTL1_CONF LS16(6, 4, 0xF)
+#define MVL_LEDFCR_CTL0 MS16(0, 0xF)
+#define MVL_LEDFCR_CTL0_CONF LS16(1, 0, 0xF)
+#define MVL_LEDPCR 0x11
+#define MVL_LEDPCR_CTL1 MS16(2, 0x3)
+#define MVL_LEDPCR_CTL1_CONF LS16(1, 2, 0x3)
+#define MVL_LEDPCR_CTL0 MS16(0, 0x3)
+#define MVL_LEDPCR_CTL0_CONF LS16(1, 0, 0x3)
+#define MVL_LEDTCR 0x12
+#define MVL_LEDTCR_INTR_POL MS16(11, 0x1)
+#define MVL_LEDTCR_INTR_EN MS16(7, 0x1)
+/* Page 18 */
+#define MVL_GEN_CTL 0x14
+#define MVL_GEN_CTL_RESET MS16(15, 0x1)
+#define MVL_GEN_CTL_MODE(v) LS16(v, 0, 0x7)
+#define MVL_GEN_CTL_MODE_COPPER LS16(0, 0, 0x7)
+#define MVL_GEN_CTL_MODE_FIBER LS16(2, 0, 0x7)
+
+/* reg 22 */
+#define MVL_PAGE_SEL 22
+
+/* reg 19_0 INT status*/
+#define MVL_PHY_ANC 0x0800
+#define MVL_PHY_LSC 0x0400
+
+s32 ngbe_read_phy_reg_mvl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+ u16 *phy_data);
+s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+ u16 phy_data);
+
+s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw);
+
+#endif /* _NGBE_PHY_MVL_H_ */
diff --git a/drivers/net/ngbe/base/ngbe_phy_rtl.c b/drivers/net/ngbe/base/ngbe_phy_rtl.c
new file mode 100644
index 0000000000..400fbe8c1f
--- /dev/null
+++ b/drivers/net/ngbe/base/ngbe_phy_rtl.c
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ */
+
+#include "ngbe_phy_rtl.h"
+
+#define RTL_PHY_RST_WAIT_PERIOD 5
+
+s32 ngbe_read_phy_reg_rtl(struct ngbe_hw *hw,
+ u32 reg_addr, u32 device_type, u16 *phy_data)
+{
+ mdi_reg_t reg;
+ mdi_reg_22_t reg22;
+
+ reg.device_type = device_type;
+ reg.addr = reg_addr;
+ ngbe_mdi_map_register(®, ®22);
+
+ wr32(hw, NGBE_PHY_CONFIG(RTL_PAGE_SELECT), reg22.page);
+ *phy_data = 0xFFFF & rd32(hw, NGBE_PHY_CONFIG(reg22.addr));
+
+ return 0;
+}
+
+s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw,
+ u32 reg_addr, u32 device_type, u16 phy_data)
+{
+ mdi_reg_t reg;
+ mdi_reg_22_t reg22;
+
+ reg.device_type = device_type;
+ reg.addr = reg_addr;
+ ngbe_mdi_map_register(®, ®22);
+
+ wr32(hw, NGBE_PHY_CONFIG(RTL_PAGE_SELECT), reg22.page);
+ wr32(hw, NGBE_PHY_CONFIG(reg22.addr), phy_data);
+
+ return 0;
+}
+
+s32 ngbe_reset_phy_rtl(struct ngbe_hw *hw)
+{
+ u16 value = 0, i;
+ s32 status = 0;
+
+ DEBUGFUNC("ngbe_reset_phy_rtl");
+
+ value |= RTL_BMCR_RESET;
+ status = hw->phy.write_reg(hw, RTL_BMCR, RTL_DEV_ZERO, value);
+
+ for (i = 0; i < RTL_PHY_RST_WAIT_PERIOD; i++) {
+ status = hw->phy.read_reg(hw, RTL_BMCR, RTL_DEV_ZERO, &value);
+ if (!(value & RTL_BMCR_RESET))
+ break;
+ msleep(1);
+ }
+
+ if (i == RTL_PHY_RST_WAIT_PERIOD) {
+ DEBUGOUT("PHY reset polling failed to complete.\n");
+ return NGBE_ERR_RESET_FAILED;
+ }
+
+ return status;
+}
+
diff --git a/drivers/net/ngbe/base/ngbe_phy_rtl.h b/drivers/net/ngbe/base/ngbe_phy_rtl.h
new file mode 100644
index 0000000000..2da5c7b626
--- /dev/null
+++ b/drivers/net/ngbe/base/ngbe_phy_rtl.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ */
+
+#include "ngbe_phy.h"
+
+#ifndef _NGBE_PHY_RTL_H_
+#define _NGBE_PHY_RTL_H_
+
+#define NGBE_PHYID_RTL 0x001CC800U
+
+/* Page 0 */
+#define RTL_DEV_ZERO 0
+#define RTL_BMCR 0x0
+#define RTL_BMCR_RESET MS16(15, 0x1)
+#define RTL_BMCR_SPEED_SELECT0 MS16(13, 0x1)
+#define RTL_BMCR_ANE MS16(12, 0x1)
+#define RTL_BMCR_RESTART_AN MS16(9, 0x1)
+#define RTL_BMCR_DUPLEX MS16(8, 0x1)
+#define RTL_BMCR_SPEED_SELECT1 MS16(6, 0x1)
+#define RTL_BMSR 0x1
+#define RTL_BMSR_ANC MS16(5, 0x1)
+#define RTL_ID1_OFFSET 0x2
+#define RTL_ID2_OFFSET 0x3
+#define RTL_ID_MASK 0xFFFFFC00U
+#define RTL_ANAR 0x4
+#define RTL_ANAR_APAUSE MS16(11, 0x1)
+#define RTL_ANAR_PAUSE MS16(10, 0x1)
+#define RTL_ANAR_100F MS16(8, 0x1)
+#define RTL_ANAR_100H MS16(7, 0x1)
+#define RTL_ANAR_10F MS16(6, 0x1)
+#define RTL_ANAR_10H MS16(5, 0x1)
+#define RTL_ANLPAR 0x5
+#define RTL_ANLPAR_LP MS16(10, 0x3)
+#define RTL_GBCR 0x9
+#define RTL_GBCR_1000F MS16(9, 0x1)
+/* Page 0xa42*/
+#define RTL_GSR 0x10
+#define RTL_GSR_ST MS16(0, 0x7)
+#define RTL_GSR_ST_LANON MS16(0, 0x3)
+#define RTL_INER 0x12
+#define RTL_INER_LSC MS16(4, 0x1)
+#define RTL_INER_ANC MS16(3, 0x1)
+/* Page 0xa43*/
+#define RTL_PHYSR 0x1A
+#define RTL_PHYSR_SPEED_MASK MS16(4, 0x3)
+#define RTL_PHYSR_SPEED_RES LS16(3, 4, 0x3)
+#define RTL_PHYSR_SPEED_1000M LS16(2, 4, 0x3)
+#define RTL_PHYSR_SPEED_100M LS16(1, 4, 0x3)
+#define RTL_PHYSR_SPEED_10M LS16(0, 4, 0x3)
+#define RTL_PHYSR_DP MS16(3, 0x1)
+#define RTL_PHYSR_RTLS MS16(2, 0x1)
+#define RTL_INSR 0x1D
+#define RTL_INSR_ACCESS MS16(5, 0x1)
+#define RTL_INSR_LSC MS16(4, 0x1)
+#define RTL_INSR_ANC MS16(3, 0x1)
+/* Page 0xa46*/
+#define RTL_SCR 0x14
+#define RTL_SCR_EXTINI MS16(1, 0x1)
+#define RTL_SCR_EFUSE MS16(0, 0x1)
+/* Page 0xa47*/
+/* Page 0xd04*/
+#define RTL_LCR 0x10
+#define RTL_EEELCR 0x11
+#define RTL_LPCR 0x12
+
+/* INTERNAL PHY CONTROL */
+#define RTL_PAGE_SELECT 31
+#define NGBE_INTERNAL_PHY_OFFSET_MAX 32
+#define NGBE_INTERNAL_PHY_ID 0x000732
+
+#define NGBE_INTPHY_LED0 0x0010
+#define NGBE_INTPHY_LED1 0x0040
+#define NGBE_INTPHY_LED2 0x2000
+
+s32 ngbe_read_phy_reg_rtl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+ u16 *phy_data);
+s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+ u16 phy_data);
+
+s32 ngbe_reset_phy_rtl(struct ngbe_hw *hw);
+
+#endif /* _NGBE_PHY_RTL_H_ */
diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.c b/drivers/net/ngbe/base/ngbe_phy_yt.c
new file mode 100644
index 0000000000..a5b032240c
--- /dev/null
+++ b/drivers/net/ngbe/base/ngbe_phy_yt.c
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ */
+
+#include "ngbe_phy_yt.h"
+
+#define YT_PHY_RST_WAIT_PERIOD 5
+
+s32 ngbe_read_phy_reg_yt(struct ngbe_hw *hw,
+ u32 reg_addr, u32 device_type, u16 *phy_data)
+{
+ mdi_reg_t reg;
+ mdi_reg_22_t reg22;
+
+ reg.device_type = device_type;
+ reg.addr = reg_addr;
+
+ ngbe_mdi_map_register(®, ®22);
+
+ /* Read MII reg according to media type */
+ if (hw->phy.media_type == ngbe_media_type_fiber) {
+ ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
+ reg22.device_type, YT_SMI_PHY_SDS);
+ ngbe_read_phy_reg_mdi(hw, reg22.addr,
+ reg22.device_type, phy_data);
+ ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
+ reg22.device_type, 0);
+ } else {
+ ngbe_read_phy_reg_mdi(hw, reg22.addr,
+ reg22.device_type, phy_data);
+ }
+
+ return 0;
+}
+
+s32 ngbe_write_phy_reg_yt(struct ngbe_hw *hw,
+ u32 reg_addr, u32 device_type, u16 phy_data)
+{
+ mdi_reg_t reg;
+ mdi_reg_22_t reg22;
+
+ reg.device_type = device_type;
+ reg.addr = reg_addr;
+
+ ngbe_mdi_map_register(®, ®22);
+
+ /* Write MII reg according to media type */
+ if (hw->phy.media_type == ngbe_media_type_fiber) {
+ ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
+ reg22.device_type, YT_SMI_PHY_SDS);
+ ngbe_write_phy_reg_mdi(hw, reg22.addr,
+ reg22.device_type, phy_data);
+ ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
+ reg22.device_type, 0);
+ } else {
+ ngbe_write_phy_reg_mdi(hw, reg22.addr,
+ reg22.device_type, phy_data);
+ }
+
+ return 0;
+}
+
+s32 ngbe_read_phy_reg_ext_yt(struct ngbe_hw *hw,
+ u32 reg_addr, u32 device_type, u16 *phy_data)
+{
+ ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr);
+ ngbe_read_phy_reg_mdi(hw, 0x1F, device_type, phy_data);
+
+ return 0;
+}
+
+s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw,
+ u32 reg_addr, u32 device_type, u16 phy_data)
+{
+ ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr);
+ ngbe_write_phy_reg_mdi(hw, 0x1F, device_type, phy_data);
+
+ return 0;
+}
+
+s32 ngbe_reset_phy_yt(struct ngbe_hw *hw)
+{
+ u32 i;
+ u16 ctrl = 0;
+ s32 status = 0;
+
+ DEBUGFUNC("ngbe_reset_phy_yt");
+
+ if (hw->phy.type != ngbe_phy_yt8521s &&
+ hw->phy.type != ngbe_phy_yt8521s_sfi)
+ return NGBE_ERR_PHY_TYPE;
+
+ status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl);
+ /* sds software reset */
+ ctrl |= YT_BCR_RESET;
+ status = hw->phy.write_reg(hw, YT_BCR, 0, ctrl);
+
+ for (i = 0; i < YT_PHY_RST_WAIT_PERIOD; i++) {
+ status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl);
+ if (!(ctrl & YT_BCR_RESET))
+ break;
+ msleep(1);
+ }
+
+ if (i == YT_PHY_RST_WAIT_PERIOD) {
+ DEBUGOUT("PHY reset polling failed to complete.\n");
+ return NGBE_ERR_RESET_FAILED;
+ }
+
+ return status;
+}
+
diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.h b/drivers/net/ngbe/base/ngbe_phy_yt.h
new file mode 100644
index 0000000000..6d49464d6d
--- /dev/null
+++ b/drivers/net/ngbe/base/ngbe_phy_yt.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ */
+
+#include "ngbe_phy.h"
+
+#ifndef _NGBE_PHY_YT_H_
+#define _NGBE_PHY_YT_H_
+
+#define NGBE_PHYID_YT 0x00000110U
+
+/* Common EXT */
+#define YT_SMI_PHY 0xA000
+#define YT_SMI_PHY_SDS MS16(1, 0x1) /* 0 for UTP */
+#define YT_CHIP 0xA001
+#define YT_CHIP_SW_RST MS16(15, 0x1)
+#define YT_CHIP_SW_LDO_EN MS16(6, 0x1)
+#define YT_CHIP_MODE_SEL(v) LS16(v, 0, 0x7)
+#define YT_RGMII_CONF1 0xA003
+#define YT_RGMII_CONF1_RXDELAY MS16(10, 0xF)
+#define YT_RGMII_CONF1_TXDELAY_FE MS16(4, 0xF)
+#define YT_RGMII_CONF1_TXDELAY MS16(0, 0x1)
+#define YT_MISC 0xA006
+#define YT_MISC_FIBER_PRIO MS16(8, 0x1) /* 0 for UTP */
+
+/* MII common registers in UTP and SDS */
+#define YT_BCR 0x0
+#define YT_BCR_RESET MS16(15, 0x1)
+#define YT_BCR_PWDN MS16(11, 0x1)
+#define YT_ANA 0x4
+/* copper */
+#define YT_ANA_100BASET_FULL MS16(8, 0x1)
+#define YT_ANA_10BASET_FULL MS16(6, 0x1)
+/* fiber */
+#define YT_FANA_PAUSE_MASK MS16(7, 0x3)
+
+#define YT_LPAR 0x5
+#define YT_CLPAR_ASM_PAUSE MS(11, 0x1)
+#define YT_CLPAR_PAUSE MS(10, 0x1)
+#define YT_FLPAR_PAUSE_MASK MS(7, 0x3)
+
+#define YT_MS_CTRL 0x9
+#define YT_MS_1000BASET_FULL MS16(9, 0x1)
+#define YT_SPST 0x11
+#define YT_SPST_SPEED_MASK MS16(14, 0x3)
+#define YT_SPST_SPEED_1000M LS16(2, 14, 0x3)
+#define YT_SPST_SPEED_100M LS16(1, 14, 0x3)
+#define YT_SPST_SPEED_10M LS16(0, 14, 0x3)
+#define YT_SPST_LINK MS16(10, 0x1)
+
+/* UTP only */
+#define YT_INTR 0x12
+#define YT_INTR_ENA_MASK MS16(2, 0x3)
+#define YT_INTR_STATUS 0x13
+
+s32 ngbe_read_phy_reg_yt(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+ u16 *phy_data);
+s32 ngbe_write_phy_reg_yt(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+ u16 phy_data);
+s32 ngbe_read_phy_reg_ext_yt(struct ngbe_hw *hw,
+ u32 reg_addr, u32 device_type, u16 *phy_data);
+s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw,
+ u32 reg_addr, u32 device_type, u16 phy_data);
+
+s32 ngbe_reset_phy_yt(struct ngbe_hw *hw);
+
+#endif /* _NGBE_PHY_YT_H_ */
diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h
index 9741cb7687..0eabc21b2b 100644
--- a/drivers/net/ngbe/base/ngbe_type.h
+++ b/drivers/net/ngbe/base/ngbe_type.h
@@ -94,6 +94,7 @@ struct ngbe_mac_info {
/* Manageability interface */
s32 (*init_thermal_sensor_thresh)(struct ngbe_hw *hw);
+ s32 (*check_overtemp)(struct ngbe_hw *hw);
enum ngbe_mac_type type;
u32 max_tx_queues;
@@ -103,8 +104,24 @@ struct ngbe_mac_info {
};
struct ngbe_phy_info {
+ s32 (*identify)(struct ngbe_hw *hw);
+ s32 (*reset_hw)(struct ngbe_hw *hw);
+ s32 (*read_reg)(struct ngbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 *phy_data);
+ s32 (*write_reg)(struct ngbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 phy_data);
+ s32 (*read_reg_unlocked)(struct ngbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 *phy_data);
+ s32 (*write_reg_unlocked)(struct ngbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 phy_data);
+
enum ngbe_media_type media_type;
enum ngbe_phy_type type;
+ u32 addr;
+ u32 id;
+ u32 revision;
+ u32 phy_semaphore_mask;
+ bool reset_disable;
};
struct ngbe_hw {
--
2.21.0.windows.1
next prev parent reply other threads:[~2021-07-08 9:33 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-08 9:32 [dpdk-dev] [PATCH v8 00/19] net: ngbe PMD Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 01/19] net/ngbe: add build and doc infrastructure Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 02/19] net/ngbe: support probe and remove Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 03/19] net/ngbe: add log type and error type Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 04/19] net/ngbe: define registers Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 05/19] net/ngbe: set MAC type and LAN ID with device initialization Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 06/19] net/ngbe: init and validate EEPROM Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 07/19] net/ngbe: add HW initialization Jiawen Wu
2021-07-08 9:32 ` Jiawen Wu [this message]
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 09/19] net/ngbe: store MAC address Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 10/19] net/ngbe: support link update Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 11/19] net/ngbe: setup the check PHY link Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 12/19] net/ngbe: add Rx queue setup and release Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 13/19] net/ngbe: add Tx " Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 14/19] net/ngbe: add device start and stop operations Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 15/19] net/ngbe: add Tx queue start and stop Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 16/19] net/ngbe: add Rx " Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 17/19] net/ngbe: add simple Rx flow Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 18/19] net/ngbe: add simple Tx flow Jiawen Wu
2021-07-08 9:32 ` [dpdk-dev] [PATCH v8 19/19] net/ngbe: support to close and reset device Jiawen Wu
2021-07-08 10:12 ` [dpdk-dev] [PATCH v8 00/19] net: ngbe PMD Andrew Rybchenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210708093239.13896-9-jiawenwu@trustnetic.com \
--to=jiawenwu@trustnetic.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.