Skip to content

Commit 2a22b7a

Browse files
Jiawen Wudavem330
authored andcommitted
net: pcs: xpcs: adapt Wangxun NICs for SGMII mode
Wangxun NICs support the connection with SFP to RJ45 module. In this case, PCS need to be configured in SGMII mode. According to chapter 6.11.1 "SGMII Auto-Negitiation" of DesignWare Cores Ethernet PCS (version 3.20a) and custom design manual, do the following configuration when the interface mode is SGMII. 1. program VR_MII_AN_CTRL bit(3) [TX_CONFIG] = 1b (PHY side SGMII) 2. program VR_MII_AN_CTRL bit(8) [MII_CTRL] = 1b (8-bit MII) 3. program VR_MII_DIG_CTRL1 bit(0) [PHY_MODE_CTRL] = 1b Also CL37 AN in backplane configurations need to be enabled because of the special hardware design. Another thing to note is that PMA needs to be reconfigured before each CL37 AN configuration for SGMII, otherwise AN will fail, although we don't know why. On this device, CL37_ANSGM_STS (bit[4:1] of VR_MII_AN_INTR_STS) indicates the status received from remote link during the auto-negotiation, and self-clear after the auto-negotiation is complete. Meanwhile, CL37_ANCMPLT_INTR will be set to 1, to indicate CL37 AN is complete. So add another way to get the state for CL37 SGMII. Signed-off-by: Jiawen Wu <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2deea43 commit 2a22b7a

File tree

3 files changed

+52
-6
lines changed

3 files changed

+52
-6
lines changed

drivers/net/pcs/pcs-xpcs-wx.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,9 @@ static bool txgbe_xpcs_mode_quirk(struct dw_xpcs *xpcs)
162162
/* When txgbe do LAN reset, PCS will change to default 10GBASE-R mode */
163163
ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_CTRL2);
164164
ret &= MDIO_PCS_CTRL2_TYPE;
165-
if (ret == MDIO_PCS_CTRL2_10GBR &&
166-
xpcs->interface != PHY_INTERFACE_MODE_10GBASER)
165+
if ((ret == MDIO_PCS_CTRL2_10GBR &&
166+
xpcs->interface != PHY_INTERFACE_MODE_10GBASER) ||
167+
xpcs->interface == PHY_INTERFACE_MODE_SGMII)
167168
return true;
168169

169170
return false;

drivers/net/pcs/pcs-xpcs.c

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,10 @@ EXPORT_SYMBOL_GPL(xpcs_config_eee);
683683
static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
684684
unsigned int neg_mode)
685685
{
686-
int ret, mdio_ctrl;
686+
int ret, mdio_ctrl, tx_conf;
687+
688+
if (xpcs->dev_flag == DW_DEV_TXGBE)
689+
xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_CL37_BP | DW_EN_VSMMD1);
687690

688691
/* For AN for C37 SGMII mode, the settings are :-
689692
* 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable SGMII AN in case
@@ -720,9 +723,15 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
720723
ret |= (DW_VR_MII_PCS_MODE_C37_SGMII <<
721724
DW_VR_MII_AN_CTRL_PCS_MODE_SHIFT &
722725
DW_VR_MII_PCS_MODE_MASK);
723-
ret |= (DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII <<
724-
DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT &
725-
DW_VR_MII_TX_CONFIG_MASK);
726+
if (xpcs->dev_flag == DW_DEV_TXGBE) {
727+
ret |= DW_VR_MII_AN_CTRL_8BIT;
728+
/* Hardware requires it to be PHY side SGMII */
729+
tx_conf = DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII;
730+
} else {
731+
tx_conf = DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII;
732+
}
733+
ret |= tx_conf << DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT &
734+
DW_VR_MII_TX_CONFIG_MASK;
726735
ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret);
727736
if (ret < 0)
728737
return ret;
@@ -736,6 +745,9 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
736745
else
737746
ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
738747

748+
if (xpcs->dev_flag == DW_DEV_TXGBE)
749+
ret |= DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL;
750+
739751
ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
740752
if (ret < 0)
741753
return ret;
@@ -1011,6 +1023,33 @@ static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs,
10111023
state->duplex = DUPLEX_FULL;
10121024
else
10131025
state->duplex = DUPLEX_HALF;
1026+
} else if (ret == DW_VR_MII_AN_STS_C37_ANCMPLT_INTR) {
1027+
int speed, duplex;
1028+
1029+
state->link = true;
1030+
1031+
speed = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1);
1032+
if (speed < 0)
1033+
return speed;
1034+
1035+
speed &= SGMII_SPEED_SS13 | SGMII_SPEED_SS6;
1036+
if (speed == SGMII_SPEED_SS6)
1037+
state->speed = SPEED_1000;
1038+
else if (speed == SGMII_SPEED_SS13)
1039+
state->speed = SPEED_100;
1040+
else if (speed == 0)
1041+
state->speed = SPEED_10;
1042+
1043+
duplex = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE);
1044+
if (duplex < 0)
1045+
return duplex;
1046+
1047+
if (duplex & DW_FULL_DUPLEX)
1048+
state->duplex = DUPLEX_FULL;
1049+
else if (duplex & DW_HALF_DUPLEX)
1050+
state->duplex = DUPLEX_HALF;
1051+
1052+
xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);
10141053
}
10151054

10161055
return 0;

drivers/net/pcs/pcs-xpcs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,14 @@
6767

6868
/* VR_MII_DIG_CTRL1 */
6969
#define DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW BIT(9)
70+
#define DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL BIT(0)
7071

7172
/* VR_MII_DIG_CTRL2 */
7273
#define DW_VR_MII_DIG_CTRL2_TX_POL_INV BIT(4)
7374
#define DW_VR_MII_DIG_CTRL2_RX_POL_INV BIT(0)
7475

7576
/* VR_MII_AN_CTRL */
77+
#define DW_VR_MII_AN_CTRL_8BIT BIT(8)
7678
#define DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT 3
7779
#define DW_VR_MII_TX_CONFIG_MASK BIT(3)
7880
#define DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII 0x1
@@ -98,6 +100,10 @@
98100
#define SGMII_SPEED_SS13 BIT(13) /* SGMII speed along with SS6 */
99101
#define SGMII_SPEED_SS6 BIT(6) /* SGMII speed along with SS13 */
100102

103+
/* SR MII MMD AN Advertisement defines */
104+
#define DW_HALF_DUPLEX BIT(6)
105+
#define DW_FULL_DUPLEX BIT(5)
106+
101107
/* VR MII EEE Control 0 defines */
102108
#define DW_VR_MII_EEE_LTX_EN BIT(0) /* LPI Tx Enable */
103109
#define DW_VR_MII_EEE_LRX_EN BIT(1) /* LPI Rx Enable */

0 commit comments

Comments
 (0)