diff options
Diffstat (limited to 'drivers/net/dsa/microchip/ksz_common.c')
-rw-r--r-- | drivers/net/dsa/microchip/ksz_common.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index f492fa9f6dd4..f424b3d10781 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -2,7 +2,7 @@ /* * Microchip switch driver main logic * - * Copyright (C) 2017-2024 Microchip Technology Inc. + * Copyright (C) 2017-2025 Microchip Technology Inc. */ #include <linux/delay.h> @@ -408,12 +408,29 @@ static void ksz9477_phylink_mac_link_up(struct phylink_config *config, int speed, int duplex, bool tx_pause, bool rx_pause); +static struct phylink_pcs * +ksz_phylink_mac_select_pcs(struct phylink_config *config, + phy_interface_t interface) +{ + struct dsa_port *dp = dsa_phylink_to_port(config); + struct ksz_device *dev = dp->ds->priv; + struct ksz_port *p = &dev->ports[dp->index]; + + if (ksz_is_sgmii_port(dev, dp->index) && + (interface == PHY_INTERFACE_MODE_SGMII || + interface == PHY_INTERFACE_MODE_1000BASEX)) + return p->pcs; + + return NULL; +} + static const struct phylink_mac_ops ksz9477_phylink_mac_ops = { .mac_config = ksz_phylink_mac_config, .mac_link_down = ksz_phylink_mac_link_down, .mac_link_up = ksz9477_phylink_mac_link_up, .mac_disable_tx_lpi = ksz_phylink_mac_disable_tx_lpi, .mac_enable_tx_lpi = ksz_phylink_mac_enable_tx_lpi, + .mac_select_pcs = ksz_phylink_mac_select_pcs, }; static const struct ksz_dev_ops ksz9477_dev_ops = { @@ -451,6 +468,7 @@ static const struct ksz_dev_ops ksz9477_dev_ops = { .reset = ksz9477_reset_switch, .init = ksz9477_switch_init, .exit = ksz9477_switch_exit, + .pcs_create = ksz9477_pcs_create, }; static const struct phylink_mac_ops lan937x_phylink_mac_ops = { @@ -1093,8 +1111,7 @@ static const struct regmap_range ksz9477_valid_regs[] = { regmap_reg_range(0x701b, 0x701b), regmap_reg_range(0x701f, 0x7020), regmap_reg_range(0x7030, 0x7030), - regmap_reg_range(0x7200, 0x7203), - regmap_reg_range(0x7206, 0x7207), + regmap_reg_range(0x7200, 0x7207), regmap_reg_range(0x7300, 0x7301), regmap_reg_range(0x7400, 0x7401), regmap_reg_range(0x7403, 0x7403), @@ -1610,6 +1627,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { true, false, false}, .gbit_capable = {true, true, true, true, true, true, true}, .ptp_capable = true, + .sgmii_port = 7, .wr_table = &ksz9477_register_set, .rd_table = &ksz9477_register_set, }, @@ -2002,6 +2020,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { .internal_phy = {true, true, true, true, true, false, false}, .gbit_capable = {true, true, true, true, true, true, true}, + .sgmii_port = 7, .wr_table = &ksz9477_register_set, .rd_table = &ksz9477_register_set, }, @@ -2137,7 +2156,7 @@ void ksz_r_mib_stats64(struct ksz_device *dev, int port) spin_unlock(&mib->stats64_lock); - if (dev->info->phy_errata_9477) { + if (dev->info->phy_errata_9477 && !ksz_is_sgmii_port(dev, port)) { ret = ksz9477_errata_monitor(dev, port, raw->tx_late_col); if (ret) dev_err(dev->dev, "Failed to monitor transmission halt\n"); @@ -2845,6 +2864,12 @@ static int ksz_setup(struct dsa_switch *ds) if (ret) return ret; + if (ksz_has_sgmii_port(dev) && dev->dev_ops->pcs_create) { + ret = dev->dev_ops->pcs_create(dev); + if (ret) + return ret; + } + /* set broadcast storm protection 10% rate */ regmap_update_bits(ksz_regmap_16(dev), regs[S_BROADCAST_CTRL], BROADCAST_STORM_RATE, @@ -3692,6 +3717,10 @@ static void ksz_phylink_mac_config(struct phylink_config *config, if (dev->info->internal_phy[port]) return; + /* No need to configure XMII control register when using SGMII. */ + if (ksz_is_sgmii_port(dev, port)) + return; + if (phylink_autoneg_inband(mode)) { dev_err(dev->dev, "In-band AN not supported!\n"); return; |