All of lore.kernel.org
 help / color / mirror / Atom feed
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(&reg, &reg22);
+
+	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(&reg, &reg22);
+
+	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(&reg, &reg22);
+
+	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(&reg, &reg22);
+
+	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(&reg, &reg22);
+
+	/* 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(&reg, &reg22);
+
+	/* 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




  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.