Skip to content

Commit bcac735

Browse files
fancerdavem330
authored andcommitted
net: pcs: xpcs: Introduce DW XPCS info structure
The being introduced structure will preserve the PCS and PMA IDs retrieved from the respective DW XPCS MMDs or potentially pre-defined by the client drivers. (The later change will be introduced later in the framework of the commit adding the memory-mapped DW XPCS devices support.) The structure fields are filled in in the xpcs_get_id() function, which used to be responsible for the PCS Device ID getting only. Besides of the PCS ID the method now fetches the PMA/PMD IDs too from MMD 1, which used to be done in xpcs_dev_flag(). The retrieved PMA ID will be from now utilized for the PMA-specific tweaks like it was introduced for the Wangxun TxGBE PCS in the commit f629acc ("net: pcs: xpcs: support to switch mode for Wangxun NICs"). Note 1. The xpcs_get_id() error-handling semantics has been changed. From now the error number will be returned from the function. There is no point in the next IOs or saving 0xffs and then looping over the actual device IDs if device couldn't be reached. -ENODEV will be returned if the very first IO operation failed thus indicating that no device could be found. Note 2. The PCS and PMA IDs macros have been converted to enum'es. The enum'es will be populated later in another commit with the virtual IDs identifying the DW XPCS devices which have some platform-specifics, but have been synthesized with the default PCS/PMA ID. Signed-off-by: Serge Semin <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 410232a commit bcac735

File tree

2 files changed

+67
-65
lines changed

2 files changed

+67
-65
lines changed

drivers/net/pcs/pcs-xpcs.c

Lines changed: 50 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -237,29 +237,6 @@ int xpcs_write_vpcs(struct dw_xpcs *xpcs, int reg, u16 val)
237237
return xpcs_write_vendor(xpcs, MDIO_MMD_PCS, reg, val);
238238
}
239239

240-
static int xpcs_dev_flag(struct dw_xpcs *xpcs)
241-
{
242-
int ret, oui;
243-
244-
ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID1);
245-
if (ret < 0)
246-
return ret;
247-
248-
oui = ret;
249-
250-
ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID2);
251-
if (ret < 0)
252-
return ret;
253-
254-
ret = (ret >> 10) & 0x3F;
255-
oui |= ret << 16;
256-
257-
if (oui == DW_OUI_WX)
258-
xpcs->dev_flag = DW_DEV_TXGBE;
259-
260-
return 0;
261-
}
262-
263240
static int xpcs_poll_reset(struct dw_xpcs *xpcs, int dev)
264241
{
265242
/* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
@@ -684,7 +661,7 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
684661
{
685662
int ret, mdio_ctrl, tx_conf;
686663

687-
if (xpcs->dev_flag == DW_DEV_TXGBE)
664+
if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
688665
xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_CL37_BP | DW_EN_VSMMD1);
689666

690667
/* For AN for C37 SGMII mode, the settings are :-
@@ -722,7 +699,7 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
722699
ret |= (DW_VR_MII_PCS_MODE_C37_SGMII <<
723700
DW_VR_MII_AN_CTRL_PCS_MODE_SHIFT &
724701
DW_VR_MII_PCS_MODE_MASK);
725-
if (xpcs->dev_flag == DW_DEV_TXGBE) {
702+
if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) {
726703
ret |= DW_VR_MII_AN_CTRL_8BIT;
727704
/* Hardware requires it to be PHY side SGMII */
728705
tx_conf = DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII;
@@ -744,7 +721,7 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
744721
else
745722
ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
746723

747-
if (xpcs->dev_flag == DW_DEV_TXGBE)
724+
if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
748725
ret |= DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL;
749726

750727
ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
@@ -766,7 +743,7 @@ static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs,
766743
int ret, mdio_ctrl, adv;
767744
bool changed = 0;
768745

769-
if (xpcs->dev_flag == DW_DEV_TXGBE)
746+
if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
770747
xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_CL37_BP | DW_EN_VSMMD1);
771748

772749
/* According to Chap 7.12, to set 1000BASE-X C37 AN, AN must
@@ -857,7 +834,7 @@ int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
857834
if (!compat)
858835
return -ENODEV;
859836

860-
if (xpcs->dev_flag == DW_DEV_TXGBE) {
837+
if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) {
861838
ret = txgbe_xpcs_switch_mode(xpcs, interface);
862839
if (ret)
863840
return ret;
@@ -1229,44 +1206,66 @@ static void xpcs_an_restart(struct phylink_pcs *pcs)
12291206
}
12301207
}
12311208

1232-
static u32 xpcs_get_id(struct dw_xpcs *xpcs)
1209+
static int xpcs_get_id(struct dw_xpcs *xpcs)
12331210
{
12341211
int ret;
12351212
u32 id;
12361213

1237-
/* First, search C73 PCS using PCS MMD */
1214+
/* First, search C73 PCS using PCS MMD 3. Return ENODEV if communication
1215+
* failed indicating that device couldn't be reached.
1216+
*/
12381217
ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID1);
12391218
if (ret < 0)
1240-
return 0xffffffff;
1219+
return -ENODEV;
12411220

12421221
id = ret << 16;
12431222

12441223
ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID2);
12451224
if (ret < 0)
1246-
return 0xffffffff;
1225+
return ret;
12471226

