Commit d55595f0 authored by Jiawen Wu's avatar Jiawen Wu Committed by David S. Miller

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: default avatarJiawen Wu <jiawenwu@trustnetic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1355fe13
......@@ -238,6 +238,29 @@ static int xpcs_write_vpcs(struct dw_xpcs *xpcs, int reg, u16 val)
return xpcs_write_vendor(xpcs, MDIO_MMD_PCS, reg, val);
}
static int xpcs_dev_flag(struct dw_xpcs *xpcs)
{
int ret, oui;
ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID1);
if (ret < 0)
return ret;
oui = ret;
ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID2);
if (ret < 0)
return ret;
ret = (ret >> 10) & 0x3F;
oui |= ret << 16;
if (oui == DW_OUI_WX)
xpcs->dev_flag = DW_DEV_TXGBE;
return 0;
}
static int xpcs_poll_reset(struct dw_xpcs *xpcs, int dev)
{
/* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
......@@ -1284,6 +1307,10 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
goto out;
}
ret = xpcs_dev_flag(xpcs);
if (ret)
goto out;
xpcs->pcs.ops = &xpcs_phylink_ops;
xpcs->pcs.neg_mode = true;
if (compat->an_mode == DW_10GBASER)
......@@ -1291,9 +1318,11 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
xpcs->pcs.poll = true;
ret = xpcs_soft_reset(xpcs, compat);
if (ret)
goto out;
if (xpcs->dev_flag != DW_DEV_TXGBE) {
ret = xpcs_soft_reset(xpcs, compat);
if (ret)
goto out;
}
return xpcs;
}
......
......@@ -20,12 +20,19 @@
#define DW_AN_C37_1000BASEX 4
#define DW_10GBASER 5
/* device vendor OUI */
#define DW_OUI_WX 0x0018fc80
/* dev_flag */
#define DW_DEV_TXGBE BIT(0)
struct xpcs_id;
struct dw_xpcs {
struct mdio_device *mdiodev;
const struct xpcs_id *id;
struct phylink_pcs pcs;
int dev_flag;
};
int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment