diff options
author | Arun Ramadoss <arun.ramadoss@microchip.com> | 2022-07-24 14:58:17 +0530 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2022-07-27 09:39:17 +0100 |
commit | 8560664fd32aa055b3c128337356e32e8fc25b5a (patch) | |
tree | 72b84dcb58503632a3ae514b040a53133f00216e /drivers/net/dsa/microchip/ksz_common.c | |
parent | aa5b8b73d4bd34618508165bc0e5b7eb4b7c2c20 (diff) | |
download | linux-8560664fd32aa055b3c128337356e32e8fc25b5a.tar.bz2 |
net: dsa: microchip: add common duplex and flow control function
This patch add common function for configuring the Full/Half duplex and
transmit/receive flow control. KSZ8795 uses the Global control register
4 for configuring the duplex and flow control, whereas all other KSZ9477
based switch uses the xMII Control 0 register.
Signed-off-by: Arun Ramadoss <arun.ramadoss@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/microchip/ksz_common.c')
-rw-r--r-- | drivers/net/dsa/microchip/ksz_common.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 85392d3b1c2b..28c21f5a285f 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -281,11 +281,15 @@ static const u32 ksz8795_masks[] = { [DYNAMIC_MAC_TABLE_FID] = GENMASK(26, 20), [DYNAMIC_MAC_TABLE_SRC_PORT] = GENMASK(26, 24), [DYNAMIC_MAC_TABLE_TIMESTAMP] = GENMASK(28, 27), + [P_MII_TX_FLOW_CTRL] = BIT(5), + [P_MII_RX_FLOW_CTRL] = BIT(5), }; static const u8 ksz8795_xmii_ctrl0[] = { [P_MII_100MBIT] = 0, [P_MII_10MBIT] = 1, + [P_MII_FULL_DUPLEX] = 0, + [P_MII_HALF_DUPLEX] = 1, }; static const u8 ksz8795_xmii_ctrl1[] = { @@ -370,6 +374,8 @@ static const u16 ksz9477_regs[] = { static const u32 ksz9477_masks[] = { [ALU_STAT_WRITE] = 0, [ALU_STAT_READ] = 1, + [P_MII_TX_FLOW_CTRL] = BIT(5), + [P_MII_RX_FLOW_CTRL] = BIT(3), }; static const u8 ksz9477_shifts[] = { @@ -379,6 +385,8 @@ static const u8 ksz9477_shifts[] = { static const u8 ksz9477_xmii_ctrl0[] = { [P_MII_100MBIT] = 1, [P_MII_10MBIT] = 0, + [P_MII_FULL_DUPLEX] = 1, + [P_MII_HALF_DUPLEX] = 0, }; static const u8 ksz9477_xmii_ctrl1[] = { @@ -389,6 +397,8 @@ static const u8 ksz9477_xmii_ctrl1[] = { static const u32 lan937x_masks[] = { [ALU_STAT_WRITE] = 1, [ALU_STAT_READ] = 2, + [P_MII_TX_FLOW_CTRL] = BIT(5), + [P_MII_RX_FLOW_CTRL] = BIT(3), }; static const u8 lan937x_shifts[] = { @@ -1468,6 +1478,32 @@ void ksz_port_set_xmii_speed(struct ksz_device *dev, int port, int speed) ksz_set_100_10mbit(dev, port, speed); } +void ksz_duplex_flowctrl(struct ksz_device *dev, int port, int duplex, + bool tx_pause, bool rx_pause) +{ + const u8 *bitval = dev->info->xmii_ctrl0; + const u32 *masks = dev->info->masks; + const u16 *regs = dev->info->regs; + u8 mask; + u8 val; + + mask = P_MII_DUPLEX_M | masks[P_MII_TX_FLOW_CTRL] | + masks[P_MII_RX_FLOW_CTRL]; + + if (duplex == DUPLEX_FULL) + val = FIELD_PREP(P_MII_DUPLEX_M, bitval[P_MII_FULL_DUPLEX]); + else + val = FIELD_PREP(P_MII_DUPLEX_M, bitval[P_MII_HALF_DUPLEX]); + + if (tx_pause) + val |= masks[P_MII_TX_FLOW_CTRL]; + + if (rx_pause) + val |= masks[P_MII_RX_FLOW_CTRL]; + + ksz_prmw8(dev, port, regs[P_XMII_CTRL_0], mask, val); +} + static void ksz_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface, |