1248-
/* If Device IDs are not all zeros or all ones,
1249-
* we found C73 AN-type device
1227+
id |= ret;
1228+
1229+
/* If Device IDs are not all zeros or ones, then 10GBase-X/R or C73
1230+
* KR/KX4 PCS found. Otherwise fallback to detecting 1000Base-X or C37
1231+
* PCS in MII MMD 31.
12501232
*/
1251-
if ((id | ret) && (id | ret) != 0xffffffff)
1252-
return id | ret;
1233+
if (!id || id == 0xffffffff) {
1234+
ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID1);
1235+
if (ret < 0)
1236+
return ret;
1237+
1238+
id = ret << 16;
1239+
1240+
ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID2);
1241+
if (ret < 0)
1242+
return ret;
12531243

1254-
/* Next, search C37 PCS using Vendor-Specific MII MMD */
1255-
ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID1);
1244+
id |= ret;
1245+
}
1246+
1247+
xpcs->info.pcs = id;
1248+
1249+
/* Find out PMA/PMD ID from MMD 1 device ID registers */
1250+
ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID1);
12561251
if (ret < 0)
1257-
return 0xffffffff;
1252+
return ret;
12581253

1259-
id = ret << 16;
1254+
id = ret;
12601255

1261-
ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID2);
1256+
ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID2);
12621257
if (ret < 0)
1263-
return 0xffffffff;
1258+
return ret;
1259+
1260+
/* Note the inverted dword order and masked out Model/Revision numbers
1261+
* with respect to what is done with the PCS ID...
1262+
*/
1263+
ret = (ret >> 10) & 0x3F;
1264+
id |= ret << 16;
12641265

1265-
/* If Device IDs are not all zeros, we found C37 AN-type device */
1266-
if (id | ret)
1267-
return id | ret;
1266+
xpcs->info.pma = id;
12681267

1269-
return 0xffffffff;
1268+
return 0;
12701269
}
12711270

12721271
static const struct dw_xpcs_compat synopsys_xpcs_compat[DW_XPCS_INTERFACE_MAX] = {
@@ -1390,15 +1389,16 @@ static void xpcs_free_data(struct dw_xpcs *xpcs)
13901389

13911390
static int xpcs_init_id(struct dw_xpcs *xpcs)
13921391
{
1393-
u32 xpcs_id;
13941392
int i, ret;
13951393

1396-
xpcs_id = xpcs_get_id(xpcs);
1394+
ret = xpcs_get_id(xpcs);
1395+
if (ret < 0)
1396+
return ret;
13971397

13981398
for (i = 0; i < ARRAY_SIZE(xpcs_desc_list); i++) {
13991399
const struct dw_xpcs_desc *desc = &xpcs_desc_list[i];
14001400

1401-
if ((xpcs_id & desc->mask) != desc->id)
1401+
if ((xpcs->info.pcs & desc->mask) != desc->id)
14021402
continue;
14031403

14041404
xpcs->desc = desc;
@@ -1409,10 +1409,6 @@ static int xpcs_init_id(struct dw_xpcs *xpcs)
14091409
if (!xpcs->desc)
14101410
return -ENODEV;
14111411

1412-
ret = xpcs_dev_flag(xpcs);
1413-
if (ret < 0)
1414-
return ret;
1415-
14161412
return 0;
14171413
}
14181414

@@ -1424,7 +1420,7 @@ static int xpcs_init_iface(struct dw_xpcs *xpcs, phy_interface_t interface)
14241420
if (!compat)
14251421
return -EINVAL;
14261422

1427-
if (xpcs->dev_flag == DW_DEV_TXGBE) {
1423+
if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) {
14281424
xpcs->pcs.poll = false;
14291425
return 0;
14301426
}

include/linux/pcs/pcs-xpcs.h

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@
99

1010
#include <linux/phy.h>
1111
#include <linux/phylink.h>
12-
13-
#define NXP_SJA1105_XPCS_ID 0x00000010
14-
#define NXP_SJA1110_XPCS_ID 0x00000020
15-
#define DW_XPCS_ID 0x7996ced0
16-
#define DW_XPCS_ID_MASK 0xffffffff
12+
#include <linux/types.h>
1713

1814
/* AN mode */
1915
#define DW_AN_C73 1
@@ -22,20 +18,30 @@
2218
#define DW_AN_C37_1000BASEX 4
2319
#define DW_10GBASER 5
2420

25-
/* device vendor OUI */
26-
#define DW_OUI_WX 0x0018fc80
21+
struct dw_xpcs_desc;
2722

28-
/* dev_flag */
29-
#define DW_DEV_TXGBE BIT(0)
23+
enum dw_xpcs_pcs_id {
24+
NXP_SJA1105_XPCS_ID = 0x00000010,
25+
NXP_SJA1110_XPCS_ID = 0x00000020,
26+
DW_XPCS_ID = 0x7996ced0,
27+
DW_XPCS_ID_MASK = 0xffffffff,
28+
};
3029

31-
struct dw_xpcs_desc;
30+
enum dw_xpcs_pma_id {
31+
WX_TXGBE_XPCS_PMA_10G_ID = 0x0018fc80,
32+
};
33+
34+
struct dw_xpcs_info {
35+
u32 pcs;
36+
u32 pma;
37+
};
3238

3339
struct dw_xpcs {
40+
struct dw_xpcs_info info;
3441
const struct dw_xpcs_desc *desc;
3542
struct mdio_device *mdiodev;
3643
struct phylink_pcs pcs;
3744
phy_interface_t interface;
38-
int dev_flag;
3945
};
4046

4147
int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface);

0 commit comments

Comments
 (0)