|
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