diff options
| author | 2020-07-05 15:25:59 -0700 | |
|---|---|---|
| committer | 2020-07-05 15:25:59 -0700 | |
| commit | dbacfd8ca755b9f710ab17a1e47572fc4e5dabcc (patch) | |
| tree | 830c899a6be455557058bc2753daece86a104cde | |
| parent | Merge branch 'qlogic-use-generic-power-management' (diff) | |
| parent | net: dsa: felix: use resolved link config in mac_link_up() (diff) | |
Merge branch 'Phylink-integration-improvements-for-Felix-DSA-driver'
Vladimir Oltean says:
====================
Phylink integration improvements for Felix DSA driver
This is an overhaul of the Felix switch driver's phylink operations.
Patches 1, 3, 4 and 5 are cleanup, patch 2 is adding a new feature and
and patch 6 is adaptation to the new format of an existing phylink API
(mac_link_up).
Changes since v2:
- Replaced "PHYLINK" with "phylink".
- Rewrote commit message of patch 5/6.
Changes since v1:
- Now using phy_clear_bits and phy_set_bits instead of plain writes to
MII_BMCR. This combines former patches 1/7 and 6/7 into a single new
patch 1/6.
- Updated commit message of patch 5/6.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/dsa/ocelot/felix.c | 108 | ||||
| -rw-r--r-- | drivers/net/dsa/ocelot/felix.h | 11 | ||||
| -rw-r--r-- | drivers/net/dsa/ocelot/felix_vsc9959.c | 294 | ||||
| -rw-r--r-- | include/linux/fsl/enetc_mdio.h | 1 |
4 files changed, 211 insertions, 203 deletions
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index 75020af7f7a4..75652ed99b24 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -194,13 +194,15 @@ static void felix_phylink_validate(struct dsa_switch *ds, int port, return; } - /* No half-duplex. */ phylink_set_port_modes(mask); phylink_set(mask, Autoneg); phylink_set(mask, Pause); phylink_set(mask, Asym_Pause); + phylink_set(mask, 10baseT_Half); phylink_set(mask, 10baseT_Full); + phylink_set(mask, 100baseT_Half); phylink_set(mask, 100baseT_Full); + phylink_set(mask, 1000baseT_Half); phylink_set(mask, 1000baseT_Full); if (state->interface == PHY_INTERFACE_MODE_INTERNAL || @@ -233,50 +235,10 @@ static void felix_phylink_mac_config(struct dsa_switch *ds, int port, const struct phylink_link_state *state) { struct ocelot *ocelot = ds->priv; - struct ocelot_port *ocelot_port = ocelot->ports[port]; - struct felix *felix = ocelot_to_felix(ocelot); - u32 mac_fc_cfg; - - /* Take port out of reset by clearing the MAC_TX_RST, MAC_RX_RST and - * PORT_RST bits in CLOCK_CFG - */ - ocelot_port_writel(ocelot_port, DEV_CLOCK_CFG_LINK_SPEED(state->speed), - DEV_CLOCK_CFG); - - /* Flow control. Link speed is only used here to evaluate the time - * specification in incoming pause frames. - */ - mac_fc_cfg = SYS_MAC_FC_CFG_FC_LINK_SPEED(state->speed); - - /* handle Rx pause in all cases, with 2500base-X this is used for rate - * adaptation. - */ - mac_fc_cfg |= SYS_MAC_FC_CFG_RX_FC_ENA; - - if (state->pause & MLO_PAUSE_TX) - mac_fc_cfg |= SYS_MAC_FC_CFG_TX_FC_ENA | - SYS_MAC_FC_CFG_PAUSE_VAL_CFG(0xffff) | - SYS_MAC_FC_CFG_FC_LATENCY_CFG(0x7) | - SYS_MAC_FC_CFG_ZERO_PAUSE_ENA; - ocelot_write_rix(ocelot, mac_fc_cfg, SYS_MAC_FC_CFG, port); - - ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port); - - if (felix->info->pcs_init) - felix->info->pcs_init(ocelot, port, link_an_mode, state); - - if (felix->info->port_sched_speed_set) - felix->info->port_sched_speed_set(ocelot, port, - state->speed); -} - -static void felix_phylink_mac_an_restart(struct dsa_switch *ds, int port) -{ - struct ocelot *ocelot = ds->priv; struct felix *felix = ocelot_to_felix(ocelot); - if (felix->info->pcs_an_restart) - felix->info->pcs_an_restart(ocelot, port); + if (felix->info->pcs_config) + felix->info->pcs_config(ocelot, port, link_an_mode, state); } static void felix_phylink_mac_link_down(struct dsa_switch *ds, int port, @@ -300,8 +262,58 @@ static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port, { struct ocelot *ocelot = ds->priv; struct ocelot_port *ocelot_port = ocelot->ports[port]; + struct felix *felix = ocelot_to_felix(ocelot); + u32 mac_fc_cfg; + + /* Take port out of reset by clearing the MAC_TX_RST, MAC_RX_RST and + * PORT_RST bits in DEV_CLOCK_CFG. Note that the way this system is + * integrated is that the MAC speed is fixed and it's the PCS who is + * performing the rate adaptation, so we have to write "1000Mbps" into + * the LINK_SPEED field of DEV_CLOCK_CFG (which is also its default + * value). + */ + ocelot_port_writel(ocelot_port, + DEV_CLOCK_CFG_LINK_SPEED(OCELOT_SPEED_1000), + DEV_CLOCK_CFG); + + switch (speed) { + case SPEED_10: + mac_fc_cfg = SYS_MAC_FC_CFG_FC_LINK_SPEED(3); + break; + case SPEED_100: + mac_fc_cfg = SYS_MAC_FC_CFG_FC_LINK_SPEED(2); + break; + case SPEED_1000: + case SPEED_2500: + mac_fc_cfg = SYS_MAC_FC_CFG_FC_LINK_SPEED(1); + break; + default: + dev_err(ocelot->dev, "Unsupported speed on port %d: %d\n", + port, speed); + return; + } + + /* handle Rx pause in all cases, with 2500base-X this is used for rate + * adaptation. + */ + mac_fc_cfg |= SYS_MAC_FC_CFG_RX_FC_ENA; + + if (tx_pause) + mac_fc_cfg |= SYS_MAC_FC_CFG_TX_FC_ENA | + SYS_MAC_FC_CFG_PAUSE_VAL_CFG(0xffff) | + SYS_MAC_FC_CFG_FC_LATENCY_CFG(0x7) | + SYS_MAC_FC_CFG_ZERO_PAUSE_ENA; - /* Enable MAC module */ + /* Flow control. Link speed is only used here to evaluate the time + * specification in incoming pause frames. + */ + ocelot_write_rix(ocelot, mac_fc_cfg, SYS_MAC_FC_CFG, port); + + ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port); + + /* Undo the effects of felix_phylink_mac_link_down: + * enable MAC module + */ ocelot_port_writel(ocelot_port, DEV_MAC_ENA_CFG_RX_ENA | DEV_MAC_ENA_CFG_TX_ENA, DEV_MAC_ENA_CFG); @@ -318,6 +330,13 @@ static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port, QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) | QSYS_SWITCH_PORT_MODE_PORT_ENA, QSYS_SWITCH_PORT_MODE, port); + + if (felix->info->pcs_link_up) + felix->info->pcs_link_up(ocelot, port, link_an_mode, interface, + speed, duplex); + + if (felix->info->port_sched_speed_set) + felix->info->port_sched_speed_set(ocelot, port, speed); } static void felix_port_qos_map_init(struct ocelot *ocelot, int port) @@ -784,7 +803,6 @@ static const struct dsa_switch_ops felix_switch_ops = { .phylink_validate = felix_phylink_validate, .phylink_mac_link_state = felix_phylink_mac_pcs_get_state, .phylink_mac_config = felix_phylink_mac_config, - .phylink_mac_an_restart = felix_phylink_mac_an_restart, .phylink_mac_link_down = felix_phylink_mac_link_down, .phylink_mac_link_up = felix_phylink_mac_link_up, .port_enable = felix_port_enable, diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h index a891736ca006..00137b64132b 100644 --- a/drivers/net/dsa/ocelot/felix.h +++ b/drivers/net/dsa/ocelot/felix.h @@ -28,10 +28,13 @@ struct felix_info { int imdio_pci_bar; int (*mdio_bus_alloc)(struct ocelot *ocelot); void (*mdio_bus_free)(struct ocelot *ocelot); - void (*pcs_init)(struct ocelot *ocelot, int port, - unsigned int link_an_mode, - const struct phylink_link_state *state); - void (*pcs_an_restart)(struct ocelot *ocelot, int port); + void (*pcs_config)(struct ocelot *ocelot, int port, + unsigned int link_an_mode, + const struct phylink_link_state *state); + void (*pcs_link_up)(struct ocelot *ocelot, int port, + unsigned int link_an_mode, + phy_interface_t interface, + int speed, int duplex); void (*pcs_link_state)(struct ocelot *ocelot, int port, struct phylink_link_state *state); int (*prevalidate_phy_mode)(struct ocelot *ocelot, int port, diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 2067776773f7..19614537b1ba 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -728,42 +728,6 @@ static int vsc9959_reset(struct ocelot *ocelot) return 0; } -static void vsc9959_pcs_an_restart_sgmii(struct phy_device *pcs) -{ - phy_set_bits(pcs, MII_BMCR, BMCR_ANRESTART); -} - -static void vsc9959_pcs_an_restart_usxgmii(struct phy_device *pcs) -{ - phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_BMCR, - USXGMII_BMCR_RESET | - USXGMII_BMCR_AN_EN | - USXGMII_BMCR_RST_AN); -} - -static void vsc9959_pcs_an_restart(struct ocelot *ocelot, int port) -{ - struct felix *felix = ocelot_to_felix(ocelot); - struct phy_device *pcs = felix->pcs[port]; - - if (!pcs) - return; - - switch (pcs->interface) { - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_QSGMII: - vsc9959_pcs_an_restart_sgmii(pcs); - break; - case PHY_INTERFACE_MODE_USXGMII: - vsc9959_pcs_an_restart_usxgmii(pcs); - break; - default: - dev_err(ocelot->dev, "Invalid PCS interface type %s\n", - phy_modes(pcs->interface)); - break; - } -} - /* We enable SGMII AN only when the PHY has managed = "in-band-status" in the * device tree. If we are in MLO_AN_PHY mode, we program directly state->speed * into the PCS, which is retrieved out-of-band over MDIO. This also has the @@ -773,129 +737,54 @@ static void vsc9959_pcs_an_restart(struct ocelot *ocelot, int port) * traffic if SGMII AN is enabled but not completed (acknowledged by us), so * setting MLO_AN_INBAND is actually required for those. */ -static void vsc9959_pcs_init_sgmii(struct phy_device *pcs, - unsigned int link_an_mode, - const struct phylink_link_state *state) +static void vsc9959_pcs_config_sgmii(struct phy_device *pcs, + unsigned int link_an_mode, + const struct phylink_link_state *state) { - if (link_an_mode == MLO_AN_INBAND) { - int bmsr, bmcr; - - /* Some PHYs like VSC8234 don't like it when AN restarts on - * their system side and they restart line side AN too, going - * into an endless link up/down loop. Don't restart PCS AN if - * link is up already. - * We do check that AN is enabled just in case this is the 1st - * call, PCS detects a carrier but AN is disabled from power on - * or by boot loader. - */ - bmcr = phy_read(pcs, MII_BMCR); - if (bmcr < 0) - return; - - bmsr = phy_read(pcs, MII_BMSR); - if (bmsr < 0) - return; + int bmsr, bmcr; - if ((bmcr & BMCR_ANENABLE) && (bmsr & BMSR_LSTATUS)) - return; - - /* SGMII spec requires tx_config_Reg[15:0] to be exactly 0x4001 - * for the MAC PCS in order to acknowledge the AN. - */ - phy_write(pcs, MII_ADVERTISE, ADVERTISE_SGMII | - ADVERTISE_LPACK); + /* Some PHYs like VSC8234 don't like it when AN restarts on + * their system side and they restart line side AN too, going + * into an endless link up/down loop. Don't restart PCS AN if + * link is up already. + * We do check that AN is enabled just in case this is the 1st + * call, PCS detects a carrier but AN is disabled from power on + * or by boot loader. + */ + bmcr = phy_read(pcs, MII_BMCR); + if (bmcr < 0) + return; - phy_write(pcs, ENETC_PCS_IF_MODE, - ENETC_PCS_IF_MODE_SGMII_EN | - ENETC_PCS_IF_MODE_USE_SGMII_AN); + bmsr = phy_read(pcs, MII_BMSR); + if (bmsr < 0) + return; - /* Adjust link timer for SGMII */ - phy_write(pcs, ENETC_PCS_LINK_TIMER1, - ENETC_PCS_LINK_TIMER1_VAL); - phy_write(pcs, ENETC_PCS_LINK_TIMER2, - ENETC_PCS_LINK_TIMER2_VAL); + if ((bmcr & BMCR_ANENABLE) && (bmsr & BMSR_LSTATUS)) + return; - phy_write(pcs, MII_BMCR, BMCR_ANRESTART | BMCR_ANENABLE); - } else { - int speed; + /* SGMII spec requires tx_config_Reg[15:0] to be exactly 0x4001 + * for the MAC PCS in order to acknowledge the AN. + */ + phy_write(pcs, MII_ADVERTISE, ADVERTISE_SGMII | + ADVERTISE_LPACK); - if (state->duplex == DUPLEX_HALF) { - phydev_err(pcs, "Half duplex not supported\n"); - return; - } - switch (state->speed) { - case SPEED_1000: - speed = ENETC_PCS_SPEED_1000; - break; - case SPEED_100: - speed = ENETC_PCS_SPEED_100; - break; - case SPEED_10: - speed = ENETC_PCS_SPEED_10; - break; - case SPEED_UNKNOWN: - /* Silently don't do anything */ - return; - default: - phydev_err(pcs, "Invalid PCS speed %d\n", state->speed); - return; - } + phy_write(pcs, ENETC_PCS_IF_MODE, + ENETC_PCS_IF_MODE_SGMII_EN | + ENETC_PCS_IF_MODE_USE_SGMII_AN); - phy_write(pcs, ENETC_PCS_IF_MODE, - ENETC_PCS_IF_MODE_SGMII_EN | - ENETC_PCS_IF_MODE_SGMII_SPEED(speed)); + /* Adjust link timer for SGMII */ + phy_write(pcs, ENETC_PCS_LINK_TIMER1, + ENETC_PCS_LINK_TIMER1_VAL); + phy_write(pcs, ENETC_PCS_LINK_TIMER2, + ENETC_PCS_LINK_TIMER2_VAL); - /* Yes, not a mistake: speed is given by IF_MODE. */ - phy_write(pcs, MII_BMCR, BMCR_RESET | - BMCR_SPEED1000 | - BMCR_FULLDPLX); - } + phy_set_bits(pcs, MII_BMCR, BMCR_ANENABLE); } -/* 2500Base-X is SerDes protocol 7 on Felix and 6 on ENETC. It is a SerDes lane - * clocked at 3.125 GHz which encodes symbols with 8b/10b and does not have - * auto-negotiation of any link parameters. Electrically it is compatible with - * a single lane of XAUI. - * The hardware reference manual wants to call this mode SGMII, but it isn't - * really, since the fundamental features of SGMII: - * - Downgrading the link speed by duplicating symbols - * - Auto-negotiation - * are not there. - * The speed is configured at 1000 in the IF_MODE and BMCR MDIO registers - * because the clock frequency is actually given by a PLL configured in the - * Reset Configuration Word (RCW). - * Since there is no difference between fixed speed SGMII w/o AN and 802.3z w/o - * AN, we call this PHY interface type 2500Base-X. In case a PHY negotiates a - * lower link speed on line side, the system-side interface remains fixed at - * 2500 Mbps and we do rate adaptation through pause frames. - */ -static void vsc9959_pcs_init_2500basex(struct phy_device *pcs, +static void vsc9959_pcs_config_usxgmii(struct phy_device *pcs, unsigned int link_an_mode, const struct phylink_link_state *state) { - if (link_an_mode == MLO_AN_INBAND) { - phydev_err(pcs, "AN not supported on 3.125GHz SerDes lane\n"); - return; - } - - phy_write(pcs, ENETC_PCS_IF_MODE, - ENETC_PCS_IF_MODE_SGMII_EN | - ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_2500)); - - phy_write(pcs, MII_BMCR, BMCR_SPEED1000 | - BMCR_FULLDPLX | - BMCR_RESET); -} - -static void vsc9959_pcs_init_usxgmii(struct phy_device *pcs, - unsigned int link_an_mode, - const struct phylink_link_state *state) -{ - if (link_an_mode != MLO_AN_INBAND) { - phydev_err(pcs, "USXGMII only supports in-band AN for now\n"); - return; - } - /* Configure device ability for the USXGMII Replicator */ phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_ADVERTISE, USXGMII_ADVERTISE_SPEED(USXGMII_SPEED_2500) | @@ -905,9 +794,9 @@ static void vsc9959_pcs_init_usxgmii(struct phy_device *pcs, USXGMII_ADVERTISE_FDX); } -static void vsc9959_pcs_init(struct ocelot *ocelot, int port, - unsigned int link_an_mode, - const struct phylink_link_state *state) +static void vsc9959_pcs_config(struct ocelot *ocelot, int port, + unsigned int link_an_mode, + const struct phylink_link_state *state) { struct felix *felix = ocelot_to_felix(ocelot); struct phy_device *pcs = felix->pcs[port]; @@ -924,8 +813,11 @@ static void vsc9959_pcs_init(struct ocelot *ocelot, int port, linkmode_set_bit_array(phy_basic_ports_array, ARRAY_SIZE(phy_basic_ports_array), pcs->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, pcs->supported); linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, pcs->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, pcs->supported); linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, pcs->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, pcs->supported); linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, pcs->supported); if (pcs->interface == PHY_INTERFACE_MODE_2500BASEX || pcs->interface == PHY_INTERFACE_MODE_USXGMII) @@ -936,16 +828,110 @@ static void vsc9959_pcs_init(struct ocelot *ocelot, int port, pcs->supported); phy_advertise_supported(pcs); + if (!phylink_autoneg_inband(link_an_mode)) + return; + switch (pcs->interface) { case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_QSGMII: - vsc9959_pcs_init_sgmii(pcs, link_an_mode, state); + vsc9959_pcs_config_sgmii(pcs, link_an_mode, state); break; case PHY_INTERFACE_MODE_2500BASEX: - vsc9959_pcs_init_2500basex(pcs, link_an_mode, state); + phydev_err(pcs, "AN not supported on 3.125GHz SerDes lane\n"); break; case PHY_INTERFACE_MODE_USXGMII: - vsc9959_pcs_init_usxgmii(pcs, link_an_mode, state); + vsc9959_pcs_config_usxgmii(pcs, link_an_mode, state); + break; + default: + dev_err(ocelot->dev, "Unsupported link mode %s\n", + phy_modes(pcs->interface)); + } +} + +static void vsc9959_pcs_link_up_sgmii(struct phy_device *pcs, + unsigned int link_an_mode, + int speed, int duplex) +{ + u16 if_mode = ENETC_PCS_IF_MODE_SGMII_EN; + + switch (speed) { + case SPEED_1000: + if_mode |= ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_1000); + break; + case SPEED_100: + if_mode |= ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_100); + break; + case SPEED_10: + if_mode |= ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_10); + break; + default: + phydev_err(pcs, "Invalid PCS speed %d\n", speed); + return; + } + + if (duplex == DUPLEX_HALF) + if_mode |= ENETC_PCS_IF_MODE_DUPLEX_HALF; + + phy_write(pcs, ENETC_PCS_IF_MODE, if_mode); + phy_clear_bits(pcs, MII_BMCR, BMCR_ANENABLE); +} + +/* 2500Base-X is SerDes protocol 7 on Felix and 6 on ENETC. It is a SerDes lane + * clocked at 3.125 GHz which encodes symbols with 8b/10b and does not have + * auto-negotiation of any link parameters. Electrically it is compatible with + * a single lane of XAUI. + * The hardware reference manual wants to call this mode SGMII, but it isn't + * really, since the fundamental features of SGMII: + * - Downgrading the link speed by duplicating symbols + * - Auto-negotiation + * are not there. + * The speed is configured at 1000 in the IF_MODE and BMCR MDIO registers + * because the clock frequency is actually given by a PLL configured in the + * Reset Configuration Word (RCW). + * Since there is no difference between fixed speed SGMII w/o AN and 802.3z w/o + * AN, we call this PHY interface type 2500Base-X. In case a PHY negotiates a + * lower link speed on line side, the system-side interface remains fixed at + * 2500 Mbps and we do rate adaptation through pause frames. + */ +static void vsc9959_pcs_link_up_2500basex(struct phy_device *pcs, + unsigned int link_an_mode, + int speed, int duplex) +{ + u16 if_mode = ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_2500) | + ENETC_PCS_IF_MODE_SGMII_EN; + + if (duplex == DUPLEX_HALF) + if_mode |= ENETC_PCS_IF_MODE_DUPLEX_HALF; + + phy_write(pcs, ENETC_PCS_IF_MODE, if_mode); + phy_clear_bits(pcs, MII_BMCR, BMCR_ANENABLE); +} + +static void vsc9959_pcs_link_up(struct ocelot *ocelot, int port, + unsigned int link_an_mode, + phy_interface_t interface, + int speed, int duplex) +{ + struct felix *felix = ocelot_to_felix(ocelot); + struct phy_device *pcs = felix->pcs[port]; + + if (!pcs) + return; + + if (phylink_autoneg_inband(link_an_mode)) + return; + + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_QSGMII: + vsc9959_pcs_link_up_sgmii(pcs, link_an_mode, speed, duplex); + break; + case PHY_INTERFACE_MODE_2500BASEX: + vsc9959_pcs_link_up_2500basex(pcs, link_an_mode, speed, + duplex); + break; + case PHY_INTERFACE_MODE_USXGMII: + phydev_err(pcs, "USXGMII only supports in-band AN for now\n"); break; default: dev_err(ocelot->dev, "Unsupported link mode %s\n", @@ -1412,8 +1398,8 @@ struct felix_info felix_info_vsc9959 = { .imdio_pci_bar = 0, .mdio_bus_alloc = vsc9959_mdio_bus_alloc, .mdio_bus_free = vsc9959_mdio_bus_free, - .pcs_init = vsc9959_pcs_init, - .pcs_an_restart = vsc9959_pcs_an_restart, + .pcs_config = vsc9959_pcs_config, + .pcs_link_up = vsc9959_pcs_link_up, .pcs_link_state = vsc9959_pcs_link_state, .prevalidate_phy_mode = vsc9959_prevalidate_phy_mode, .port_setup_tc = vsc9959_port_setup_tc, diff --git a/include/linux/fsl/enetc_mdio.h b/include/linux/fsl/enetc_mdio.h index 4875dd38af7e..2d9203314865 100644 --- a/include/linux/fsl/enetc_mdio.h +++ b/include/linux/fsl/enetc_mdio.h @@ -15,6 +15,7 @@ #define ENETC_PCS_IF_MODE_SGMII_EN BIT(0) #define ENETC_PCS_IF_MODE_USE_SGMII_AN BIT(1) #define ENETC_PCS_IF_MODE_SGMII_SPEED(x) (((x) << 2) & GENMASK(3, 2)) +#define ENETC_PCS_IF_MODE_DUPLEX_HALF BIT(3) /* Not a mistake, the SerDes PLL needs to be set at 3.125 GHz by Reset * Configuration Word (RCW, outside Linux control) for 2.5G SGMII mode. The PCS |
