Lines Matching +full:port +full:- +full:mapping +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2019-2024 Microchip Technology Inc.
21 /* marker for ports without built-in PHY */
25 * lan9370_phy_addr - Mapping of LAN9370 switch ports to PHY addresses.
27 * Each entry corresponds to a specific port on the LAN9370 switch,
28 * where ports 1-4 are connected to integrated 100BASE-T1 PHYs, and
29 * Port 5 is connected to an RGMII interface without a PHY. The values
33 [0] = 2, /* Port 1, T1 AFE0 */
34 [1] = 3, /* Port 2, T1 AFE1 */
35 [2] = 5, /* Port 3, T1 AFE3 */
36 [3] = 6, /* Port 4, T1 AFE4 */
37 [4] = LAN937X_NO_PHY, /* Port 5, RGMII 2 */
41 * lan9371_phy_addr - Mapping of LAN9371 switch ports to PHY addresses.
46 [0] = 2, /* Port 1, T1 AFE0 */
47 [1] = 3, /* Port 2, T1 AFE1 */
48 [2] = 5, /* Port 3, T1 AFE3 */
49 [3] = 8, /* Port 4, TX PHY */
50 [4] = LAN937X_NO_PHY, /* Port 5, RGMII 2 */
51 [5] = LAN937X_NO_PHY, /* Port 6, RGMII 1 */
55 * lan9372_phy_addr - Mapping of LAN9372 switch ports to PHY addresses.
60 [0] = 2, /* Port 1, T1 AFE0 */
61 [1] = 3, /* Port 2, T1 AFE1 */
62 [2] = 5, /* Port 3, T1 AFE3 */
63 [3] = 8, /* Port 4, TX PHY */
64 [4] = LAN937X_NO_PHY, /* Port 5, RGMII 2 */
65 [5] = LAN937X_NO_PHY, /* Port 6, RGMII 1 */
66 [6] = 6, /* Port 7, T1 AFE4 */
67 [7] = 4, /* Port 8, T1 AFE2 */
71 * lan9373_phy_addr - Mapping of LAN9373 switch ports to PHY addresses.
76 [0] = 2, /* Port 1, T1 AFE0 */
77 [1] = 3, /* Port 2, T1 AFE1 */
78 [2] = 5, /* Port 3, T1 AFE3 */
79 [3] = LAN937X_NO_PHY, /* Port 4, SGMII */
80 [4] = LAN937X_NO_PHY, /* Port 5, RGMII 2 */
81 [5] = LAN937X_NO_PHY, /* Port 6, RGMII 1 */
82 [6] = 6, /* Port 7, T1 AFE4 */
83 [7] = 4, /* Port 8, T1 AFE2 */
87 * lan9374_phy_addr - Mapping of LAN9374 switch ports to PHY addresses.
92 [0] = 2, /* Port 1, T1 AFE0 */
93 [1] = 3, /* Port 2, T1 AFE1 */
94 [2] = 5, /* Port 3, T1 AFE3 */
95 [3] = 7, /* Port 4, T1 AFE5 */
96 [4] = LAN937X_NO_PHY, /* Port 5, RGMII 2 */
97 [5] = LAN937X_NO_PHY, /* Port 6, RGMII 1 */
98 [6] = 6, /* Port 7, T1 AFE4 */
99 [7] = 4, /* Port 8, T1 AFE2 */
107 static int lan937x_port_cfg(struct ksz_device *dev, int port, int offset, in lan937x_port_cfg() argument
110 return regmap_update_bits(ksz_regmap_8(dev), PORT_CTRL_ADDR(port, offset), in lan937x_port_cfg()
115 * lan937x_create_phy_addr_map - Create port-to-PHY address map for MDIO bus.
119 * This function sets up the PHY address mapping for the LAN937x switches,
121 * 1. **SPI Access**: A straightforward one-to-one port-to-PHY address
122 * mapping is applied.
123 * 2. **MDIO Access**: The PHY address mapping varies based on chip variant
127 * https://microchip.my.site.com/s/article/LAN9374-Virtual-PHY-PHY-Address-Mapping
130 * simple direct mapping (port number = PHY address) is applied. If side MDIO
134 * The appropriate mapping table is selected based on the chip ID, and the
135 * `phy_addr_map` is populated with the correct addresses for each port. Any
136 * port with no PHY is assigned a `LAN937X_NO_PHY` marker.
149 /* simple direct mapping */ in lan937x_create_phy_addr_map()
150 for (i = 0; i < dev->info->port_cnt; i++) in lan937x_create_phy_addr_map()
151 dev->phy_addr_map[i] = i; in lan937x_create_phy_addr_map()
169 switch (dev->info->chip_id) { in lan937x_create_phy_addr_map()
191 return -EINVAL; in lan937x_create_phy_addr_map()
194 if (size < dev->info->port_cnt) in lan937x_create_phy_addr_map()
195 return -EINVAL; in lan937x_create_phy_addr_map()
197 for (i = 0; i < dev->info->port_cnt; i++) { in lan937x_create_phy_addr_map()
199 dev->phy_addr_map[i] = phy_addr_map[i]; in lan937x_create_phy_addr_map()
201 dev->phy_addr_map[i] = phy_addr_map[i] + offset; in lan937x_create_phy_addr_map()
208 * lan937x_mdio_bus_preinit - Pre-initialize MDIO bus for accessing PHYs.
214 * mode.
249 dev_err(dev->dev, "failed to preinit the MDIO bus\n"); in lan937x_mdio_bus_preinit()
262 /* get register address based on the logical port */ in lan937x_vphy_ind_addr_wr()
274 /* Check for internal phy port */ in lan937x_internal_phy_write()
275 if (!dev->info->internal_phy[addr]) in lan937x_internal_phy_write()
276 return -EOPNOTSUPP; in lan937x_internal_phy_write()
297 dev_err(dev->dev, "Failed to write phy register\n"); in lan937x_internal_phy_write()
310 /* Check for internal phy port, return 0xffff for non-existent phy */ in lan937x_internal_phy_read()
311 if (!dev->info->internal_phy[addr]) in lan937x_internal_phy_read()
327 dev_err(dev->dev, "Failed to read phy register\n"); in lan937x_internal_phy_read()
376 void lan937x_port_setup(struct ksz_device *dev, int port, bool cpu_port) in lan937x_port_setup() argument
378 const u32 *masks = dev->info->masks; in lan937x_port_setup()
379 const u16 *regs = dev->info->regs; in lan937x_port_setup()
380 struct dsa_switch *ds = dev->ds; in lan937x_port_setup()
383 /* enable tag tail for host port */ in lan937x_port_setup()
385 lan937x_port_cfg(dev, port, REG_PORT_CTRL_0, in lan937x_port_setup()
388 /* Enable the Port Queue split */ in lan937x_port_setup()
389 ksz9477_port_queue_split(dev, port); in lan937x_port_setup()
392 lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_1, PORT_BACK_PRESSURE, in lan937x_port_setup()
396 lan937x_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_PRIO_ENABLE, true); in lan937x_port_setup()
398 if (!dev->info->internal_phy[port]) in lan937x_port_setup()
399 lan937x_port_cfg(dev, port, regs[P_XMII_CTRL_0], in lan937x_port_setup()
407 member = BIT(dsa_upstream_port(ds, port)); in lan937x_port_setup()
409 dev->dev_ops->cfg_port_member(dev, port, member); in lan937x_port_setup()
414 struct ksz_device *dev = ds->priv; in lan937x_config_cpu_port()
418 if (dev->info->cpu_ports & (1 << dp->index)) { in lan937x_config_cpu_port()
419 dev->cpu_port = dp->index; in lan937x_config_cpu_port()
421 /* enable cpu port */ in lan937x_config_cpu_port()
422 lan937x_port_setup(dev, dp->index, true); in lan937x_config_cpu_port()
427 ksz_port_stp_state_set(ds, dp->index, BR_STATE_DISABLED); in lan937x_config_cpu_port()
431 int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu) in lan937x_change_mtu() argument
433 struct dsa_switch *ds = dev->ds; in lan937x_change_mtu()
438 if (dsa_is_cpu_port(ds, port)) in lan937x_change_mtu()
442 ret = lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_0, in lan937x_change_mtu()
445 ret = lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_0, in lan937x_change_mtu()
448 dev_err(ds->dev, "failed to enable jumbo\n"); in lan937x_change_mtu()
453 ret = ksz_pwrite16(dev, port, PORT_MAX_FR_SIZE, new_mtu); in lan937x_change_mtu()
455 dev_err(ds->dev, "failed to update mtu for port %d\n", port); in lan937x_change_mtu()
470 #define MAX_TIMER_VAL ((1 << 20) - 1) in lan937x_set_ageing_time()
472 /* The aging timer comprises a 3-bit multiplier and a 20-bit second in lan937x_set_ageing_time()
488 return -EINVAL; in lan937x_set_ageing_time()
535 static void lan937x_set_tune_adj(struct ksz_device *dev, int port, in lan937x_set_tune_adj() argument
540 ksz_pread16(dev, port, reg, &data16); in lan937x_set_tune_adj()
544 ksz_pwrite16(dev, port, reg, data16); in lan937x_set_tune_adj()
548 ksz_pwrite16(dev, port, reg, data16); in lan937x_set_tune_adj()
551 static void lan937x_set_rgmii_tx_delay(struct ksz_device *dev, int port) in lan937x_set_rgmii_tx_delay() argument
558 val = (port == LAN937X_RGMII_1_PORT) ? RGMII_1_TX_DELAY_2NS : in lan937x_set_rgmii_tx_delay()
561 lan937x_set_tune_adj(dev, port, REG_PORT_XMII_CTRL_5, val); in lan937x_set_rgmii_tx_delay()
564 static void lan937x_set_rgmii_rx_delay(struct ksz_device *dev, int port) in lan937x_set_rgmii_rx_delay() argument
568 val = (port == LAN937X_RGMII_1_PORT) ? RGMII_1_RX_DELAY_2NS : in lan937x_set_rgmii_rx_delay()
571 lan937x_set_tune_adj(dev, port, REG_PORT_XMII_CTRL_4, val); in lan937x_set_rgmii_rx_delay()
574 void lan937x_phylink_get_caps(struct ksz_device *dev, int port, in lan937x_phylink_get_caps() argument
577 config->mac_capabilities = MAC_100FD; in lan937x_phylink_get_caps()
579 if (dev->info->supports_rgmii[port]) { in lan937x_phylink_get_caps()
581 config->mac_capabilities |= MAC_ASYM_PAUSE | MAC_SYM_PAUSE | in lan937x_phylink_get_caps()
583 } else if (is_lan937x_tx_phy(dev, port)) { in lan937x_phylink_get_caps()
584 config->mac_capabilities |= MAC_ASYM_PAUSE | MAC_SYM_PAUSE | in lan937x_phylink_get_caps()
589 void lan937x_setup_rgmii_delay(struct ksz_device *dev, int port) in lan937x_setup_rgmii_delay() argument
591 struct ksz_port *p = &dev->ports[port]; in lan937x_setup_rgmii_delay()
593 if (p->rgmii_tx_val) { in lan937x_setup_rgmii_delay()
594 lan937x_set_rgmii_tx_delay(dev, port); in lan937x_setup_rgmii_delay()
595 dev_info(dev->dev, "Applied rgmii tx delay for the port %d\n", in lan937x_setup_rgmii_delay()
596 port); in lan937x_setup_rgmii_delay()
599 if (p->rgmii_rx_val) { in lan937x_setup_rgmii_delay()
600 lan937x_set_rgmii_rx_delay(dev, port); in lan937x_setup_rgmii_delay()
601 dev_info(dev->dev, "Applied rgmii rx delay for the port %d\n", in lan937x_setup_rgmii_delay()
602 port); in lan937x_setup_rgmii_delay()
606 int lan937x_tc_cbs_set_cinc(struct ksz_device *dev, int port, u32 val) in lan937x_tc_cbs_set_cinc() argument
608 return ksz_pwrite32(dev, port, REG_PORT_MTI_CREDIT_INCREMENT, val); in lan937x_tc_cbs_set_cinc()
613 dev->port_mask = (1 << dev->info->port_cnt) - 1; in lan937x_switch_init()
620 struct ksz_device *dev = ds->priv; in lan937x_setup()
626 ds->vlan_filtering_is_global = true; in lan937x_setup()
628 /* Enable aggressive back off for half duplex & UNH mode */ in lan937x_setup()