• Home
  • Raw
  • Download

Lines Matching full:xpcs

4  * Synopsys DesignWare XPCS helpers
10 #include <linux/pcs/pcs-xpcs.h>
14 #include "pcs-xpcs.h"
152 int (*pma_config)(struct dw_xpcs *xpcs);
177 int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface) in xpcs_get_an_mode() argument
181 compat = xpcs_find_compat(xpcs->id, interface); in xpcs_get_an_mode()
204 int xpcs_read(struct dw_xpcs *xpcs, int dev, u32 reg) in xpcs_read() argument
206 return mdiodev_c45_read(xpcs->mdiodev, dev, reg); in xpcs_read()
209 int xpcs_write(struct dw_xpcs *xpcs, int dev, u32 reg, u16 val) in xpcs_write() argument
211 return mdiodev_c45_write(xpcs->mdiodev, dev, reg, val); in xpcs_write()
214 static int xpcs_modify_changed(struct dw_xpcs *xpcs, int dev, u32 reg, in xpcs_modify_changed() argument
217 return mdiodev_c45_modify_changed(xpcs->mdiodev, dev, reg, mask, set); in xpcs_modify_changed()
220 static int xpcs_read_vendor(struct dw_xpcs *xpcs, int dev, u32 reg) in xpcs_read_vendor() argument
222 return xpcs_read(xpcs, dev, DW_VENDOR | reg); in xpcs_read_vendor()
225 static int xpcs_write_vendor(struct dw_xpcs *xpcs, int dev, int reg, in xpcs_write_vendor() argument
228 return xpcs_write(xpcs, dev, DW_VENDOR | reg, val); in xpcs_write_vendor()
231 int xpcs_read_vpcs(struct dw_xpcs *xpcs, int reg) in xpcs_read_vpcs() argument
233 return xpcs_read_vendor(xpcs, MDIO_MMD_PCS, reg); in xpcs_read_vpcs()
236 int xpcs_write_vpcs(struct dw_xpcs *xpcs, int reg, u16 val) in xpcs_write_vpcs() argument
238 return xpcs_write_vendor(xpcs, MDIO_MMD_PCS, reg, val); in xpcs_write_vpcs()
241 static int xpcs_dev_flag(struct dw_xpcs *xpcs) in xpcs_dev_flag() argument
245 ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID1); in xpcs_dev_flag()
251 ret = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_DEVID2); in xpcs_dev_flag()
259 xpcs->dev_flag = DW_DEV_TXGBE; in xpcs_dev_flag()
264 static int xpcs_poll_reset(struct dw_xpcs *xpcs, int dev) in xpcs_poll_reset() argument
272 ret = xpcs_read(xpcs, dev, MDIO_CTRL1); in xpcs_poll_reset()
280 static int xpcs_soft_reset(struct dw_xpcs *xpcs, in xpcs_soft_reset() argument
299 ret = xpcs_write(xpcs, dev, MDIO_CTRL1, MDIO_CTRL1_RESET); in xpcs_soft_reset()
303 return xpcs_poll_reset(xpcs, dev); in xpcs_soft_reset()
312 static int xpcs_read_fault_c73(struct dw_xpcs *xpcs, in xpcs_read_fault_c73() argument
319 xpcs_warn(xpcs, state, "Link fault condition detected!\n"); in xpcs_read_fault_c73()
323 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT2); in xpcs_read_fault_c73()
328 xpcs_warn(xpcs, state, "Receiver fault detected!\n"); in xpcs_read_fault_c73()
330 xpcs_warn(xpcs, state, "Transmitter fault detected!\n"); in xpcs_read_fault_c73()
332 ret = xpcs_read_vendor(xpcs, MDIO_MMD_PCS, DW_VR_XS_PCS_DIG_STS); in xpcs_read_fault_c73()
337 xpcs_warn(xpcs, state, "FIFO fault condition detected!\n"); in xpcs_read_fault_c73()
341 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1); in xpcs_read_fault_c73()
346 xpcs_warn(xpcs, state, "Link is not locked!\n"); in xpcs_read_fault_c73()
348 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT2); in xpcs_read_fault_c73()
353 xpcs_warn(xpcs, state, "Link has errors!\n"); in xpcs_read_fault_c73()
360 static void xpcs_config_usxgmii(struct dw_xpcs *xpcs, int speed) in xpcs_config_usxgmii() argument
388 ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1); in xpcs_config_usxgmii()
392 ret = xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_EN); in xpcs_config_usxgmii()
396 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1); in xpcs_config_usxgmii()
403 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret); in xpcs_config_usxgmii()
407 ret = xpcs_read_vpcs(xpcs, MDIO_CTRL1); in xpcs_config_usxgmii()
411 ret = xpcs_write_vpcs(xpcs, MDIO_CTRL1, ret | DW_USXGMII_RST); in xpcs_config_usxgmii()
418 pr_err("%s: XPCS access returned %pe\n", __func__, ERR_PTR(ret)); in xpcs_config_usxgmii()
421 static int _xpcs_config_aneg_c73(struct dw_xpcs *xpcs, in _xpcs_config_aneg_c73() argument
426 /* By default, in USXGMII mode XPCS operates at 10G baud and in _xpcs_config_aneg_c73()
439 ret = xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV3, adv); in _xpcs_config_aneg_c73()
452 ret = xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV2, adv); in _xpcs_config_aneg_c73()
463 return xpcs_write(xpcs, MDIO_MMD_AN, DW_SR_AN_ADV1, adv); in _xpcs_config_aneg_c73()
466 static int xpcs_config_aneg_c73(struct dw_xpcs *xpcs, in xpcs_config_aneg_c73() argument
471 ret = _xpcs_config_aneg_c73(xpcs, compat); in xpcs_config_aneg_c73()
475 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_CTRL1); in xpcs_config_aneg_c73()
481 return xpcs_write(xpcs, MDIO_MMD_AN, MDIO_CTRL1, ret); in xpcs_config_aneg_c73()
484 static int xpcs_aneg_done_c73(struct dw_xpcs *xpcs, in xpcs_aneg_done_c73() argument
491 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_AN_LPA); in xpcs_aneg_done_c73()
497 xpcs_config_aneg_c73(xpcs, compat); in xpcs_aneg_done_c73()
507 static int xpcs_read_lpa_c73(struct dw_xpcs *xpcs, in xpcs_read_lpa_c73() argument
522 ret = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_AN_LPA + i); in xpcs_read_lpa_c73()
534 static int xpcs_get_max_xlgmii_speed(struct dw_xpcs *xpcs, in xpcs_get_max_xlgmii_speed() argument
588 static void xpcs_resolve_pma(struct dw_xpcs *xpcs, in xpcs_resolve_pma() argument
599 state->speed = xpcs_get_max_xlgmii_speed(xpcs, state); in xpcs_resolve_pma()
612 struct dw_xpcs *xpcs; in xpcs_validate() local
615 xpcs = phylink_pcs_to_xpcs(pcs); in xpcs_validate()
616 compat = xpcs_find_compat(xpcs->id, state->interface); in xpcs_validate()
631 void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces) in xpcs_get_interfaces() argument
636 const struct xpcs_compat *compat = &xpcs->id->compat[i]; in xpcs_get_interfaces()
645 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) in xpcs_config_eee() argument
649 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0); in xpcs_config_eee()
666 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0, ret); in xpcs_config_eee()
670 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1); in xpcs_config_eee()
679 return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, ret); in xpcs_config_eee()
683 static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, in xpcs_config_aneg_c37_sgmii() argument
688 if (xpcs->dev_flag == DW_DEV_TXGBE) in xpcs_config_aneg_c37_sgmii()
689 xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_CL37_BP | DW_EN_VSMMD1); in xpcs_config_aneg_c37_sgmii()
696 * DW xPCS used with DW EQoS MAC is always MAC side SGMII. in xpcs_config_aneg_c37_sgmii()
707 mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL); in xpcs_config_aneg_c37_sgmii()
712 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, in xpcs_config_aneg_c37_sgmii()
718 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL); in xpcs_config_aneg_c37_sgmii()
726 if (xpcs->dev_flag == DW_DEV_TXGBE) { in xpcs_config_aneg_c37_sgmii()
735 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret); in xpcs_config_aneg_c37_sgmii()
739 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1); in xpcs_config_aneg_c37_sgmii()
748 if (xpcs->dev_flag == DW_DEV_TXGBE) in xpcs_config_aneg_c37_sgmii()
751 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); in xpcs_config_aneg_c37_sgmii()
756 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, in xpcs_config_aneg_c37_sgmii()
762 static int xpcs_config_aneg_c37_1000basex(struct dw_xpcs *xpcs, in xpcs_config_aneg_c37_1000basex() argument
770 if (xpcs->dev_flag == DW_DEV_TXGBE) in xpcs_config_aneg_c37_1000basex()
771 xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_CL37_BP | DW_EN_VSMMD1); in xpcs_config_aneg_c37_1000basex()
778 mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL); in xpcs_config_aneg_c37_1000basex()
783 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, in xpcs_config_aneg_c37_1000basex()
789 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL); in xpcs_config_aneg_c37_1000basex()
794 if (!xpcs->pcs.poll) in xpcs_config_aneg_c37_1000basex()
796 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL, ret); in xpcs_config_aneg_c37_1000basex()
806 ret = xpcs_modify_changed(xpcs, MDIO_MMD_VEND2, in xpcs_config_aneg_c37_1000basex()
815 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0); in xpcs_config_aneg_c37_1000basex()
820 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, in xpcs_config_aneg_c37_1000basex()
829 static int xpcs_config_2500basex(struct dw_xpcs *xpcs) in xpcs_config_2500basex() argument
833 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1); in xpcs_config_2500basex()
838 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); in xpcs_config_2500basex()
842 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL); in xpcs_config_2500basex()
848 return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ret); in xpcs_config_2500basex()
851 int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface, in xpcs_do_config() argument
857 compat = xpcs_find_compat(xpcs->id, interface); in xpcs_do_config()
861 if (xpcs->dev_flag == DW_DEV_TXGBE) { in xpcs_do_config()
862 ret = txgbe_xpcs_switch_mode(xpcs, interface); in xpcs_do_config()
872 ret = xpcs_config_aneg_c73(xpcs, compat); in xpcs_do_config()
878 ret = xpcs_config_aneg_c37_sgmii(xpcs, neg_mode); in xpcs_do_config()
883 ret = xpcs_config_aneg_c37_1000basex(xpcs, neg_mode, in xpcs_do_config()
889 ret = xpcs_config_2500basex(xpcs); in xpcs_do_config()
898 ret = compat->pma_config(xpcs); in xpcs_do_config()
912 struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); in xpcs_config() local
914 return xpcs_do_config(xpcs, interface, advertising, neg_mode); in xpcs_config()
917 static int xpcs_get_state_c73(struct dw_xpcs *xpcs, in xpcs_get_state_c73() argument
930 pcs_stat1 = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_STAT1); in xpcs_get_state_c73()
940 ret = xpcs_read_fault_c73(xpcs, state, pcs_stat1); in xpcs_get_state_c73()
942 ret = xpcs_soft_reset(xpcs, compat); in xpcs_get_state_c73()
948 return xpcs_do_config(xpcs, state->interface, NULL, in xpcs_get_state_c73()
963 an_stat1 = xpcs_read(xpcs, MDIO_MMD_AN, MDIO_STAT1); in xpcs_get_state_c73()
969 state->an_complete = xpcs_aneg_done_c73(xpcs, state, compat, in xpcs_get_state_c73()
976 ret = xpcs_read_lpa_c73(xpcs, state, an_stat1); in xpcs_get_state_c73()
984 xpcs_resolve_pma(xpcs, state); in xpcs_get_state_c73()
990 static int xpcs_get_state_c37_sgmii(struct dw_xpcs *xpcs, in xpcs_get_state_c37_sgmii() argument
1004 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS); in xpcs_get_state_c37_sgmii()
1031 speed = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1); in xpcs_get_state_c37_sgmii()
1043 duplex = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE); in xpcs_get_state_c37_sgmii()
1052 xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0); in xpcs_get_state_c37_sgmii()
1058 static int xpcs_get_state_c37_1000basex(struct dw_xpcs *xpcs, in xpcs_get_state_c37_1000basex() argument
1068 lpa = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_LPA); in xpcs_get_state_c37_1000basex()
1072 bmsr = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_BMSR); in xpcs_get_state_c37_1000basex()
1077 if (!xpcs->pcs.poll) { in xpcs_get_state_c37_1000basex()
1080 an_intr = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS); in xpcs_get_state_c37_1000basex()
1083 xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, an_intr); in xpcs_get_state_c37_1000basex()
1096 struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); in xpcs_get_state() local
1100 compat = xpcs_find_compat(xpcs->id, state->interface); in xpcs_get_state()
1106 phylink_mii_c45_pcs_get_state(xpcs->mdiodev, state); in xpcs_get_state()
1109 ret = xpcs_get_state_c73(xpcs, state, compat); in xpcs_get_state()
1117 ret = xpcs_get_state_c37_sgmii(xpcs, state); in xpcs_get_state()
1124 ret = xpcs_get_state_c37_1000basex(xpcs, state); in xpcs_get_state()
1135 static void xpcs_link_up_sgmii(struct dw_xpcs *xpcs, unsigned int neg_mode, in xpcs_link_up_sgmii() argument
1144 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, val); in xpcs_link_up_sgmii()
1149 static void xpcs_link_up_1000basex(struct dw_xpcs *xpcs, unsigned int neg_mode, in xpcs_link_up_1000basex() argument
1173 ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, val); in xpcs_link_up_1000basex()
1181 struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); in xpcs_link_up() local
1184 return xpcs_config_usxgmii(xpcs, speed); in xpcs_link_up()
1186 return xpcs_link_up_sgmii(xpcs, neg_mode, speed, duplex); in xpcs_link_up()
1188 return xpcs_link_up_1000basex(xpcs, neg_mode, speed, duplex); in xpcs_link_up()
1194 struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); in xpcs_an_restart() local
1197 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1); in xpcs_an_restart()
1200 xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, ret); in xpcs_an_restart()
1204 static u32 xpcs_get_id(struct dw_xpcs *xpcs) in xpcs_get_id() argument
1210 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID1); in xpcs_get_id()
1216 ret = xpcs_read(xpcs, MDIO_MMD_PCS, MII_PHYSID2); in xpcs_get_id()
1227 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID1); in xpcs_get_id()
1233 ret = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_PHYSID2); in xpcs_get_id()
1343 struct dw_xpcs *xpcs; in xpcs_create() local
1347 xpcs = kzalloc(sizeof(*xpcs), GFP_KERNEL); in xpcs_create()
1348 if (!xpcs) in xpcs_create()
1352 xpcs->mdiodev = mdiodev; in xpcs_create()
1354 xpcs_id = xpcs_get_id(xpcs); in xpcs_create()
1363 xpcs->id = entry; in xpcs_create()
1371 ret = xpcs_dev_flag(xpcs); in xpcs_create()
1375 xpcs->pcs.ops = &xpcs_phylink_ops; in xpcs_create()
1376 xpcs->pcs.neg_mode = true; in xpcs_create()
1378 if (xpcs->dev_flag != DW_DEV_TXGBE) { in xpcs_create()
1379 xpcs->pcs.poll = true; in xpcs_create()
1381 ret = xpcs_soft_reset(xpcs, compat); in xpcs_create()
1386 return xpcs; in xpcs_create()
1393 kfree(xpcs); in xpcs_create()
1398 void xpcs_destroy(struct dw_xpcs *xpcs) in xpcs_destroy() argument
1400 if (xpcs) in xpcs_destroy()
1401 mdio_device_put(xpcs->mdiodev); in xpcs_destroy()
1402 kfree(xpcs); in xpcs_destroy()
1410 struct dw_xpcs *xpcs; in xpcs_create_mdiodev() local
1416 xpcs = xpcs_create(mdiodev, interface); in xpcs_create_mdiodev()
1426 return xpcs; in xpcs_create_mdiodev()