Skip to content

Commit a7c2a32

Browse files
sean-anderson-secodavem330
authored andcommitted
net: fman: memac: Use lynx pcs driver
Although not stated in the datasheet, as far as I can tell PCS for mEMACs is a "Lynx." By reusing the existing driver, we can remove the PCS management code from the memac driver. This requires calling some PCS functions manually which phylink would usually do for us, but we will let it do that soon. One problem is that we don't actually have a PCS for QSGMII. We pretend that each mEMAC's MDIO bus has four QSGMII PCSs, but this is not the case. Only the "base" mEMAC's MDIO bus has the four QSGMII PCSs. This is not an issue yet, because we never get the PCS state. However, it will be once the conversion to phylink is complete, since the links will appear to never come up. To get around this, we allow specifying multiple PCSs in pcsphy. This breaks backwards compatibility with old device trees, but only for QSGMII. IMO this is the only reasonable way to figure out what the actual QSGMII PCS is. Additionally, we now also support a separate XFI PCS. This can allow the SerDes driver to set different addresses for the SGMII and XFI PCSs so they can be accessed at the same time. Signed-off-by: Sean Anderson <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0fc83bd commit a7c2a32

File tree

2 files changed

+105
-156
lines changed

2 files changed

+105
-156
lines changed

drivers/net/ethernet/freescale/fman/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ config FSL_FMAN
44
depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
55
select GENERIC_ALLOCATOR
66
select PHYLIB
7+
select PHYLINK
8+
select PCS
9+
select PCS_LYNX
710
select CRC32
811
default n
912
help

drivers/net/ethernet/freescale/fman/fman_memac.c

Lines changed: 102 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -11,43 +11,12 @@
1111

1212
#include <linux/slab.h>
1313
#include <linux/io.h>
14+
#include <linux/pcs-lynx.h>
1415
#include <linux/phy.h>
1516
#include <linux/phy_fixed.h>
1617
#include <linux/phy/phy.h>
1718
#include <linux/of_mdio.h>
1819

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-
5120
/* Num of additional exact match MAC adr regs */
5221
#define MEMAC_NUM_OF_PADDRS 7
5322

@@ -326,7 +295,9 @@ struct fman_mac {
326295
struct fman_rev_info fm_rev_info;
327296
bool basex_if;
328297
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;
330301
bool allmulti_enabled;
331302
};
332303

@@ -487,91 +458,22 @@ static u32 get_mac_addr_hash_code(u64 eth_addr)
487458
return xor_val;
488459
}
489460

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)
492464
{
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);
543475
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);
575477
}
576478

577479
static int check_init_parameters(struct fman_mac *memac)
@@ -983,7 +885,6 @@ static int memac_set_exception(struct fman_mac *memac,
983885
static int memac_init(struct fman_mac *memac)
984886
{
985887
struct memac_cfg *memac_drv_param;
986-
u8 i;
987888
enet_addr_t eth_addr;
988889
bool slow_10g_if = false;
989890
struct fixed_phy_status *fixed_link = NULL;
@@ -1036,32 +937,10 @@ static int memac_init(struct fman_mac *memac)
1036937
iowrite32be(reg32, &memac->regs->command_config);
1037938
}
1038939

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);
1065944

1066945
/* Max Frame Length */
1067946
err = fman_set_mac_max_frame(memac->fm, memac->mac_id,
@@ -1097,12 +976,25 @@ static int memac_init(struct fman_mac *memac)
1097976
return 0;
1098977
}
1099978

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+
1100991
static int memac_free(struct fman_mac *memac)
1101992
{
1102993
free_init_resources(memac);
1103994

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);
1106998

1107999
kfree(memac->memac_drv_param);
11081000
kfree(memac);
@@ -1153,12 +1045,31 @@ static struct fman_mac *memac_config(struct mac_device *mac_dev,
11531045
return memac;
11541046
}
11551047

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+
11561067
int memac_initialization(struct mac_device *mac_dev,
11571068
struct device_node *mac_node,
11581069
struct fman_mac_params *params)
11591070
{
11601071
int err;
1161-
struct device_node *phy_node;
1072+
struct phylink_pcs *pcs;
11621073
struct fixed_phy_status *fixed_link;
11631074
struct fman_mac *memac;
11641075

@@ -1188,23 +1099,58 @@ int memac_initialization(struct mac_device *mac_dev,
11881099
memac = mac_dev->fman_mac;
11891100
memac->memac_drv_param->max_frame_length = fman_get_max_frm();
11901101
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");
11971109
goto _return_fm_mac_free;
11981110
}
1111+
} else if (err != -EINVAL && err != -ENODATA) {
1112+
goto _return_fm_mac_free;
1113+
}
11991114

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");
12041122
goto _return_fm_mac_free;
12051123
}
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;
12061143
}
12071144

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+
12081154
memac->serdes = devm_of_phy_get(mac_dev->dev, mac_node, "serdes");
12091155
err = PTR_ERR(memac->serdes);
12101156
if (err == -ENODEV || err == -ENOSYS) {

0 commit comments

Comments
 (0)