From: Jiawen Wu <jiawenwu@trustnetic.com>
To: dev@dpdk.org
Cc: Jiawen Wu <jiawenwu@trustnetic.com>
Subject: [PATCH v2 06/12] net/ngbe: add support to custom PHY interfaces
Date: Wed, 9 Feb 2022 18:42:07 +0800 [thread overview]
Message-ID: <20220209104213.602728-7-jiawenwu@trustnetic.com> (raw)
In-Reply-To: <20220209104213.602728-1-jiawenwu@trustnetic.com>
Support sub_device ID 61/62/64 for YT8521S SFP, and 51/52 for M88E1512
PHY.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
doc/guides/rel_notes/release_22_03.rst | 7 +
drivers/net/ngbe/base/ngbe_devids.h | 12 +-
drivers/net/ngbe/base/ngbe_hw.c | 50 +++++--
drivers/net/ngbe/base/ngbe_phy.c | 27 ++--
drivers/net/ngbe/base/ngbe_phy.h | 2 +-
drivers/net/ngbe/base/ngbe_phy_mvl.c | 55 +++++++-
drivers/net/ngbe/base/ngbe_phy_mvl.h | 5 +
drivers/net/ngbe/base/ngbe_phy_yt.c | 182 +++++++++++++++++++++----
drivers/net/ngbe/base/ngbe_phy_yt.h | 19 ++-
drivers/net/ngbe/base/ngbe_type.h | 8 ++
drivers/net/ngbe/ngbe_ethdev.c | 6 +-
11 files changed, 314 insertions(+), 59 deletions(-)
diff --git a/doc/guides/rel_notes/release_22_03.rst b/doc/guides/rel_notes/release_22_03.rst
index 746f50e84f..233c34a2d0 100644
--- a/doc/guides/rel_notes/release_22_03.rst
+++ b/doc/guides/rel_notes/release_22_03.rst
@@ -69,6 +69,13 @@ New Features
* Added AES-XCBC support in lookaside protocol (IPsec) for CN9K & CN10K.
* Added AES-CMAC support in CN9K & CN10K.
+* **Updated Wangxun ngbe driver.**
+
+ * Added support for devices of custom PHY interfaces.
+ - M88E1512 PHY connects to RJ45
+ - M88E1512 PHY connects to RGMII combo
+ - YT8521S PHY connects to SFP
+
* **Added an API to retrieve event port id of ethdev Rx adapter.**
The new API ``rte_event_eth_rx_adapter_event_port_get()`` was added.
diff --git a/drivers/net/ngbe/base/ngbe_devids.h b/drivers/net/ngbe/base/ngbe_devids.h
index 6010cc050e..83eedf423e 100644
--- a/drivers/net/ngbe/base/ngbe_devids.h
+++ b/drivers/net/ngbe/base/ngbe_devids.h
@@ -19,9 +19,11 @@
#define NGBE_SUB_DEV_ID_EM_VF 0x0110
#define NGBE_DEV_ID_EM 0x0100
#define NGBE_SUB_DEV_ID_EM_MVL_RGMII 0x0200
+#define NGBE_SUB_DEV_ID_EM_MVL_MIX 0x0252
#define NGBE_SUB_DEV_ID_EM_MVL_SFP 0x0403
#define NGBE_SUB_DEV_ID_EM_RTL_SGMII 0x0410
#define NGBE_SUB_DEV_ID_EM_YT8521S_SFP 0x0460
+#define NGBE_SUB_DEV_ID_EM_RTL_YT8521S_SFP 0x0461
#define NGBE_DEV_ID_EM_WX1860AL_W 0x0100
#define NGBE_DEV_ID_EM_WX1860AL_W_VF 0x0110
@@ -67,15 +69,19 @@
#define NGBE_SUB_DEV_ID_EM_SF400_LY_YT 0x0470
/* Assign excessive id with masks */
-#define NGBE_INTERNAL_MASK 0x000F
-#define NGBE_OEM_MASK 0x00F0
+#define NGBE_OEM_MASK 0x00FF
#define NGBE_WOL_SUP_MASK 0x4000
#define NGBE_NCSI_SUP_MASK 0x8000
-#define NGBE_INTERNAL_SFP 0x0003
+#define NGBE_M88E1512_SFP 0x0003
#define NGBE_OCP_CARD 0x0040
#define NGBE_LY_M88E1512_SFP 0x0050
+#define NGBE_M88E1512_RJ45 0x0051
+#define NGBE_M88E1512_MIX 0x0052
#define NGBE_YT8521S_SFP 0x0060
+#define NGBE_INTERNAL_YT8521S_SFP 0x0061
+#define NGBE_YT8521S_SFP_GPIO 0x0062
+#define NGBE_INTERNAL_YT8521S_SFP_GPIO 0x0064
#define NGBE_LY_YT8521S_SFP 0x0070
#define NGBE_WOL_SUP 0x4000
#define NGBE_NCSI_SUP 0x8000
diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c
index 72d475ccf9..67e4b4a6fd 100644
--- a/drivers/net/ngbe/base/ngbe_hw.c
+++ b/drivers/net/ngbe/base/ngbe_hw.c
@@ -124,8 +124,7 @@ ngbe_reset_misc_em(struct ngbe_hw *hw)
wr32m(hw, NGBE_GPIE, NGBE_GPIE_MSIX, NGBE_GPIE_MSIX);
- if ((hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_M88E1512_SFP ||
- (hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_YT8521S_SFP) {
+ if (hw->gpio_ctl) {
/* gpio0 is used to power on/off control*/
wr32(hw, NGBE_GPIODIR, NGBE_GPIODIR_DDR(1));
wr32(hw, NGBE_GPIODATA, NGBE_GPIOBIT_0);
@@ -1617,19 +1616,21 @@ s32 ngbe_get_link_capabilities_em(struct ngbe_hw *hw,
bool *autoneg)
{
s32 status = 0;
-
+ u16 value = 0;
DEBUGFUNC("\n");
hw->mac.autoneg = *autoneg;
- switch (hw->sub_device_id) {
- case NGBE_SUB_DEV_ID_EM_RTL_SGMII:
+ if (hw->phy.type == ngbe_phy_rtl) {
*speed = NGBE_LINK_SPEED_1GB_FULL |
NGBE_LINK_SPEED_100M_FULL |
NGBE_LINK_SPEED_10M_FULL;
- break;
- default:
- break;
+ }
+
+ if (hw->phy.type == ngbe_phy_yt8521s_sfi) {
+ ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value);
+ if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(1))
+ *speed = NGBE_LINK_SPEED_1GB_FULL;
}
return status;
@@ -1815,11 +1816,23 @@ s32 ngbe_set_mac_type(struct ngbe_hw *hw)
case NGBE_SUB_DEV_ID_EM_MVL_RGMII:
hw->phy.media_type = ngbe_media_type_copper;
hw->mac.type = ngbe_mac_em;
+ hw->mac.link_type = ngbe_link_copper;
+ break;
+ case NGBE_SUB_DEV_ID_EM_RTL_YT8521S_SFP:
+ hw->phy.media_type = ngbe_media_type_copper;
+ hw->mac.type = ngbe_mac_em;
+ hw->mac.link_type = ngbe_link_fiber;
break;
case NGBE_SUB_DEV_ID_EM_MVL_SFP:
case NGBE_SUB_DEV_ID_EM_YT8521S_SFP:
hw->phy.media_type = ngbe_media_type_fiber;
hw->mac.type = ngbe_mac_em;
+ hw->mac.link_type = ngbe_link_fiber;
+ break;
+ case NGBE_SUB_DEV_ID_EM_MVL_MIX:
+ hw->phy.media_type = ngbe_media_type_unknown;
+ hw->mac.type = ngbe_mac_em;
+ hw->mac.link_type = ngbe_link_type_unknown;
break;
case NGBE_SUB_DEV_ID_EM_VF:
hw->phy.media_type = ngbe_media_type_virtual;
@@ -1871,7 +1884,7 @@ s32 ngbe_enable_rx_dma(struct ngbe_hw *hw, u32 regval)
void ngbe_map_device_id(struct ngbe_hw *hw)
{
u16 oem = hw->sub_system_id & NGBE_OEM_MASK;
- u16 internal = hw->sub_system_id & NGBE_INTERNAL_MASK;
+
hw->is_pf = true;
/* move subsystem_device_id to device_id */
@@ -1905,20 +1918,31 @@ void ngbe_map_device_id(struct ngbe_hw *hw)
case NGBE_DEV_ID_EM_WX1860A1:
case NGBE_DEV_ID_EM_WX1860A1L:
hw->device_id = NGBE_DEV_ID_EM;
- if (oem == NGBE_LY_M88E1512_SFP ||
- internal == NGBE_INTERNAL_SFP)
+ if (oem == NGBE_M88E1512_SFP || oem == NGBE_LY_M88E1512_SFP)
hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_SFP;
- else if (hw->sub_system_id == NGBE_SUB_DEV_ID_EM_M88E1512_RJ45)
+ else if (oem == NGBE_M88E1512_RJ45 ||
+ (hw->sub_system_id == NGBE_SUB_DEV_ID_EM_M88E1512_RJ45))
hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_RGMII;
+ else if (oem == NGBE_M88E1512_MIX)
+ hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_MIX;
else if (oem == NGBE_YT8521S_SFP ||
- oem == NGBE_LY_YT8521S_SFP)
+ oem == NGBE_YT8521S_SFP_GPIO ||
+ oem == NGBE_LY_YT8521S_SFP)
hw->sub_device_id = NGBE_SUB_DEV_ID_EM_YT8521S_SFP;
+ else if (oem == NGBE_INTERNAL_YT8521S_SFP ||
+ oem == NGBE_INTERNAL_YT8521S_SFP_GPIO)
+ hw->sub_device_id = NGBE_SUB_DEV_ID_EM_RTL_YT8521S_SFP;
else
hw->sub_device_id = NGBE_SUB_DEV_ID_EM_RTL_SGMII;
break;
default:
break;
}
+
+ if (oem == NGBE_LY_M88E1512_SFP || oem == NGBE_YT8521S_SFP_GPIO ||
+ oem == NGBE_INTERNAL_YT8521S_SFP_GPIO ||
+ oem == NGBE_LY_YT8521S_SFP)
+ hw->gpio_ctl = true;
}
/**
diff --git a/drivers/net/ngbe/base/ngbe_phy.c b/drivers/net/ngbe/base/ngbe_phy.c
index 51b0a2ec60..93450b2977 100644
--- a/drivers/net/ngbe/base/ngbe_phy.c
+++ b/drivers/net/ngbe/base/ngbe_phy.c
@@ -54,8 +54,7 @@ static bool ngbe_probe_phy(struct ngbe_hw *hw, u16 phy_addr)
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)
+ if (ngbe_get_phy_type_from_id(hw))
return false;
return true;
@@ -174,37 +173,39 @@ s32 ngbe_get_phy_id(struct ngbe_hw *hw)
/**
* 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)
+s32 ngbe_get_phy_type_from_id(struct ngbe_hw *hw)
{
- enum ngbe_phy_type phy_type;
+ s32 status = 0;
DEBUGFUNC("ngbe_get_phy_type_from_id");
switch (hw->phy.id) {
case NGBE_PHYID_RTL:
- phy_type = ngbe_phy_rtl;
+ hw->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;
+ hw->phy.type = ngbe_phy_mvl_sfi;
+ else if (hw->phy.media_type == ngbe_media_type_copper)
+ hw->phy.type = ngbe_phy_mvl;
else
- phy_type = ngbe_phy_mvl;
+ status = ngbe_check_phy_mode_mvl(hw);
break;
case NGBE_PHYID_YT:
if (hw->phy.media_type == ngbe_media_type_fiber)
- phy_type = ngbe_phy_yt8521s_sfi;
+ hw->phy.type = ngbe_phy_yt8521s_sfi;
else
- phy_type = ngbe_phy_yt8521s;
+ hw->phy.type = ngbe_phy_yt8521s;
break;
default:
- phy_type = ngbe_phy_unknown;
+ hw->phy.type = ngbe_phy_unknown;
+ status = NGBE_ERR_DEVICE_NOT_SUPPORTED;
break;
}
- return phy_type;
+ return status;
}
/**
@@ -400,11 +401,13 @@ s32 ngbe_init_phy(struct ngbe_hw *hw)
switch (hw->sub_device_id) {
case NGBE_SUB_DEV_ID_EM_RTL_SGMII:
+ case NGBE_SUB_DEV_ID_EM_RTL_YT8521S_SFP:
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:
+ case NGBE_SUB_DEV_ID_EM_MVL_MIX:
hw->phy.read_reg_unlocked = ngbe_read_phy_reg_mvl;
hw->phy.write_reg_unlocked = ngbe_write_phy_reg_mvl;
break;
diff --git a/drivers/net/ngbe/base/ngbe_phy.h b/drivers/net/ngbe/base/ngbe_phy.h
index f262ff3350..e93d6a4c4a 100644
--- a/drivers/net/ngbe/base/ngbe_phy.h
+++ b/drivers/net/ngbe/base/ngbe_phy.h
@@ -48,7 +48,7 @@ typedef struct mdi_reg mdi_reg_t;
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_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);
diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.c b/drivers/net/ngbe/base/ngbe_phy_mvl.c
index 2eb351d258..8a4df90a42 100644
--- a/drivers/net/ngbe/base/ngbe_phy_mvl.c
+++ b/drivers/net/ngbe/base/ngbe_phy_mvl.c
@@ -48,6 +48,31 @@ s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw,
return 0;
}
+s32 ngbe_check_phy_mode_mvl(struct ngbe_hw *hw)
+{
+ u16 value = 0;
+
+ /* select page 18 reg 20 */
+ ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 18);
+ ngbe_read_phy_reg_mdi(hw, MVL_GEN_CTL, 0, &value);
+ if (MVL_GEN_CTL_MODE(value) == MVL_GEN_CTL_MODE_COPPER) {
+ /* mode select to RGMII-to-copper */
+ hw->phy.type = ngbe_phy_mvl;
+ hw->phy.media_type = ngbe_media_type_copper;
+ hw->mac.link_type = ngbe_link_copper;
+ } else if (MVL_GEN_CTL_MODE(value) == MVL_GEN_CTL_MODE_FIBER) {
+ /* mode select to RGMII-to-sfi */
+ hw->phy.type = ngbe_phy_mvl_sfi;
+ hw->phy.media_type = ngbe_media_type_fiber;
+ hw->mac.link_type = ngbe_link_fiber;
+ } else {
+ DEBUGOUT("marvell 88E1512 mode %x is not supported.\n", value);
+ return NGBE_ERR_DEVICE_NOT_SUPPORTED;
+ }
+
+ return 0;
+}
+
s32 ngbe_init_phy_mvl(struct ngbe_hw *hw)
{
s32 ret_val = 0;
@@ -125,6 +150,29 @@ s32 ngbe_setup_phy_link_mvl(struct ngbe_hw *hw, u32 speed,
hw->phy.autoneg_advertised = 0;
if (hw->phy.type == ngbe_phy_mvl) {
+ if (!hw->mac.autoneg) {
+ switch (speed) {
+ case NGBE_LINK_SPEED_1GB_FULL:
+ value = MVL_CTRL_SPEED_SELECT1;
+ break;
+ case NGBE_LINK_SPEED_100M_FULL:
+ value = MVL_CTRL_SPEED_SELECT0;
+ break;
+ case NGBE_LINK_SPEED_10M_FULL:
+ value = 0;
+ break;
+ default:
+ value = MVL_CTRL_SPEED_SELECT0 |
+ MVL_CTRL_SPEED_SELECT1;
+ DEBUGOUT("unknown speed = 0x%x.\n", speed);
+ break;
+ }
+ /* duplex full */
+ value |= MVL_CTRL_DUPLEX | MVL_CTRL_RESET;
+ ngbe_write_phy_reg_mdi(hw, MVL_CTRL, 0, value);
+
+ goto skip_an;
+ }
if (speed & NGBE_LINK_SPEED_1GB_FULL) {
value_r9 |= MVL_PHY_1000BASET_FULL;
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
@@ -162,7 +210,12 @@ s32 ngbe_setup_phy_link_mvl(struct ngbe_hw *hw, u32 speed,
hw->phy.write_reg(hw, MVL_ANA, 0, value);
}
- value = MVL_CTRL_RESTART_AN | MVL_CTRL_ANE;
+ value = MVL_CTRL_RESTART_AN | MVL_CTRL_ANE | MVL_CTRL_RESET;
+ ngbe_write_phy_reg_mdi(hw, MVL_CTRL, 0, value);
+
+skip_an:
+ ngbe_read_phy_reg_mdi(hw, MVL_CTRL, 0, &value);
+ value |= MVL_CTRL_PWDN;
ngbe_write_phy_reg_mdi(hw, MVL_CTRL, 0, value);
hw->phy.read_reg(hw, MVL_INTR, 0, &value);
diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.h b/drivers/net/ngbe/base/ngbe_phy_mvl.h
index a2b5202d4b..8aee236390 100644
--- a/drivers/net/ngbe/base/ngbe_phy_mvl.h
+++ b/drivers/net/ngbe/base/ngbe_phy_mvl.h
@@ -12,8 +12,12 @@
/* Page 0 for Copper, Page 1 for Fiber */
#define MVL_CTRL 0x0
#define MVL_CTRL_RESET MS16(15, 0x1)
+#define MVL_CTRL_SPEED_SELECT0 MS16(13, 0x1)
#define MVL_CTRL_ANE MS16(12, 0x1)
+#define MVL_CTRL_PWDN MS16(11, 0x1)
#define MVL_CTRL_RESTART_AN MS16(9, 0x1)
+#define MVL_CTRL_DUPLEX MS16(8, 0x1)
+#define MVL_CTRL_SPEED_SELECT1 MS16(6, 0x1)
#define MVL_ANA 0x4
/* copper */
#define MVL_CANA_ASM_PAUSE MS16(11, 0x1)
@@ -86,6 +90,7 @@ 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_check_phy_mode_mvl(struct ngbe_hw *hw);
s32 ngbe_init_phy_mvl(struct ngbe_hw *hw);
s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw);
diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.c b/drivers/net/ngbe/base/ngbe_phy_yt.c
index 8db0f9ce48..2d184a1c30 100644
--- a/drivers/net/ngbe/base/ngbe_phy_yt.c
+++ b/drivers/net/ngbe/base/ngbe_phy_yt.c
@@ -104,23 +104,22 @@ s32 ngbe_init_phy_yt(struct ngbe_hw *hw)
DEBUGFUNC("ngbe_init_phy_yt");
- if (hw->phy.type != ngbe_phy_yt8521s_sfi)
- return 0;
-
- /* select sds area register */
+ /* close sds area register */
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
/* enable interrupts */
- ngbe_write_phy_reg_mdi(hw, YT_INTR, 0, YT_INTR_ENA_MASK);
-
- /* select fiber_to_rgmii first in multiplex */
- ngbe_read_phy_reg_ext_yt(hw, YT_MISC, 0, &value);
- value |= YT_MISC_FIBER_PRIO;
- ngbe_write_phy_reg_ext_yt(hw, YT_MISC, 0, value);
+ ngbe_write_phy_reg_mdi(hw, YT_INTR, 0,
+ YT_INTR_ENA_MASK | YT_SDS_INTR_ENA_MASK);
+ /* power down in fiber mode */
hw->phy.read_reg(hw, YT_BCR, 0, &value);
value |= YT_BCR_PWDN;
hw->phy.write_reg(hw, YT_BCR, 0, value);
+ /* power down in UTP mode */
+ ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &value);
+ value |= YT_BCR_PWDN;
+ ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
+
return 0;
}
@@ -136,15 +135,44 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
hw->phy.autoneg_advertised = 0;
- if (hw->phy.type == ngbe_phy_yt8521s) {
+ /* check chip_mode first */
+ ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value);
+ if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(0)) {
+ /* UTP to rgmii */
+ if (!hw->mac.autoneg) {
+ switch (speed) {
+ case NGBE_LINK_SPEED_1GB_FULL:
+ value = YT_BCR_SPEED_SELECT1;
+ break;
+ case NGBE_LINK_SPEED_100M_FULL:
+ value = YT_BCR_SPEED_SELECT0;
+ break;
+ case NGBE_LINK_SPEED_10M_FULL:
+ value = 0;
+ break;
+ default:
+ value = YT_BCR_SPEED_SELECT0 |
+ YT_BCR_SPEED_SELECT1;
+ DEBUGOUT("unknown speed = 0x%x.\n",
+ speed);
+ break;
+ }
+ /* duplex full */
+ value |= YT_BCR_DUPLEX | YT_BCR_RESET;
+ hw->phy.write_reg(hw, YT_BCR, 0, value);
+
+ goto skip_an;
+ }
+
/*disable 100/10base-T Self-negotiation ability*/
hw->phy.read_reg(hw, YT_ANA, 0, &value);
- value &= ~(YT_ANA_100BASET_FULL | YT_ANA_10BASET_FULL);
+ value &= ~(YT_ANA_100BASET_FULL | YT_ANA_100BASET_HALF |
+ YT_ANA_10BASET_FULL | YT_ANA_10BASET_HALF);
hw->phy.write_reg(hw, YT_ANA, 0, value);
/*disable 1000base-T Self-negotiation ability*/
hw->phy.read_reg(hw, YT_MS_CTRL, 0, &value);
- value &= ~YT_MS_1000BASET_FULL;
+ value &= ~(YT_MS_1000BASET_FULL | YT_MS_1000BASET_HALF);
hw->phy.write_reg(hw, YT_MS_CTRL, 0, value);
if (speed & NGBE_LINK_SPEED_1GB_FULL) {
@@ -172,9 +200,15 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
/* software reset to make the above configuration take effect*/
hw->phy.read_reg(hw, YT_BCR, 0, &value);
- value |= YT_BCR_RESET;
+ value |= YT_BCR_RESET | YT_BCR_ANE | YT_BCR_RESTART_AN;
hw->phy.write_reg(hw, YT_BCR, 0, value);
- } else {
+skip_an:
+ /* power on in UTP mode */
+ ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &value);
+ value &= ~YT_BCR_PWDN;
+ ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
+ } else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(1)) {
+ /* fiber to rgmii */
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
/* RGMII_Config1 : Config rx and tx training delay */
@@ -190,6 +224,88 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
/* software reset */
ngbe_write_phy_reg_sds_ext_yt(hw, 0x0, 0, 0x9140);
+ /* power on phy */
+ hw->phy.read_reg(hw, YT_BCR, 0, &value);
+ value &= ~YT_BCR_PWDN;
+ hw->phy.write_reg(hw, YT_BCR, 0, value);
+ } else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(2)) {
+ /* power on in UTP mode */
+ ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &value);
+ value &= ~YT_BCR_PWDN;
+ ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value);
+ /* power down in fiber mode */
+ hw->phy.read_reg(hw, YT_BCR, 0, &value);
+ value &= ~YT_BCR_PWDN;
+ hw->phy.write_reg(hw, YT_BCR, 0, value);
+
+ hw->phy.read_reg(hw, YT_SPST, 0, &value);
+ if (value & YT_SPST_LINK) {
+ /* fiber up */
+ hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
+ } else {
+ /* utp up */
+ /*disable 100/10base-T Self-negotiation ability*/
+ hw->phy.read_reg(hw, YT_ANA, 0, &value);
+ value &= ~(YT_ANA_100BASET_FULL | YT_ANA_100BASET_HALF |
+ YT_ANA_10BASET_FULL | YT_ANA_10BASET_HALF);
+ hw->phy.write_reg(hw, YT_ANA, 0, value);
+
+ /*disable 1000base-T Self-negotiation ability*/
+ hw->phy.read_reg(hw, YT_MS_CTRL, 0, &value);
+ value &= ~(YT_MS_1000BASET_FULL | YT_MS_1000BASET_HALF);
+ hw->phy.write_reg(hw, YT_MS_CTRL, 0, value);
+
+ if (speed & NGBE_LINK_SPEED_1GB_FULL) {
+ hw->phy.autoneg_advertised |=
+ NGBE_LINK_SPEED_1GB_FULL;
+ value_r9 |= YT_MS_1000BASET_FULL;
+ }
+ if (speed & NGBE_LINK_SPEED_100M_FULL) {
+ hw->phy.autoneg_advertised |=
+ NGBE_LINK_SPEED_100M_FULL;
+ value_r4 |= YT_ANA_100BASET_FULL;
+ }
+ if (speed & NGBE_LINK_SPEED_10M_FULL) {
+ hw->phy.autoneg_advertised |=
+ NGBE_LINK_SPEED_10M_FULL;
+ value_r4 |= YT_ANA_10BASET_FULL;
+ }
+
+ /* enable 1000base-T Self-negotiation ability */
+ hw->phy.read_reg(hw, YT_MS_CTRL, 0, &value);
+ value |= value_r9;
+ hw->phy.write_reg(hw, YT_MS_CTRL, 0, value);
+
+ /* enable 100/10base-T Self-negotiation ability */
+ hw->phy.read_reg(hw, YT_ANA, 0, &value);
+ value |= value_r4;
+ hw->phy.write_reg(hw, YT_ANA, 0, value);
+
+ /* software reset to make the above configuration
+ * take effect
+ */
+ hw->phy.read_reg(hw, YT_BCR, 0, &value);
+ value |= YT_BCR_RESET;
+ hw->phy.write_reg(hw, YT_BCR, 0, value);
+ }
+ } else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(4)) {
+ hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
+
+ ngbe_read_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, &value);
+ value |= YT_RGMII_CONF1_MODE;
+ ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, value);
+
+ ngbe_read_phy_reg_ext_yt(hw, YT_RGMII_CONF2, 0, &value);
+ value &= ~(YT_RGMII_CONF2_SPEED_MASK | YT_RGMII_CONF2_DUPLEX |
+ YT_RGMII_CONF2_LINKUP);
+ value |= YT_RGMII_CONF2_SPEED(2) | YT_RGMII_CONF2_DUPLEX |
+ YT_RGMII_CONF2_LINKUP;
+ ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF2, 0, value);
+
+ ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value);
+ value &= ~YT_SMI_PHY_SW_RST;
+ ngbe_write_phy_reg_ext_yt(hw, YT_CHIP, 0, value);
+
/* power on phy */
hw->phy.read_reg(hw, YT_BCR, 0, &value);
value &= ~YT_BCR_PWDN;
@@ -214,16 +330,34 @@ s32 ngbe_reset_phy_yt(struct ngbe_hw *hw)
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++) {
+ /* check chip_mode first */
+ ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &ctrl);
+ if (ctrl & YT_CHIP_MODE_MASK) {
+ /* fiber to rgmii */
status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl);
- if (!(ctrl & YT_BCR_RESET))
- break;
- msleep(1);
+ /* 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);
+ }
+ } else {
+ /* UTP to rgmii */
+ status = ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &ctrl);
+ /* sds software reset */
+ ctrl |= YT_BCR_RESET;
+ status = ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, ctrl);
+
+ for (i = 0; i < YT_PHY_RST_WAIT_PERIOD; i++) {
+ status = ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &ctrl);
+ if (!(ctrl & YT_BCR_RESET))
+ break;
+ msleep(1);
+ }
}
if (i == YT_PHY_RST_WAIT_PERIOD) {
diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.h b/drivers/net/ngbe/base/ngbe_phy_yt.h
index e729e0c854..c8763a90df 100644
--- a/drivers/net/ngbe/base/ngbe_phy_yt.h
+++ b/drivers/net/ngbe/base/ngbe_phy_yt.h
@@ -11,26 +11,41 @@
/* Common EXT */
#define YT_SMI_PHY 0xA000
+#define YT_SMI_PHY_SW_RST MS16(15, 0x1)
#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_MASK MS16(0, 0x7)
#define YT_CHIP_MODE_SEL(v) LS16(v, 0, 0x7)
#define YT_RGMII_CONF1 0xA003
+#define YT_RGMII_CONF1_MODE MS16(15, 0x1)
#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_RGMII_CONF2 0xA004
+#define YT_RGMII_CONF2_SPEED_MASK MS16(6, 0x3)
+#define YT_RGMII_CONF2_SPEED(v) LS16(v, 6, 0x3)
+#define YT_RGMII_CONF2_DUPLEX MS16(5, 0x1)
+#define YT_RGMII_CONF2_LINKUP MS16(4, 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_SPEED_SELECT0 MS16(13, 0x1)
+#define YT_BCR_ANE MS16(12, 0x1)
#define YT_BCR_PWDN MS16(11, 0x1)
+#define YT_BCR_RESTART_AN MS16(9, 0x1)
+#define YT_BCR_DUPLEX MS16(8, 0x1)
+#define YT_BCR_SPEED_SELECT1 MS16(6, 0x1)
#define YT_ANA 0x4
/* copper */
#define YT_ANA_100BASET_FULL MS16(8, 0x1)
+#define YT_ANA_100BASET_HALF MS16(7, 0x1)
#define YT_ANA_10BASET_FULL MS16(6, 0x1)
+#define YT_ANA_10BASET_HALF MS16(5, 0x1)
/* fiber */
#define YT_FANA_PAUSE_MASK MS16(7, 0x3)
@@ -41,6 +56,7 @@
#define YT_MS_CTRL 0x9
#define YT_MS_1000BASET_FULL MS16(9, 0x1)
+#define YT_MS_1000BASET_HALF MS16(8, 0x1)
#define YT_SPST 0x11
#define YT_SPST_SPEED_MASK MS16(14, 0x3)
#define YT_SPST_SPEED_1000M LS16(2, 14, 0x3)
@@ -50,7 +66,8 @@
/* UTP only */
#define YT_INTR 0x12
-#define YT_INTR_ENA_MASK MS16(2, 0x3)
+#define YT_INTR_ENA_MASK MS16(10, 0x3)
+#define YT_SDS_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,
diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h
index 4c995e7397..cb8d65ff27 100644
--- a/drivers/net/ngbe/base/ngbe_type.h
+++ b/drivers/net/ngbe/base/ngbe_type.h
@@ -44,6 +44,12 @@ enum ngbe_eeprom_type {
ngbe_eeprom_none /* No NVM support */
};
+enum ngbe_link_type {
+ ngbe_link_type_unknown = 0,
+ ngbe_link_fiber,
+ ngbe_link_copper
+};
+
enum ngbe_mac_type {
ngbe_mac_unknown = 0,
ngbe_mac_em,
@@ -312,6 +318,7 @@ struct ngbe_mac_info {
s32 (*check_overtemp)(struct ngbe_hw *hw);
enum ngbe_mac_type type;
+ enum ngbe_link_type link_type;
u8 addr[ETH_ADDR_LEN];
u8 perm_addr[ETH_ADDR_LEN];
#define NGBE_MAX_MTA 128
@@ -422,6 +429,7 @@ struct ngbe_hw {
u32 q_tx_regs[8 * 4];
bool offset_loaded;
bool is_pf;
+ bool gpio_ctl;
struct {
u64 rx_qp_packets;
u64 tx_qp_packets;
diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c
index cc530fdced..9f42c26f9b 100644
--- a/drivers/net/ngbe/ngbe_ethdev.c
+++ b/drivers/net/ngbe/ngbe_ethdev.c
@@ -1097,8 +1097,7 @@ ngbe_dev_start(struct rte_eth_dev *dev)
/* resume enabled intr since HW reset */
ngbe_enable_intr(dev);
- if ((hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_M88E1512_SFP ||
- (hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_YT8521S_SFP) {
+ if (hw->gpio_ctl) {
/* gpio0 is used to power on/off control*/
wr32(hw, NGBE_GPIODATA, 0);
}
@@ -1141,8 +1140,7 @@ ngbe_dev_stop(struct rte_eth_dev *dev)
rte_eal_alarm_cancel(ngbe_dev_setup_link_alarm_handler, dev);
- if ((hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_M88E1512_SFP ||
- (hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_YT8521S_SFP) {
+ if (hw->gpio_ctl) {
/* gpio0 is used to power on/off control*/
wr32(hw, NGBE_GPIODATA, NGBE_GPIOBIT_0);
}
--
2.21.0.windows.1
next prev parent reply other threads:[~2022-02-09 10:36 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-09 10:42 [PATCH v2 00/12] Wangxun fixes and supports Jiawen Wu
2022-02-09 10:42 ` [PATCH v2 01/12] net/ngbe: fix failed to receive packets Jiawen Wu
2022-02-09 10:42 ` [PATCH v2 02/12] net/ngbe: fix link interrupt sometimes lost Jiawen Wu
2022-02-09 10:42 ` [PATCH v2 03/12] net/ngbe: fix Tx pending Jiawen Wu
2022-02-09 19:07 ` Ferruh Yigit
2022-02-09 10:42 ` [PATCH v2 04/12] net/ngbe: fix RxTx packet statistics Jiawen Wu
2022-02-09 10:42 ` [PATCH v2 05/12] net/ngbe: optimize the PHY initialization process Jiawen Wu
2022-02-09 10:42 ` Jiawen Wu [this message]
2022-02-09 10:42 ` [PATCH v2 07/12] net/ngbe: add LED OEM support Jiawen Wu
2022-02-09 19:06 ` Ferruh Yigit
2022-02-09 10:42 ` [PATCH v2 08/12] net/ngbe: fix debug log Jiawen Wu
2022-02-09 19:07 ` Ferruh Yigit
2022-02-10 8:03 ` Jiawen Wu
2022-02-10 9:02 ` Ferruh Yigit
2022-02-10 9:49 ` Jiawen Wu
2022-02-10 10:16 ` Ferruh Yigit
2022-02-11 2:02 ` Jiawen Wu
2022-02-09 10:42 ` [PATCH v2 09/12] net/txgbe: add LED OEM support Jiawen Wu
2022-02-09 10:42 ` [PATCH v2 10/12] net/txgbe: fix debug log Jiawen Wu
2022-02-09 19:07 ` Ferruh Yigit
2022-02-09 10:42 ` [PATCH v2 11/12] net/txgbe: fix to set link up and down Jiawen Wu
2022-02-09 10:42 ` [PATCH v2 12/12] net/txgbe: fix KR auto-negotiation Jiawen Wu
2022-02-09 19:06 ` [PATCH v2 00/12] Wangxun fixes and supports Ferruh Yigit
2022-02-11 13:10 ` Ferruh Yigit
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=20220209104213.602728-7-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).