mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 18:43:33 +02:00
Merge branch 'net-dsa-mv88e6xxx-serdes-link-without-phy'
Chris Packham says: ==================== net: dsa: mv88e6xxx: serdes link without phy This small series gets my hardware into a working state. The key points are to make sure we don't force the link and that we ask the MAC for the link status. I also have updated my dts to say `phy-mode = "1000base-x";` and `managed = "in-band-status";` I've dropped the patch for the 88E6123 as it's a distraction and I lack hardware to do any proper testing with it. Earlier versions are on the mailing list if anyone wants to pick it up in the future. I notice there's a series for mv88e6393x circulating on the netdev mailing list. As patch #1 is adding a new device specific op either this series will need updating to cover the mv88e6393x or the mv88e6393x series will need updating for the new op depenting on which lands first. ==================== Link: https://lore.kernel.org/r/20201124043440.28400-1-chris.packham@alliedtelesis.co.nz Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
64088b2ac1
|
|
@ -727,8 +727,8 @@ static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
|
|||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
if ((!mv88e6xxx_port_ppu_updates(chip, port) ||
|
||||
mode == MLO_AN_FIXED) && ops->port_set_link)
|
||||
err = ops->port_set_link(chip, port, LINK_FORCED_DOWN);
|
||||
mode == MLO_AN_FIXED) && ops->port_sync_link)
|
||||
err = ops->port_sync_link(chip, port, mode, false);
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
|
||||
if (err)
|
||||
|
|
@ -768,8 +768,8 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (ops->port_set_link)
|
||||
err = ops->port_set_link(chip, port, LINK_FORCED_UP);
|
||||
if (ops->port_sync_link)
|
||||
err = ops->port_sync_link(chip, port, mode, true);
|
||||
}
|
||||
error:
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
|
|
@ -3210,6 +3210,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
|
|||
.phy_read = mv88e6185_phy_ppu_read,
|
||||
.phy_write = mv88e6185_phy_ppu_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||
|
|
@ -3249,6 +3250,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
|
|||
.phy_read = mv88e6185_phy_ppu_read,
|
||||
.phy_write = mv88e6185_phy_ppu_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6185_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_set_frame_mode = mv88e6085_port_set_frame_mode,
|
||||
.port_set_egress_floods = mv88e6185_port_set_egress_floods,
|
||||
|
|
@ -3261,6 +3263,9 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
|
|||
.stats_get_strings = mv88e6095_stats_get_strings,
|
||||
.stats_get_stats = mv88e6095_stats_get_stats,
|
||||
.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
|
||||
.serdes_power = mv88e6185_serdes_power,
|
||||
.serdes_get_lane = mv88e6185_serdes_get_lane,
|
||||
.serdes_pcs_get_state = mv88e6185_serdes_pcs_get_state,
|
||||
.ppu_enable = mv88e6185_g1_ppu_enable,
|
||||
.ppu_disable = mv88e6185_g1_ppu_disable,
|
||||
.reset = mv88e6185_g1_reset,
|
||||
|
|
@ -3279,6 +3284,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6185_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||
|
|
@ -3299,6 +3305,12 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
|
|||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
||||
.serdes_power = mv88e6185_serdes_power,
|
||||
.serdes_get_lane = mv88e6185_serdes_get_lane,
|
||||
.serdes_pcs_get_state = mv88e6185_serdes_pcs_get_state,
|
||||
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
|
||||
.serdes_irq_enable = mv88e6097_serdes_irq_enable,
|
||||
.serdes_irq_status = mv88e6097_serdes_irq_status,
|
||||
.pot_clear = mv88e6xxx_g2_pot_clear,
|
||||
.reset = mv88e6352_g1_reset,
|
||||
.rmu_disable = mv88e6085_g1_rmu_disable,
|
||||
|
|
@ -3317,6 +3329,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_set_frame_mode = mv88e6085_port_set_frame_mode,
|
||||
.port_set_egress_floods = mv88e6352_port_set_egress_floods,
|
||||
|
|
@ -3351,6 +3364,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
|
|||
.phy_read = mv88e6185_phy_ppu_read,
|
||||
.phy_write = mv88e6185_phy_ppu_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||
|
|
@ -3392,6 +3406,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6341_port_max_speed_mode,
|
||||
|
|
@ -3443,6 +3458,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||
|
|
@ -3484,6 +3500,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
|
|||
.phy_read = mv88e6165_phy_read,
|
||||
.phy_write = mv88e6165_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
|
|
@ -3518,6 +3535,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
|
@ -3560,6 +3578,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
|
@ -3611,6 +3630,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
|
@ -3653,6 +3673,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
|
@ -3706,6 +3727,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
|
|||
.phy_read = mv88e6185_phy_ppu_read,
|
||||
.phy_write = mv88e6185_phy_ppu_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6185_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_set_frame_mode = mv88e6085_port_set_frame_mode,
|
||||
.port_set_egress_floods = mv88e6185_port_set_egress_floods,
|
||||
|
|
@ -3723,6 +3745,9 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
|
|||
.set_egress_port = mv88e6095_g1_set_egress_port,
|
||||
.watchdog_ops = &mv88e6097_watchdog_ops,
|
||||
.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
|
||||
.serdes_power = mv88e6185_serdes_power,
|
||||
.serdes_get_lane = mv88e6185_serdes_get_lane,
|
||||
.serdes_pcs_get_state = mv88e6185_serdes_pcs_get_state,
|
||||
.set_cascade_port = mv88e6185_g1_set_cascade_port,
|
||||
.ppu_enable = mv88e6185_g1_ppu_enable,
|
||||
.ppu_disable = mv88e6185_g1_ppu_disable,
|
||||
|
|
@ -3743,6 +3768,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6390_port_max_speed_mode,
|
||||
|
|
@ -3802,6 +3828,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
|
||||
|
|
@ -3861,6 +3888,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6390_port_max_speed_mode,
|
||||
|
|
@ -3920,6 +3948,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
|
@ -3978,6 +4007,7 @@ static const struct mv88e6xxx_ops mv88e6250_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6250_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
|
@ -4015,6 +4045,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6390_port_max_speed_mode,
|
||||
|
|
@ -4076,6 +4107,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||
|
|
@ -4118,6 +4150,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||||
|
|
@ -4158,6 +4191,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6341_port_max_speed_mode,
|
||||
|
|
@ -4211,6 +4245,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
|
@ -4251,6 +4286,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
|
@ -4295,6 +4331,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
|
||||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||||
|
|
@ -4355,6 +4392,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6390_port_max_speed_mode,
|
||||
|
|
@ -4418,6 +4456,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
|||
.phy_read = mv88e6xxx_g2_smi_phy_read,
|
||||
.phy_write = mv88e6xxx_g2_smi_phy_write,
|
||||
.port_set_link = mv88e6xxx_port_set_link,
|
||||
.port_sync_link = mv88e6xxx_port_sync_link,
|
||||
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
|
||||
.port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
|
||||
.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
|
||||
|
|
|
|||
|
|
@ -417,6 +417,10 @@ struct mv88e6xxx_ops {
|
|||
*/
|
||||
int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link);
|
||||
|
||||
/* Synchronise the port link state with that of the SERDES
|
||||
*/
|
||||
int (*port_sync_link)(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup);
|
||||
|
||||
#define PAUSE_ON 1
|
||||
#define PAUSE_OFF 0
|
||||
|
||||
|
|
|
|||
|
|
@ -162,6 +162,42 @@ int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mv88e6xxx_port_sync_link(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup)
|
||||
{
|
||||
const struct mv88e6xxx_ops *ops = chip->info->ops;
|
||||
int err = 0;
|
||||
int link;
|
||||
|
||||
if (isup)
|
||||
link = LINK_FORCED_UP;
|
||||
else
|
||||
link = LINK_FORCED_DOWN;
|
||||
|
||||
if (ops->port_set_link)
|
||||
err = ops->port_set_link(chip, port, link);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int mv88e6185_port_sync_link(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup)
|
||||
{
|
||||
const struct mv88e6xxx_ops *ops = chip->info->ops;
|
||||
int err = 0;
|
||||
int link;
|
||||
|
||||
if (mode == MLO_AN_INBAND)
|
||||
link = LINK_UNFORCED;
|
||||
else if (isup)
|
||||
link = LINK_FORCED_UP;
|
||||
else
|
||||
link = LINK_FORCED_DOWN;
|
||||
|
||||
if (ops->port_set_link)
|
||||
err = ops->port_set_link(chip, port, link);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mv88e6xxx_port_set_speed_duplex(struct mv88e6xxx_chip *chip,
|
||||
int port, int speed, bool alt_bit,
|
||||
bool force_bit, int duplex)
|
||||
|
|
|
|||
|
|
@ -298,6 +298,9 @@ int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
|
|||
|
||||
int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link);
|
||||
|
||||
int mv88e6xxx_port_sync_link(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup);
|
||||
int mv88e6185_port_sync_link(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup);
|
||||
|
||||
int mv88e6065_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
|
||||
int speed, int duplex);
|
||||
int mv88e6185_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
|
||||
|
|
|
|||
|
|
@ -400,14 +400,16 @@ void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
|
|||
{
|
||||
u16 *p = _p;
|
||||
u16 reg;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
if (!mv88e6352_port_has_serdes(chip, port))
|
||||
return;
|
||||
|
||||
for (i = 0 ; i < 32; i++) {
|
||||
mv88e6352_serdes_read(chip, i, ®);
|
||||
p[i] = reg;
|
||||
err = mv88e6352_serdes_read(chip, i, ®);
|
||||
if (!err)
|
||||
p[i] = reg;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -428,6 +430,115 @@ u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
|
|||
return lane;
|
||||
}
|
||||
|
||||
int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
|
||||
bool up)
|
||||
{
|
||||
/* The serdes power can't be controlled on this switch chip but we need
|
||||
* to supply this function to avoid returning -EOPNOTSUPP in
|
||||
* mv88e6xxx_serdes_power_up/mv88e6xxx_serdes_power_down
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
|
||||
{
|
||||
/* There are no configurable serdes lanes on this switch chip but we
|
||||
* need to return non-zero so that callers of
|
||||
* mv88e6xxx_serdes_get_lane() know this is a serdes port.
|
||||
*/
|
||||
switch (chip->ports[port].cmode) {
|
||||
case MV88E6185_PORT_STS_CMODE_SERDES:
|
||||
case MV88E6185_PORT_STS_CMODE_1000BASE_X:
|
||||
return 0xff;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
|
||||
u8 lane, struct phylink_link_state *state)
|
||||
{
|
||||
int err;
|
||||
u16 status;
|
||||
|
||||
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
state->link = !!(status & MV88E6XXX_PORT_STS_LINK);
|
||||
|
||||
if (state->link) {
|
||||
state->duplex = status & MV88E6XXX_PORT_STS_DUPLEX ? DUPLEX_FULL : DUPLEX_HALF;
|
||||
|
||||
switch (status & MV88E6XXX_PORT_STS_SPEED_MASK) {
|
||||
case MV88E6XXX_PORT_STS_SPEED_1000:
|
||||
state->speed = SPEED_1000;
|
||||
break;
|
||||
case MV88E6XXX_PORT_STS_SPEED_100:
|
||||
state->speed = SPEED_100;
|
||||
break;
|
||||
case MV88E6XXX_PORT_STS_SPEED_10:
|
||||
state->speed = SPEED_10;
|
||||
break;
|
||||
default:
|
||||
dev_err(chip->dev, "invalid PHY speed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
state->duplex = DUPLEX_UNKNOWN;
|
||||
state->speed = SPEED_UNKNOWN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
|
||||
bool enable)
|
||||
{
|
||||
u8 cmode = chip->ports[port].cmode;
|
||||
|
||||
/* The serdes interrupts are enabled in the G2_INT_MASK register. We
|
||||
* need to return 0 to avoid returning -EOPNOTSUPP in
|
||||
* mv88e6xxx_serdes_irq_enable/mv88e6xxx_serdes_irq_disable
|
||||
*/
|
||||
switch (cmode) {
|
||||
case MV88E6185_PORT_STS_CMODE_SERDES:
|
||||
case MV88E6185_PORT_STS_CMODE_1000BASE_X:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static void mv88e6097_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
|
||||
{
|
||||
u16 status;
|
||||
int err;
|
||||
|
||||
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &status);
|
||||
if (err) {
|
||||
dev_err(chip->dev, "can't read port status: %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
dsa_port_phylink_mac_change(chip->ds, port, !!(status & MV88E6XXX_PORT_STS_LINK));
|
||||
}
|
||||
|
||||
irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
|
||||
u8 lane)
|
||||
{
|
||||
u8 cmode = chip->ports[port].cmode;
|
||||
|
||||
switch (cmode) {
|
||||
case MV88E6185_PORT_STS_CMODE_SERDES:
|
||||
case MV88E6185_PORT_STS_CMODE_1000BASE_X:
|
||||
mv88e6097_serdes_irq_link(chip, port);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
|
||||
{
|
||||
u8 cmode = chip->ports[port].cmode;
|
||||
|
|
@ -987,6 +1098,7 @@ void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
|
|||
u16 *p = _p;
|
||||
int lane;
|
||||
u16 reg;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
lane = mv88e6xxx_serdes_get_lane(chip, port);
|
||||
|
|
@ -994,8 +1106,9 @@ void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
|
|||
return;
|
||||
|
||||
for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
|
||||
mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
|
||||
mv88e6390_serdes_regs[i], ®);
|
||||
p[i] = reg;
|
||||
err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
|
||||
mv88e6390_serdes_regs[i], ®);
|
||||
if (!err)
|
||||
p[i] = reg;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
#define MV88E6390_PG_CONTROL 0xf010
|
||||
#define MV88E6390_PG_CONTROL_ENABLE_PC BIT(0)
|
||||
|
||||
u8 mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
|
||||
u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
|
||||
u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
|
||||
u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
|
||||
|
|
@ -85,6 +86,8 @@ int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
|
|||
u8 lane, unsigned int mode,
|
||||
phy_interface_t interface,
|
||||
const unsigned long *advertise);
|
||||
int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
|
||||
u8 lane, struct phylink_link_state *state);
|
||||
int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
|
||||
u8 lane, struct phylink_link_state *state);
|
||||
int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
|
||||
|
|
@ -101,14 +104,20 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
|
|||
int port);
|
||||
unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
|
||||
int port);
|
||||
int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
|
||||
bool up);
|
||||
int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
|
||||
bool on);
|
||||
int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
|
||||
bool on);
|
||||
int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
|
||||
bool enable);
|
||||
int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
|
||||
bool enable);
|
||||
int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
|
||||
bool enable);
|
||||
irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
|
||||
u8 lane);
|
||||
irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
|
||||
u8 lane);
|
||||
irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user