@@ -1439,6 +1439,127 @@ void ksz8_config_cpu_port(struct dsa_switch *ds)
1439
1439
}
1440
1440
}
1441
1441
1442
+ /**
1443
+ * ksz8_phy_port_link_up - Configures ports with integrated PHYs
1444
+ * @dev: The KSZ device instance.
1445
+ * @port: The port number to configure.
1446
+ * @duplex: The desired duplex mode.
1447
+ * @tx_pause: If true, enables transmit pause.
1448
+ * @rx_pause: If true, enables receive pause.
1449
+ *
1450
+ * Description:
1451
+ * The function configures flow control settings for a given port based on the
1452
+ * desired settings and current duplex mode.
1453
+ *
1454
+ * According to the KSZ8873 datasheet, the PORT_FORCE_FLOW_CTRL bit in the
1455
+ * Port Control 2 register (0x1A for Port 1, 0x22 for Port 2, 0x32 for Port 3)
1456
+ * determines how flow control is handled on the port:
1457
+ * "1 = will always enable full-duplex flow control on the port, regardless
1458
+ * of AN result.
1459
+ * 0 = full-duplex flow control is enabled based on AN result."
1460
+ *
1461
+ * This means that the flow control behavior depends on the state of this bit:
1462
+ * - If PORT_FORCE_FLOW_CTRL is set to 1, the switch will ignore AN results and
1463
+ * force flow control on the port.
1464
+ * - If PORT_FORCE_FLOW_CTRL is set to 0, the switch will enable or disable
1465
+ * flow control based on the AN results.
1466
+ *
1467
+ * However, there is a potential limitation in this configuration. It is
1468
+ * currently not possible to force disable flow control on a port if we still
1469
+ * advertise pause support. While such a configuration is not currently
1470
+ * supported by Linux, and may not make practical sense, it's important to be
1471
+ * aware of this limitation when working with the KSZ8873 and similar devices.
1472
+ */
1473
+ static void ksz8_phy_port_link_up (struct ksz_device * dev , int port , int duplex ,
1474
+ bool tx_pause , bool rx_pause )
1475
+ {
1476
+ const u16 * regs = dev -> info -> regs ;
1477
+ u8 sctrl = 0 ;
1478
+
1479
+ /* The KSZ8795 switch differs from the KSZ8873 by supporting
1480
+ * asymmetric pause control. However, since a single bit is used to
1481
+ * control both RX and TX pause, we can't enforce asymmetric pause
1482
+ * control - both TX and RX pause will be either enabled or disabled
1483
+ * together.
1484
+ *
1485
+ * If auto-negotiation is enabled, we usually allow the flow control to
1486
+ * be determined by the auto-negotiation process based on the
1487
+ * capabilities of both link partners. However, for KSZ8873, the
1488
+ * PORT_FORCE_FLOW_CTRL bit may be set by the hardware bootstrap,
1489
+ * ignoring the auto-negotiation result. Thus, even in auto-negotiation
1490
+ * mode, we need to ensure that the PORT_FORCE_FLOW_CTRL bit is
1491
+ * properly cleared.
1492
+ *
1493
+ * In the absence of pause auto-negotiation, we will enforce symmetric
1494
+ * pause control for both variants of switches - KSZ8873 and KSZ8795.
1495
+ *
1496
+ * Autoneg Pause Autoneg rx,tx PORT_FORCE_FLOW_CTRL
1497
+ * 1 1 x 0
1498
+ * 0 1 x 0 (flow control probably disabled)
1499
+ * x 0 1 1 (flow control force enabled)
1500
+ * 1 0 0 0 (flow control still depends on
1501
+ * aneg result due to hardware)
1502
+ * 0 0 0 0 (flow control probably disabled)
1503
+ */
1504
+ if (dev -> ports [port ].manual_flow && tx_pause )
1505
+ sctrl |= PORT_FORCE_FLOW_CTRL ;
1506
+
1507
+ ksz_prmw8 (dev , port , regs [P_STP_CTRL ], PORT_FORCE_FLOW_CTRL , sctrl );
1508
+ }
1509
+
1510
+ /**
1511
+ * ksz8_cpu_port_link_up - Configures the CPU port of the switch.
1512
+ * @dev: The KSZ device instance.
1513
+ * @speed: The desired link speed.
1514
+ * @duplex: The desired duplex mode.
1515
+ * @tx_pause: If true, enables transmit pause.
1516
+ * @rx_pause: If true, enables receive pause.
1517
+ *
1518
+ * Description:
1519
+ * The function configures flow control and speed settings for the CPU
1520
+ * port of the switch based on the desired settings, current duplex mode, and
1521
+ * speed.
1522
+ */
1523
+ static void ksz8_cpu_port_link_up (struct ksz_device * dev , int speed , int duplex ,
1524
+ bool tx_pause , bool rx_pause )
1525
+ {
1526
+ const u16 * regs = dev -> info -> regs ;
1527
+ u8 ctrl = 0 ;
1528
+
1529
+ /* SW_FLOW_CTRL, SW_HALF_DUPLEX, and SW_10_MBIT bits are bootstrappable
1530
+ * at least on KSZ8873. They can have different values depending on your
1531
+ * board setup.
1532
+ */
1533
+ if (tx_pause || rx_pause )
1534
+ ctrl |= SW_FLOW_CTRL ;
1535
+
1536
+ if (duplex == DUPLEX_HALF )
1537
+ ctrl |= SW_HALF_DUPLEX ;
1538
+
1539
+ /* This hardware only supports SPEED_10 and SPEED_100. For SPEED_10
1540
+ * we need to set the SW_10_MBIT bit. Otherwise, we can leave it 0.
1541
+ */
1542
+ if (speed == SPEED_10 )
1543
+ ctrl |= SW_10_MBIT ;
1544
+
1545
+ ksz_rmw8 (dev , regs [S_BROADCAST_CTRL ], SW_HALF_DUPLEX | SW_FLOW_CTRL |
1546
+ SW_10_MBIT , ctrl );
1547
+ }
1548
+
1549
+ void ksz8_phylink_mac_link_up (struct ksz_device * dev , int port ,
1550
+ unsigned int mode , phy_interface_t interface ,
1551
+ struct phy_device * phydev , int speed , int duplex ,
1552
+ bool tx_pause , bool rx_pause )
1553
+ {
1554
+ /* If the port is the CPU port, apply special handling. Only the CPU
1555
+ * port is configured via global registers.
1556
+ */
1557
+ if (dev -> cpu_port == port )
1558
+ ksz8_cpu_port_link_up (dev , speed , duplex , tx_pause , rx_pause );
1559
+ else if (dev -> info -> internal_phy [port ])
1560
+ ksz8_phy_port_link_up (dev , port , duplex , tx_pause , rx_pause );
1561
+ }
1562
+
1442
1563
static int ksz8_handle_global_errata (struct dsa_switch * ds )
1443
1564
{
1444
1565
struct ksz_device * dev = ds -> priv ;
@@ -1487,8 +1608,6 @@ int ksz8_setup(struct dsa_switch *ds)
1487
1608
*/
1488
1609
ds -> vlan_filtering_is_global = true;
1489
1610
1490
- ksz_cfg (dev , S_REPLACE_VID_CTRL , SW_FLOW_CTRL , true);
1491
-
1492
1611
/* Enable automatic fast aging when link changed detected. */
1493
1612
ksz_cfg (dev , S_LINK_AGING_CTRL , SW_LINK_AUTO_AGING , true);
1494
1613
0 commit comments