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