mirror of
https://github.com/lkl/linux.git
synced 2025-12-19 16:13:19 +09:00
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>
This commit is contained in:
committed by
David S. Miller
parent
1355fe134a
commit
d55595f04d
@@ -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);
|
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)
|
static int xpcs_poll_reset(struct dw_xpcs *xpcs, int dev)
|
||||||
{
|
{
|
||||||
/* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
|
/* 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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = xpcs_dev_flag(xpcs);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
xpcs->pcs.ops = &xpcs_phylink_ops;
|
xpcs->pcs.ops = &xpcs_phylink_ops;
|
||||||
xpcs->pcs.neg_mode = true;
|
xpcs->pcs.neg_mode = true;
|
||||||
if (compat->an_mode == DW_10GBASER)
|
if (compat->an_mode == DW_10GBASER)
|
||||||
@@ -1291,9 +1318,11 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
|
|||||||
|
|
||||||
xpcs->pcs.poll = true;
|
xpcs->pcs.poll = true;
|
||||||
|
|
||||||
ret = xpcs_soft_reset(xpcs, compat);
|
if (xpcs->dev_flag != DW_DEV_TXGBE) {
|
||||||
if (ret)
|
ret = xpcs_soft_reset(xpcs, compat);
|
||||||
goto out;
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
return xpcs;
|
return xpcs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,19 @@
|
|||||||
#define DW_AN_C37_1000BASEX 4
|
#define DW_AN_C37_1000BASEX 4
|
||||||
#define DW_10GBASER 5
|
#define DW_10GBASER 5
|
||||||
|
|
||||||
|
/* device vendor OUI */
|
||||||
|
#define DW_OUI_WX 0x0018fc80
|
||||||
|
|
||||||
|
/* dev_flag */
|
||||||
|
#define DW_DEV_TXGBE BIT(0)
|
||||||
|
|
||||||
struct xpcs_id;
|
struct xpcs_id;
|
||||||
|
|
||||||
struct dw_xpcs {
|
struct dw_xpcs {
|
||||||
struct mdio_device *mdiodev;
|
struct mdio_device *mdiodev;
|
||||||
const struct xpcs_id *id;
|
const struct xpcs_id *id;
|
||||||
struct phylink_pcs pcs;
|
struct phylink_pcs pcs;
|
||||||
|
int dev_flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface);
|
int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface);
|
||||||
|
|||||||
Reference in New Issue
Block a user