Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: pcs: xpcs: add specific vendor supoprt for Wangxun 10Gb NICs

Since Wangxun 10Gb NICs require some special configuration on the IP of
Synopsys Designware XPCS, introduce dev_flag for different vendors. Read
OUI from device identifier registers, to detect Wangxun devices.

And xpcs_soft_reset() is skipped to avoid the reset of device identifier
registers.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jiawen Wu and committed by
David S. Miller
d55595f0 1355fe13

+39 -3
+32 -3
drivers/net/pcs/pcs-xpcs.c
··· 238 238 return xpcs_write_vendor(xpcs, MDIO_MMD_PCS, reg, val); 239 239 } 240 240 241 + static int xpcs_dev_flag(struct dw_xpcs *xpcs) 242 + { 243 + int ret, oui; 244 + 245 + ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID1); 246 + if (ret < 0) 247 + return ret; 248 + 249 + oui = ret; 250 + 251 + ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID2); 252 + if (ret < 0) 253 + return ret; 254 + 255 + ret = (ret >> 10) & 0x3F; 256 + oui |= ret << 16; 257 + 258 + if (oui == DW_OUI_WX) 259 + xpcs->dev_flag = DW_DEV_TXGBE; 260 + 261 + return 0; 262 + } 263 + 241 264 static int xpcs_poll_reset(struct dw_xpcs *xpcs, int dev) 242 265 { 243 266 /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */ ··· 1307 1284 goto out; 1308 1285 } 1309 1286 1287 + ret = xpcs_dev_flag(xpcs); 1288 + if (ret) 1289 + goto out; 1290 + 1310 1291 xpcs->pcs.ops = &xpcs_phylink_ops; 1311 1292 xpcs->pcs.neg_mode = true; 1312 1293 if (compat->an_mode == DW_10GBASER) ··· 1318 1291 1319 1292 xpcs->pcs.poll = true; 1320 1293 1321 - ret = xpcs_soft_reset(xpcs, compat); 1322 - if (ret) 1323 - goto out; 1294 + if (xpcs->dev_flag != DW_DEV_TXGBE) { 1295 + ret = xpcs_soft_reset(xpcs, compat); 1296 + if (ret) 1297 + goto out; 1298 + } 1324 1299 1325 1300 return xpcs; 1326 1301 }
+7
include/linux/pcs/pcs-xpcs.h
··· 20 20 #define DW_AN_C37_1000BASEX 4 21 21 #define DW_10GBASER 5 22 22 23 + /* device vendor OUI */ 24 + #define DW_OUI_WX 0x0018fc80 25 + 26 + /* dev_flag */ 27 + #define DW_DEV_TXGBE BIT(0) 28 + 23 29 struct xpcs_id; 24 30 25 31 struct dw_xpcs { 26 32 struct mdio_device *mdiodev; 27 33 const struct xpcs_id *id; 28 34 struct phylink_pcs pcs; 35 + int dev_flag; 29 36 }; 30 37 31 38 int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface);