^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (c) 2019 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * +----------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * GMAC1----RGMII----|--MAC0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * \---MDIO1----|--REGs |----MDIO3----\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * | | | +------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * | | +--| |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * | MAC1-|----RMII--M-----| PHY0 |-o P0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * | | | | +------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * | | | +--| |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * | MAC2-|----RMII--------| PHY1 |-o P1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * | | | | +------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * | | | +--| |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * | MAC3-|----RMII--------| PHY2 |-o P2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * | | | | +------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * | | | +--| |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * | MAC4-|----RMII--------| PHY3 |-o P3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * | | | | +------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * | | | +--| |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * | MAC5-|--+-RMII--M-----|-PHY4-|-o P4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * | | | | +------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * +----------------------+ | \--CFG_SW_PHY_SWAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * GMAC0---------------RMII--------------------/ \-CFG_SW_PHY_ADDR_SWAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * \---MDIO0--NC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * GMAC0 and MAC5 are connected together and use same PHY. Depending on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * configuration it can be PHY4 (default) or PHY0. Only GMAC0 or MAC5 can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * used at same time. If GMAC0 is used (default) then MAC5 should be disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * CFG_SW_PHY_SWAP - swap connections of PHY0 and PHY4. If this bit is not set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * PHY4 is connected to GMAC0/MAC5 bundle and PHY0 is connected to MAC1. If this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * bit is set, PHY4 is connected to MAC1 and PHY0 is connected to GMAC0/MAC5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * bundle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * CFG_SW_PHY_ADDR_SWAP - swap addresses of PHY0 and PHY4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * CFG_SW_PHY_SWAP and CFG_SW_PHY_ADDR_SWAP are part of SoC specific register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * set and not related to switch internal registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/of_mdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <net/dsa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define AR9331_SW_NAME "ar9331_switch"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define AR9331_SW_PORTS 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* dummy reg to change page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define AR9331_SW_REG_PAGE 0x40000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* Global Interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define AR9331_SW_REG_GINT 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define AR9331_SW_REG_GINT_MASK 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define AR9331_SW_GINT_PHY_INT BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define AR9331_SW_REG_FLOOD_MASK 0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define AR9331_SW_FLOOD_MASK_BROAD_TO_CPU BIT(26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define AR9331_SW_REG_GLOBAL_CTRL 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define AR9331_SW_GLOBAL_CTRL_MFS_M GENMASK(13, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define AR9331_SW_REG_MDIO_CTRL 0x98
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define AR9331_SW_MDIO_CTRL_BUSY BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define AR9331_SW_MDIO_CTRL_MASTER_EN BIT(30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define AR9331_SW_MDIO_CTRL_CMD_READ BIT(27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define AR9331_SW_MDIO_CTRL_PHY_ADDR_M GENMASK(25, 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define AR9331_SW_MDIO_CTRL_REG_ADDR_M GENMASK(20, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define AR9331_SW_MDIO_CTRL_DATA_M GENMASK(16, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define AR9331_SW_REG_PORT_STATUS(_port) (0x100 + (_port) * 0x100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* FLOW_LINK_EN - enable mac flow control config auto-neg with phy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * If not set, mac can be config by software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define AR9331_SW_PORT_STATUS_FLOW_LINK_EN BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* LINK_EN - If set, MAC is configured from PHY link status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * If not set, MAC should be configured by software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define AR9331_SW_PORT_STATUS_LINK_EN BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define AR9331_SW_PORT_STATUS_DUPLEX_MODE BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define AR9331_SW_PORT_STATUS_RX_FLOW_EN BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define AR9331_SW_PORT_STATUS_TX_FLOW_EN BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define AR9331_SW_PORT_STATUS_RXMAC BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define AR9331_SW_PORT_STATUS_TXMAC BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define AR9331_SW_PORT_STATUS_SPEED_M GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define AR9331_SW_PORT_STATUS_SPEED_1000 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define AR9331_SW_PORT_STATUS_SPEED_100 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define AR9331_SW_PORT_STATUS_SPEED_10 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define AR9331_SW_PORT_STATUS_MAC_MASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) (AR9331_SW_PORT_STATUS_TXMAC | AR9331_SW_PORT_STATUS_RXMAC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define AR9331_SW_PORT_STATUS_LINK_MASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) (AR9331_SW_PORT_STATUS_DUPLEX_MODE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) AR9331_SW_PORT_STATUS_RX_FLOW_EN | AR9331_SW_PORT_STATUS_TX_FLOW_EN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) AR9331_SW_PORT_STATUS_SPEED_M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Phy bypass mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * ------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * Bit: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * real | start | OP | PhyAddr | Reg Addr | TA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * atheros| start | OP | 2'b00 |PhyAdd[2:0]| Reg Addr[4:0] | TA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * Bit: |16 |17 |18 |19 |20 |21 |22 |23 |24 |25 |26 |27 |28 |29 |30 |31 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * real | Data |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * atheros| Data |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * ------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * Page address mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * ------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * Bit: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * real | start | OP | PhyAddr | Reg Addr | TA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * atheros| start | OP | 2'b11 | 8'b0 | TA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * Bit: |16 |17 |18 |19 |20 |21 |22 |23 |24 |25 |26 |27 |28 |29 |30 |31 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * real | Data |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * atheros| | Page [9:0] |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* In case of Page Address mode, Bit[18:9] of 32 bit register address should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * written to bits[9:0] of mdio data register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define AR9331_SW_ADDR_PAGE GENMASK(18, 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* ------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Normal register access mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * ------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * Bit: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * real | start | OP | PhyAddr | Reg Addr | TA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * atheros| start | OP | 2'b10 | low_addr[7:0] | TA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * Bit: |16 |17 |18 |19 |20 |21 |22 |23 |24 |25 |26 |27 |28 |29 |30 |31 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * real | Data |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * atheros| Data |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * ------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define AR9331_SW_LOW_ADDR_PHY GENMASK(8, 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define AR9331_SW_LOW_ADDR_REG GENMASK(5, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define AR9331_SW_MDIO_PHY_MODE_M GENMASK(4, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define AR9331_SW_MDIO_PHY_MODE_PAGE 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define AR9331_SW_MDIO_PHY_MODE_REG 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define AR9331_SW_MDIO_PHY_MODE_BYPASS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define AR9331_SW_MDIO_PHY_ADDR_M GENMASK(2, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* Empirical determined values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define AR9331_SW_MDIO_POLL_SLEEP_US 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define AR9331_SW_MDIO_POLL_TIMEOUT_US 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct ar9331_sw_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct dsa_switch ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct dsa_switch_ops ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct irq_domain *irqdomain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) u32 irq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct mutex lock_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct mii_bus *mbus; /* mdio master */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct mii_bus *sbus; /* mdio slave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct reset_control *sw_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* Warning: switch reset will reset last AR9331_SW_MDIO_PHY_MODE_PAGE request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * If some kind of optimization is used, the request should be repeated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static int ar9331_sw_reset(struct ar9331_sw_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ret = reset_control_assert(priv->sw_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* AR9331 doc do not provide any information about proper reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * sequence. The AR8136 (the closes switch to the AR9331) doc says:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * reset duration should be greater than 10ms. So, let's use this value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) usleep_range(10000, 15000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ret = reset_control_deassert(priv->sw_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* There is no information on how long should we wait after reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * AR8136 has an EEPROM and there is an Interrupt for EEPROM load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * status. AR9331 has no EEPROM support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * For now, do not wait. In case AR8136 will be needed, the after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * reset delay can be added as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) dev_err_ratelimited(priv->dev, "%s: %i\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static int ar9331_sw_mbus_write(struct mii_bus *mbus, int port, int regnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct ar9331_sw_priv *priv = mbus->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct regmap *regmap = priv->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ret = regmap_write(regmap, AR9331_SW_REG_MDIO_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) AR9331_SW_MDIO_CTRL_BUSY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) AR9331_SW_MDIO_CTRL_MASTER_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) FIELD_PREP(AR9331_SW_MDIO_CTRL_PHY_ADDR_M, port) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) FIELD_PREP(AR9331_SW_MDIO_CTRL_REG_ADDR_M, regnum) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) FIELD_PREP(AR9331_SW_MDIO_CTRL_DATA_M, data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ret = regmap_read_poll_timeout(regmap, AR9331_SW_REG_MDIO_CTRL, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) !(val & AR9331_SW_MDIO_CTRL_BUSY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) AR9331_SW_MDIO_POLL_SLEEP_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) AR9331_SW_MDIO_POLL_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) dev_err_ratelimited(priv->dev, "PHY write error: %i\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int ar9331_sw_mbus_read(struct mii_bus *mbus, int port, int regnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct ar9331_sw_priv *priv = mbus->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct regmap *regmap = priv->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) ret = regmap_write(regmap, AR9331_SW_REG_MDIO_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) AR9331_SW_MDIO_CTRL_BUSY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) AR9331_SW_MDIO_CTRL_MASTER_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) AR9331_SW_MDIO_CTRL_CMD_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) FIELD_PREP(AR9331_SW_MDIO_CTRL_PHY_ADDR_M, port) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) FIELD_PREP(AR9331_SW_MDIO_CTRL_REG_ADDR_M, regnum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) ret = regmap_read_poll_timeout(regmap, AR9331_SW_REG_MDIO_CTRL, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) !(val & AR9331_SW_MDIO_CTRL_BUSY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) AR9331_SW_MDIO_POLL_SLEEP_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) AR9331_SW_MDIO_POLL_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ret = regmap_read(regmap, AR9331_SW_REG_MDIO_CTRL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return FIELD_GET(AR9331_SW_MDIO_CTRL_DATA_M, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) dev_err_ratelimited(priv->dev, "PHY read error: %i\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static int ar9331_sw_mbus_init(struct ar9331_sw_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct device *dev = priv->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct mii_bus *mbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct device_node *np, *mnp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) mbus = devm_mdiobus_alloc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (!mbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) mbus->name = np->full_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) snprintf(mbus->id, MII_BUS_ID_SIZE, "%pOF", np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) mbus->read = ar9331_sw_mbus_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) mbus->write = ar9331_sw_mbus_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) mbus->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) mbus->parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) mnp = of_get_child_by_name(np, "mdio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (!mnp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ret = devm_of_mdiobus_register(dev, mbus, mnp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) of_node_put(mnp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) priv->mbus = mbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static int ar9331_sw_setup(struct dsa_switch *ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct ar9331_sw_priv *priv = (struct ar9331_sw_priv *)ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct regmap *regmap = priv->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ret = ar9331_sw_reset(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* Reset will set proper defaults. CPU - Port0 will be enabled and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * configured. All other ports (ports 1 - 5) are disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ret = ar9331_sw_mbus_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* Do not drop broadcast frames */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ret = regmap_write_bits(regmap, AR9331_SW_REG_FLOOD_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) AR9331_SW_FLOOD_MASK_BROAD_TO_CPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) AR9331_SW_FLOOD_MASK_BROAD_TO_CPU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* Set max frame size to the maximum supported value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ret = regmap_write_bits(regmap, AR9331_SW_REG_GLOBAL_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) AR9331_SW_GLOBAL_CTRL_MFS_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) AR9331_SW_GLOBAL_CTRL_MFS_M);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dev_err_ratelimited(priv->dev, "%s: %i\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static void ar9331_sw_port_disable(struct dsa_switch *ds, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct ar9331_sw_priv *priv = (struct ar9331_sw_priv *)ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct regmap *regmap = priv->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ret = regmap_write(regmap, AR9331_SW_REG_PORT_STATUS(port), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) dev_err_ratelimited(priv->dev, "%s: %i\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static enum dsa_tag_protocol ar9331_sw_get_tag_protocol(struct dsa_switch *ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) enum dsa_tag_protocol m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return DSA_TAG_PROTO_AR9331;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static void ar9331_sw_phylink_validate(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) unsigned long *supported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct phylink_link_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) switch (port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (state->interface != PHY_INTERFACE_MODE_GMII)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) goto unsupported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) phylink_set(mask, 1000baseT_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) phylink_set(mask, 1000baseT_Half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) goto unsupported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) dev_err(ds->dev, "Unsupported port: %i\n", port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) phylink_set_port_modes(mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) phylink_set(mask, Pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) phylink_set(mask, Asym_Pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) phylink_set(mask, 10baseT_Half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) phylink_set(mask, 10baseT_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) phylink_set(mask, 100baseT_Half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) phylink_set(mask, 100baseT_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) bitmap_and(supported, supported, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) __ETHTOOL_LINK_MODE_MASK_NBITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) bitmap_and(state->advertising, state->advertising, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) __ETHTOOL_LINK_MODE_MASK_NBITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) unsupported:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) dev_err(ds->dev, "Unsupported interface: %d, port: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) state->interface, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static void ar9331_sw_phylink_mac_config(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) unsigned int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) const struct phylink_link_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct ar9331_sw_priv *priv = (struct ar9331_sw_priv *)ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct regmap *regmap = priv->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ret = regmap_update_bits(regmap, AR9331_SW_REG_PORT_STATUS(port),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) AR9331_SW_PORT_STATUS_LINK_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) AR9331_SW_PORT_STATUS_FLOW_LINK_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) dev_err_ratelimited(priv->dev, "%s: %i\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static void ar9331_sw_phylink_mac_link_down(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) unsigned int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) phy_interface_t interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct ar9331_sw_priv *priv = (struct ar9331_sw_priv *)ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct regmap *regmap = priv->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ret = regmap_update_bits(regmap, AR9331_SW_REG_PORT_STATUS(port),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) AR9331_SW_PORT_STATUS_MAC_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) dev_err_ratelimited(priv->dev, "%s: %i\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static void ar9331_sw_phylink_mac_link_up(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) unsigned int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) phy_interface_t interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) int speed, int duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) bool tx_pause, bool rx_pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct ar9331_sw_priv *priv = (struct ar9331_sw_priv *)ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct regmap *regmap = priv->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) val = AR9331_SW_PORT_STATUS_MAC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) switch (speed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) case SPEED_1000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) val |= AR9331_SW_PORT_STATUS_SPEED_1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) case SPEED_100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) val |= AR9331_SW_PORT_STATUS_SPEED_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) case SPEED_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) val |= AR9331_SW_PORT_STATUS_SPEED_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (duplex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) val |= AR9331_SW_PORT_STATUS_DUPLEX_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (tx_pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) val |= AR9331_SW_PORT_STATUS_TX_FLOW_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (rx_pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) val |= AR9331_SW_PORT_STATUS_RX_FLOW_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ret = regmap_update_bits(regmap, AR9331_SW_REG_PORT_STATUS(port),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) AR9331_SW_PORT_STATUS_MAC_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) AR9331_SW_PORT_STATUS_LINK_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) dev_err_ratelimited(priv->dev, "%s: %i\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static const struct dsa_switch_ops ar9331_sw_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) .get_tag_protocol = ar9331_sw_get_tag_protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) .setup = ar9331_sw_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) .port_disable = ar9331_sw_port_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) .phylink_validate = ar9331_sw_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .phylink_mac_config = ar9331_sw_phylink_mac_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .phylink_mac_link_down = ar9331_sw_phylink_mac_link_down,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) .phylink_mac_link_up = ar9331_sw_phylink_mac_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static irqreturn_t ar9331_sw_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct ar9331_sw_priv *priv = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct regmap *regmap = priv->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) u32 stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ret = regmap_read(regmap, AR9331_SW_REG_GINT, &stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) dev_err(priv->dev, "can't read interrupt status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (!stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (stat & AR9331_SW_GINT_PHY_INT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) int child_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) child_irq = irq_find_mapping(priv->irqdomain, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) handle_nested_irq(child_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) ret = regmap_write(regmap, AR9331_SW_REG_GINT, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dev_err(priv->dev, "can't write interrupt status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static void ar9331_sw_mask_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct ar9331_sw_priv *priv = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) priv->irq_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static void ar9331_sw_unmask_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct ar9331_sw_priv *priv = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) priv->irq_mask = AR9331_SW_GINT_PHY_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static void ar9331_sw_irq_bus_lock(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct ar9331_sw_priv *priv = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) mutex_lock(&priv->lock_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static void ar9331_sw_irq_bus_sync_unlock(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct ar9331_sw_priv *priv = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) struct regmap *regmap = priv->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ret = regmap_update_bits(regmap, AR9331_SW_REG_GINT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) AR9331_SW_GINT_PHY_INT, priv->irq_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) dev_err(priv->dev, "failed to change IRQ mask\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) mutex_unlock(&priv->lock_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static struct irq_chip ar9331_sw_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .name = AR9331_SW_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .irq_mask = ar9331_sw_mask_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) .irq_unmask = ar9331_sw_unmask_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .irq_bus_lock = ar9331_sw_irq_bus_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .irq_bus_sync_unlock = ar9331_sw_irq_bus_sync_unlock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static int ar9331_sw_irq_map(struct irq_domain *domain, unsigned int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) irq_hw_number_t hwirq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) irq_set_chip_data(irq, domain->host_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) irq_set_chip_and_handler(irq, &ar9331_sw_irq_chip, handle_simple_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) irq_set_nested_thread(irq, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) irq_set_noprobe(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static void ar9331_sw_irq_unmap(struct irq_domain *d, unsigned int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) irq_set_nested_thread(irq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) irq_set_chip_and_handler(irq, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) irq_set_chip_data(irq, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static const struct irq_domain_ops ar9331_sw_irqdomain_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .map = ar9331_sw_irq_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .unmap = ar9331_sw_irq_unmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .xlate = irq_domain_xlate_onecell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static int ar9331_sw_irq_init(struct ar9331_sw_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct device_node *np = priv->dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct device *dev = priv->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) int ret, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) irq = of_irq_get(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) dev_err(dev, "failed to get parent IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return irq ? irq : -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) mutex_init(&priv->lock_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ret = devm_request_threaded_irq(dev, irq, NULL, ar9331_sw_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) IRQF_ONESHOT, AR9331_SW_NAME, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) dev_err(dev, "unable to request irq: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) priv->irqdomain = irq_domain_add_linear(np, 1, &ar9331_sw_irqdomain_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (!priv->irqdomain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) dev_err(dev, "failed to create IRQ domain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) irq_set_parent(irq_create_mapping(priv->irqdomain, 0), irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static int __ar9331_mdio_write(struct mii_bus *sbus, u8 mode, u16 reg, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) u8 r, p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) p = FIELD_PREP(AR9331_SW_MDIO_PHY_MODE_M, mode) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) FIELD_GET(AR9331_SW_LOW_ADDR_PHY, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) r = FIELD_GET(AR9331_SW_LOW_ADDR_REG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return mdiobus_write(sbus, p, r, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static int __ar9331_mdio_read(struct mii_bus *sbus, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) u8 r, p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) p = FIELD_PREP(AR9331_SW_MDIO_PHY_MODE_M, AR9331_SW_MDIO_PHY_MODE_REG) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) FIELD_GET(AR9331_SW_LOW_ADDR_PHY, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) r = FIELD_GET(AR9331_SW_LOW_ADDR_REG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return mdiobus_read(sbus, p, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static int ar9331_mdio_read(void *ctx, const void *reg_buf, size_t reg_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) void *val_buf, size_t val_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct ar9331_sw_priv *priv = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct mii_bus *sbus = priv->sbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) u32 reg = *(u32 *)reg_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (reg == AR9331_SW_REG_PAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) /* We cannot read the page selector register from hardware and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * we cache its value in regmap. Return all bits set here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * that regmap will always write the page on first use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) *(u32 *)val_buf = GENMASK(9, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) ret = __ar9331_mdio_read(sbus, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) *(u32 *)val_buf = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ret = __ar9331_mdio_read(sbus, reg + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) *(u32 *)val_buf |= ret << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) dev_err_ratelimited(&sbus->dev, "Bus error. Failed to read register.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static int ar9331_mdio_write(void *ctx, u32 reg, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct ar9331_sw_priv *priv = (struct ar9331_sw_priv *)ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct mii_bus *sbus = priv->sbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (reg == AR9331_SW_REG_PAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) ret = __ar9331_mdio_write(sbus, AR9331_SW_MDIO_PHY_MODE_PAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* In case of this switch we work with 32bit registers on top of 16bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * bus. Some registers (for example access to forwarding database) have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * trigger bit on the first 16bit half of request, the result and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * configuration of request in the second half.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * To make it work properly, we should do the second part of transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * before the first one is done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) ret = __ar9331_mdio_write(sbus, AR9331_SW_MDIO_PHY_MODE_REG, reg + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) val >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) ret = __ar9331_mdio_write(sbus, AR9331_SW_MDIO_PHY_MODE_REG, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) dev_err_ratelimited(&sbus->dev, "Bus error. Failed to write register.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) static int ar9331_sw_bus_write(void *context, const void *data, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) u32 reg = *(u32 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) u32 val = *((u32 *)data + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return ar9331_mdio_write(context, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static const struct regmap_range ar9331_valid_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) regmap_reg_range(0x0, 0x0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) regmap_reg_range(0x10, 0x14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) regmap_reg_range(0x20, 0x24),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) regmap_reg_range(0x2c, 0x30),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) regmap_reg_range(0x40, 0x44),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) regmap_reg_range(0x50, 0x78),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) regmap_reg_range(0x80, 0x98),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) regmap_reg_range(0x100, 0x120),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) regmap_reg_range(0x200, 0x220),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) regmap_reg_range(0x300, 0x320),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) regmap_reg_range(0x400, 0x420),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) regmap_reg_range(0x500, 0x520),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) regmap_reg_range(0x600, 0x620),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) regmap_reg_range(0x20000, 0x200a4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) regmap_reg_range(0x20100, 0x201a4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) regmap_reg_range(0x20200, 0x202a4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) regmap_reg_range(0x20300, 0x203a4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) regmap_reg_range(0x20400, 0x204a4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) regmap_reg_range(0x20500, 0x205a4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /* dummy page selector reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) regmap_reg_range(AR9331_SW_REG_PAGE, AR9331_SW_REG_PAGE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) static const struct regmap_range ar9331_nonvolatile_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) regmap_reg_range(AR9331_SW_REG_PAGE, AR9331_SW_REG_PAGE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static const struct regmap_range_cfg ar9331_regmap_range[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) .selector_reg = AR9331_SW_REG_PAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) .selector_mask = GENMASK(9, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) .selector_shift = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) .window_start = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) .window_len = 512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) .range_min = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) .range_max = AR9331_SW_REG_PAGE - 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) static const struct regmap_access_table ar9331_register_set = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) .yes_ranges = ar9331_valid_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .n_yes_ranges = ARRAY_SIZE(ar9331_valid_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) static const struct regmap_access_table ar9331_volatile_set = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) .no_ranges = ar9331_nonvolatile_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) .n_no_ranges = ARRAY_SIZE(ar9331_nonvolatile_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) static const struct regmap_config ar9331_mdio_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) .max_register = AR9331_SW_REG_PAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) .ranges = ar9331_regmap_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) .num_ranges = ARRAY_SIZE(ar9331_regmap_range),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) .volatile_table = &ar9331_volatile_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) .wr_table = &ar9331_register_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) .rd_table = &ar9331_register_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) .cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) static struct regmap_bus ar9331_sw_bus = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) .val_format_endian_default = REGMAP_ENDIAN_NATIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) .read = ar9331_mdio_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) .write = ar9331_sw_bus_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) .max_raw_read = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) .max_raw_write = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) static int ar9331_sw_probe(struct mdio_device *mdiodev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct ar9331_sw_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) struct dsa_switch *ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) priv->regmap = devm_regmap_init(&mdiodev->dev, &ar9331_sw_bus, priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) &ar9331_mdio_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (IS_ERR(priv->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) ret = PTR_ERR(priv->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) dev_err(&mdiodev->dev, "regmap init failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) priv->sw_reset = devm_reset_control_get(&mdiodev->dev, "switch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (IS_ERR(priv->sw_reset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) dev_err(&mdiodev->dev, "missing switch reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return PTR_ERR(priv->sw_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) priv->sbus = mdiodev->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) priv->dev = &mdiodev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) ret = ar9331_sw_irq_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) ds = &priv->ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) ds->dev = &mdiodev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ds->num_ports = AR9331_SW_PORTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) ds->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) priv->ops = ar9331_sw_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) ds->ops = &priv->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) dev_set_drvdata(&mdiodev->dev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ret = dsa_register_switch(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) goto err_remove_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) err_remove_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) irq_domain_remove(priv->irqdomain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) static void ar9331_sw_remove(struct mdio_device *mdiodev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) struct ar9331_sw_priv *priv = dev_get_drvdata(&mdiodev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) irq_domain_remove(priv->irqdomain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) dsa_unregister_switch(&priv->ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) reset_control_assert(priv->sw_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) static const struct of_device_id ar9331_sw_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) { .compatible = "qca,ar9331-switch" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) static struct mdio_driver ar9331_sw_mdio_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) .probe = ar9331_sw_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) .remove = ar9331_sw_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) .mdiodrv.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) .name = AR9331_SW_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) .of_match_table = ar9331_sw_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) mdio_module_driver(ar9331_sw_mdio_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) MODULE_AUTHOR("Oleksij Rempel <kernel@pengutronix.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) MODULE_DESCRIPTION("Driver for Atheros AR9331 switch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) MODULE_LICENSE("GPL v2");