|
11 | 11 |
|
12 | 12 | #include <linux/slab.h> |
13 | 13 | #include <linux/io.h> |
| 14 | +#include <linux/pcs-lynx.h> |
14 | 15 | #include <linux/phy.h> |
15 | 16 | #include <linux/phy_fixed.h> |
16 | 17 | #include <linux/phy/phy.h> |
17 | 18 | #include <linux/of_mdio.h> |
18 | 19 |
|
19 | | -/* PCS registers */ |
20 | | -#define MDIO_SGMII_CR 0x00 |
21 | | -#define MDIO_SGMII_DEV_ABIL_SGMII 0x04 |
22 | | -#define MDIO_SGMII_LINK_TMR_L 0x12 |
23 | | -#define MDIO_SGMII_LINK_TMR_H 0x13 |
24 | | -#define MDIO_SGMII_IF_MODE 0x14 |
25 | | - |
26 | | -/* SGMII Control defines */ |
27 | | -#define SGMII_CR_AN_EN 0x1000 |
28 | | -#define SGMII_CR_RESTART_AN 0x0200 |
29 | | -#define SGMII_CR_FD 0x0100 |
30 | | -#define SGMII_CR_SPEED_SEL1_1G 0x0040 |
31 | | -#define SGMII_CR_DEF_VAL (SGMII_CR_AN_EN | SGMII_CR_FD | \ |
32 | | - SGMII_CR_SPEED_SEL1_1G) |
33 | | - |
34 | | -/* SGMII Device Ability for SGMII defines */ |
35 | | -#define MDIO_SGMII_DEV_ABIL_SGMII_MODE 0x4001 |
36 | | -#define MDIO_SGMII_DEV_ABIL_BASEX_MODE 0x01A0 |
37 | | - |
38 | | -/* Link timer define */ |
39 | | -#define LINK_TMR_L 0xa120 |
40 | | -#define LINK_TMR_H 0x0007 |
41 | | -#define LINK_TMR_L_BASEX 0xaf08 |
42 | | -#define LINK_TMR_H_BASEX 0x002f |
43 | | - |
44 | | -/* SGMII IF Mode defines */ |
45 | | -#define IF_MODE_USE_SGMII_AN 0x0002 |
46 | | -#define IF_MODE_SGMII_EN 0x0001 |
47 | | -#define IF_MODE_SGMII_SPEED_100M 0x0004 |
48 | | -#define IF_MODE_SGMII_SPEED_1G 0x0008 |
49 | | -#define IF_MODE_SGMII_DUPLEX_HALF 0x0010 |
50 | | - |
51 | 20 | /* Num of additional exact match MAC adr regs */ |
52 | 21 | #define MEMAC_NUM_OF_PADDRS 7 |
53 | 22 |
|
@@ -326,7 +295,9 @@ struct fman_mac { |
326 | 295 | struct fman_rev_info fm_rev_info; |
327 | 296 | bool basex_if; |
328 | 297 | struct phy *serdes; |
329 | | - struct phy_device *pcsphy; |
| 298 | + struct phylink_pcs *sgmii_pcs; |
| 299 | + struct phylink_pcs *qsgmii_pcs; |
| 300 | + struct phylink_pcs *xfi_pcs; |
330 | 301 | bool allmulti_enabled; |
331 | 302 | }; |
332 | 303 |
|
@@ -487,91 +458,22 @@ static u32 get_mac_addr_hash_code(u64 eth_addr) |
487 | 458 | return xor_val; |
488 | 459 | } |
489 | 460 |
|
490 | | -static void setup_sgmii_internal_phy(struct fman_mac *memac, |
491 | | - struct fixed_phy_status *fixed_link) |
| 461 | +static void setup_sgmii_internal(struct fman_mac *memac, |
| 462 | + struct phylink_pcs *pcs, |
| 463 | + struct fixed_phy_status *fixed_link) |
492 | 464 | { |
493 | | - u16 tmp_reg16; |
494 | | - |
495 | | - if (WARN_ON(!memac->pcsphy)) |
496 | | - return; |
497 | | - |
498 | | - /* SGMII mode */ |
499 | | - tmp_reg16 = IF_MODE_SGMII_EN; |
500 | | - if (!fixed_link) |
501 | | - /* AN enable */ |
502 | | - tmp_reg16 |= IF_MODE_USE_SGMII_AN; |
503 | | - else { |
504 | | - switch (fixed_link->speed) { |
505 | | - case 10: |
506 | | - /* For 10M: IF_MODE[SPEED_10M] = 0 */ |
507 | | - break; |
508 | | - case 100: |
509 | | - tmp_reg16 |= IF_MODE_SGMII_SPEED_100M; |
510 | | - break; |
511 | | - case 1000: |
512 | | - default: |
513 | | - tmp_reg16 |= IF_MODE_SGMII_SPEED_1G; |
514 | | - break; |
515 | | - } |
516 | | - if (!fixed_link->duplex) |
517 | | - tmp_reg16 |= IF_MODE_SGMII_DUPLEX_HALF; |
518 | | - } |
519 | | - phy_write(memac->pcsphy, MDIO_SGMII_IF_MODE, tmp_reg16); |
520 | | - |
521 | | - /* Device ability according to SGMII specification */ |
522 | | - tmp_reg16 = MDIO_SGMII_DEV_ABIL_SGMII_MODE; |
523 | | - phy_write(memac->pcsphy, MDIO_SGMII_DEV_ABIL_SGMII, tmp_reg16); |
524 | | - |
525 | | - /* Adjust link timer for SGMII - |
526 | | - * According to Cisco SGMII specification the timer should be 1.6 ms. |
527 | | - * The link_timer register is configured in units of the clock. |
528 | | - * - When running as 1G SGMII, Serdes clock is 125 MHz, so |
529 | | - * unit = 1 / (125*10^6 Hz) = 8 ns. |
530 | | - * 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2*10^5 = 0x30d40 |
531 | | - * - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so |
532 | | - * unit = 1 / (312.5*10^6 Hz) = 3.2 ns. |
533 | | - * 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5*10^5 = 0x7a120. |
534 | | - * Since link_timer value of 1G SGMII will be too short for 2.5 SGMII, |
535 | | - * we always set up here a value of 2.5 SGMII. |
536 | | - */ |
537 | | - phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_H, LINK_TMR_H); |
538 | | - phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_L, LINK_TMR_L); |
539 | | - |
540 | | - if (!fixed_link) |
541 | | - /* Restart AN */ |
542 | | - tmp_reg16 = SGMII_CR_DEF_VAL | SGMII_CR_RESTART_AN; |
| 465 | + __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); |
| 466 | + phy_interface_t iface = memac->basex_if ? PHY_INTERFACE_MODE_1000BASEX : |
| 467 | + PHY_INTERFACE_MODE_SGMII; |
| 468 | + unsigned int mode = fixed_link ? MLO_AN_FIXED : MLO_AN_INBAND; |
| 469 | + |
| 470 | + linkmode_set_pause(advertising, true, true); |
| 471 | + pcs->ops->pcs_config(pcs, mode, iface, advertising, true); |
| 472 | + if (fixed_link) |
| 473 | + pcs->ops->pcs_link_up(pcs, mode, iface, fixed_link->speed, |
| 474 | + fixed_link->duplex); |
543 | 475 | else |
544 | | - /* AN disabled */ |
545 | | - tmp_reg16 = SGMII_CR_DEF_VAL & ~SGMII_CR_AN_EN; |
546 | | - phy_write(memac->pcsphy, 0x0, tmp_reg16); |
547 | | -} |
548 | | - |
549 | | -static void setup_sgmii_internal_phy_base_x(struct fman_mac *memac) |
550 | | -{ |
551 | | - u16 tmp_reg16; |
552 | | - |
553 | | - /* AN Device capability */ |
554 | | - tmp_reg16 = MDIO_SGMII_DEV_ABIL_BASEX_MODE; |
555 | | - phy_write(memac->pcsphy, MDIO_SGMII_DEV_ABIL_SGMII, tmp_reg16); |
556 | | - |
557 | | - /* Adjust link timer for SGMII - |
558 | | - * For Serdes 1000BaseX auto-negotiation the timer should be 10 ms. |
559 | | - * The link_timer register is configured in units of the clock. |
560 | | - * - When running as 1G SGMII, Serdes clock is 125 MHz, so |
561 | | - * unit = 1 / (125*10^6 Hz) = 8 ns. |
562 | | - * 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0 |
563 | | - * - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so |
564 | | - * unit = 1 / (312.5*10^6 Hz) = 3.2 ns. |
565 | | - * 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08. |
566 | | - * Since link_timer value of 1G SGMII will be too short for 2.5 SGMII, |
567 | | - * we always set up here a value of 2.5 SGMII. |
568 | | - */ |
569 | | - phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_H, LINK_TMR_H_BASEX); |
570 | | - phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_L, LINK_TMR_L_BASEX); |
571 | | - |
572 | | - /* Restart AN */ |
573 | | - tmp_reg16 = SGMII_CR_DEF_VAL | SGMII_CR_RESTART_AN; |
574 | | - phy_write(memac->pcsphy, 0x0, tmp_reg16); |
| 476 | + pcs->ops->pcs_an_restart(pcs); |
575 | 477 | } |
576 | 478 |
|
577 | 479 | static int check_init_parameters(struct fman_mac *memac) |
@@ -983,7 +885,6 @@ static int memac_set_exception(struct fman_mac *memac, |
983 | 885 | static int memac_init(struct fman_mac *memac) |
984 | 886 | { |
985 | 887 | struct memac_cfg *memac_drv_param; |
986 | | - u8 i; |
987 | 888 | enet_addr_t eth_addr; |
988 | 889 | bool slow_10g_if = false; |
989 | 890 | struct fixed_phy_status *fixed_link = NULL; |
@@ -1036,32 +937,10 @@ static int memac_init(struct fman_mac *memac) |
1036 | 937 | iowrite32be(reg32, &memac->regs->command_config); |
1037 | 938 | } |
1038 | 939 |
|
1039 | | - if (memac->phy_if == PHY_INTERFACE_MODE_SGMII) { |
1040 | | - /* Configure internal SGMII PHY */ |
1041 | | - if (memac->basex_if) |
1042 | | - setup_sgmii_internal_phy_base_x(memac); |
1043 | | - else |
1044 | | - setup_sgmii_internal_phy(memac, fixed_link); |
1045 | | - } else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII) { |
1046 | | - /* Configure 4 internal SGMII PHYs */ |
1047 | | - for (i = 0; i < 4; i++) { |
1048 | | - u8 qsmgii_phy_addr, phy_addr; |
1049 | | - /* QSGMII PHY address occupies 3 upper bits of 5-bit |
1050 | | - * phy_address; the lower 2 bits are used to extend |
1051 | | - * register address space and access each one of 4 |
1052 | | - * ports inside QSGMII. |
1053 | | - */ |
1054 | | - phy_addr = memac->pcsphy->mdio.addr; |
1055 | | - qsmgii_phy_addr = (u8)((phy_addr << 2) | i); |
1056 | | - memac->pcsphy->mdio.addr = qsmgii_phy_addr; |
1057 | | - if (memac->basex_if) |
1058 | | - setup_sgmii_internal_phy_base_x(memac); |
1059 | | - else |
1060 | | - setup_sgmii_internal_phy(memac, fixed_link); |
1061 | | - |
1062 | | - memac->pcsphy->mdio.addr = phy_addr; |
1063 | | - } |
1064 | | - } |
| 940 | + if (memac->phy_if == PHY_INTERFACE_MODE_SGMII) |
| 941 | + setup_sgmii_internal(memac, memac->sgmii_pcs, fixed_link); |
| 942 | + else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII) |
| 943 | + setup_sgmii_internal(memac, memac->qsgmii_pcs, fixed_link); |
1065 | 944 |
|
1066 | 945 | /* Max Frame Length */ |
1067 | 946 | err = fman_set_mac_max_frame(memac->fm, memac->mac_id, |
@@ -1097,12 +976,25 @@ static int memac_init(struct fman_mac *memac) |
1097 | 976 | return 0; |
1098 | 977 | } |
1099 | 978 |
|
| 979 | +static void pcs_put(struct phylink_pcs *pcs) |
| 980 | +{ |
| 981 | + struct mdio_device *mdiodev; |
| 982 | + |
| 983 | + if (IS_ERR_OR_NULL(pcs)) |
| 984 | + return; |
| 985 | + |
| 986 | + mdiodev = lynx_get_mdio_device(pcs); |
| 987 | + lynx_pcs_destroy(pcs); |
| 988 | + mdio_device_free(mdiodev); |
| 989 | +} |
| 990 | + |
1100 | 991 | static int memac_free(struct fman_mac *memac) |
1101 | 992 | { |
1102 | 993 | free_init_resources(memac); |
1103 | 994 |
|
1104 | | - if (memac->pcsphy) |
1105 | | - put_device(&memac->pcsphy->mdio.dev); |
| 995 | + pcs_put(memac->sgmii_pcs); |
| 996 | + pcs_put(memac->qsgmii_pcs); |
| 997 | + pcs_put(memac->xfi_pcs); |
1106 | 998 |
|
1107 | 999 | kfree(memac->memac_drv_param); |
1108 | 1000 | kfree(memac); |
@@ -1153,12 +1045,31 @@ static struct fman_mac *memac_config(struct mac_device *mac_dev, |
1153 | 1045 | return memac; |
1154 | 1046 | } |
1155 | 1047 |
|
| 1048 | +static struct phylink_pcs *memac_pcs_create(struct device_node *mac_node, |
| 1049 | + int index) |
| 1050 | +{ |
| 1051 | + struct device_node *node; |
| 1052 | + struct mdio_device *mdiodev = NULL; |
| 1053 | + struct phylink_pcs *pcs; |
| 1054 | + |
| 1055 | + node = of_parse_phandle(mac_node, "pcsphy-handle", index); |
| 1056 | + if (node && of_device_is_available(node)) |
| 1057 | + mdiodev = of_mdio_find_device(node); |
| 1058 | + of_node_put(node); |
| 1059 | + |
| 1060 | + if (!mdiodev) |
| 1061 | + return ERR_PTR(-EPROBE_DEFER); |
| 1062 | + |
| 1063 | + pcs = lynx_pcs_create(mdiodev); |
| 1064 | + return pcs; |
| 1065 | +} |
| 1066 | + |
1156 | 1067 | int memac_initialization(struct mac_device *mac_dev, |
1157 | 1068 | struct device_node *mac_node, |
1158 | 1069 | struct fman_mac_params *params) |
1159 | 1070 | { |
1160 | 1071 | int err; |
1161 | | - struct device_node *phy_node; |
| 1072 | + struct phylink_pcs *pcs; |
1162 | 1073 | struct fixed_phy_status *fixed_link; |
1163 | 1074 | struct fman_mac *memac; |
1164 | 1075 |
|
@@ -1188,23 +1099,58 @@ int memac_initialization(struct mac_device *mac_dev, |
1188 | 1099 | memac = mac_dev->fman_mac; |
1189 | 1100 | memac->memac_drv_param->max_frame_length = fman_get_max_frm(); |
1190 | 1101 | memac->memac_drv_param->reset_on_init = true; |
1191 | | - if (memac->phy_if == PHY_INTERFACE_MODE_SGMII || |
1192 | | - memac->phy_if == PHY_INTERFACE_MODE_QSGMII) { |
1193 | | - phy_node = of_parse_phandle(mac_node, "pcsphy-handle", 0); |
1194 | | - if (!phy_node) { |
1195 | | - pr_err("PCS PHY node is not available\n"); |
1196 | | - err = -EINVAL; |
| 1102 | + |
| 1103 | + err = of_property_match_string(mac_node, "pcs-handle-names", "xfi"); |
| 1104 | + if (err >= 0) { |
| 1105 | + memac->xfi_pcs = memac_pcs_create(mac_node, err); |
| 1106 | + if (IS_ERR(memac->xfi_pcs)) { |
| 1107 | + err = PTR_ERR(memac->xfi_pcs); |
| 1108 | + dev_err_probe(mac_dev->dev, err, "missing xfi pcs\n"); |
1197 | 1109 | goto _return_fm_mac_free; |
1198 | 1110 | } |
| 1111 | + } else if (err != -EINVAL && err != -ENODATA) { |
| 1112 | + goto _return_fm_mac_free; |
| 1113 | + } |
1199 | 1114 |
|
1200 | | - memac->pcsphy = of_phy_find_device(phy_node); |
1201 | | - if (!memac->pcsphy) { |
1202 | | - pr_err("of_phy_find_device (PCS PHY) failed\n"); |
1203 | | - err = -EINVAL; |
| 1115 | + err = of_property_match_string(mac_node, "pcs-handle-names", "qsgmii"); |
| 1116 | + if (err >= 0) { |
| 1117 | + memac->qsgmii_pcs = memac_pcs_create(mac_node, err); |
| 1118 | + if (IS_ERR(memac->qsgmii_pcs)) { |
| 1119 | + err = PTR_ERR(memac->qsgmii_pcs); |
| 1120 | + dev_err_probe(mac_dev->dev, err, |
| 1121 | + "missing qsgmii pcs\n"); |
1204 | 1122 | goto _return_fm_mac_free; |
1205 | 1123 | } |
| 1124 | + } else if (err != -EINVAL && err != -ENODATA) { |
| 1125 | + goto _return_fm_mac_free; |
| 1126 | + } |
| 1127 | + |
| 1128 | + /* For compatibility, if pcs-handle-names is missing, we assume this |
| 1129 | + * phy is the first one in pcsphy-handle |
| 1130 | + */ |
| 1131 | + err = of_property_match_string(mac_node, "pcs-handle-names", "sgmii"); |
| 1132 | + if (err == -EINVAL || err == -ENODATA) |
| 1133 | + pcs = memac_pcs_create(mac_node, 0); |
| 1134 | + else if (err < 0) |
| 1135 | + goto _return_fm_mac_free; |
| 1136 | + else |
| 1137 | + pcs = memac_pcs_create(mac_node, err); |
| 1138 | + |
| 1139 | + if (!pcs) { |
| 1140 | + dev_err(mac_dev->dev, "missing pcs\n"); |
| 1141 | + err = -ENOENT; |
| 1142 | + goto _return_fm_mac_free; |
1206 | 1143 | } |
1207 | 1144 |
|
| 1145 | + /* If err is set here, it means that pcs-handle-names was missing above |
| 1146 | + * (and therefore that xfi_pcs cannot be set). If we are defaulting to |
| 1147 | + * XGMII, assume this is for XFI. Otherwise, assume it is for SGMII. |
| 1148 | + */ |
| 1149 | + if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII) |
| 1150 | + memac->xfi_pcs = pcs; |
| 1151 | + else |
| 1152 | + memac->sgmii_pcs = pcs; |
| 1153 | + |
1208 | 1154 | memac->serdes = devm_of_phy_get(mac_dev->dev, mac_node, "serdes"); |
1209 | 1155 | err = PTR_ERR(memac->serdes); |
1210 | 1156 | if (err == -ENODEV || err == -ENOSYS) { |
|
0 commit comments