History

Merge branch 'rtl8365mb-vc-support'

Alvin Šipraga says: ==================== net: dsa: add support for RTL8365MB-VC This series adds support for Realtek's RTL8365MB-VC, a 4+1 port 10/100/1000M Ethernet switch. The driver - rtl8365mb - was developed by Michael Ramussen and myself. This version of the driver is relatively slim, implementing only the standalone port functionality and no offload capabilities. It is based on a previous RFC series [1] from August, and the main difference is the removal of some spurious VLAN operations. Otherwise I have simply addressed most of the feedback. Please see the respective patches for more detail. In parallel I am working on offloading the bridge layer capabilities, but I would like to get the basic stuff upstreamed as soon as possible. v3 -> v4: - get irq before setting virq parents (fixes kernel test robot warning) - remove pad-to-72-bytes logic in tagger xmit (fixes DENG Qingfang's suggestion); no longer needed as we set CPU minimum RX size to 64 bytes - use mutex to protect MIB counter access instead of a spinlock (fixes Jakub's feedback on v3 statistics refactoring) v2 -> v3: - move IRQ setup earlier in probe per Florian's suggestion - fix compilation error on some archs due to FIELD_PREP use in v1 - follow Jakub's suggestion and use the standard ethtool stats API; NOTE: new patch in the series for relevant DSA plumbing - following the stats change, it became apparent that the rtl8366 helper library is no longer that helpful; scrap it and implement the ethtool ops specifically for this chip v1 -> v2: - drop DSA port type checks during MAC configuration - use OF properties to configure RGMII TX/RX delay - don't set default fwd_offload_mark if packet is trapped to CPU - remove port mapping macros - update device tree bindings documentation with an example - cosmetic changes to the tagging driver using FIELD_* macros [1] https://lore.kernel.org/netdev/20210822193145.1312668-1-alvin@pqrs.dk/ ====================

David S. Miller committed 5 years ago

Commit c87350c2 parents 4abd7cf 2ca296913 files · +2320 −9Browse files

Unified · Split

13 files
  1. Documentation/devicetree/bindings/net/dsa/realtek-smi.txt +87 −0
  2. drivers/net/dsa/Kconfig +1 −0
  3. drivers/net/dsa/Makefile +1 −1
  4. drivers/net/dsa/realtek-smi-core.c +4 −0
  5. drivers/net/dsa/realtek-smi-core.h +1 −0
  6. drivers/net/dsa/rtl8365mb.c +1982 −0
  7. drivers/net/phy/realtek.c +8 −0
  8. include/net/dsa.h +8 −0
  9. include/uapi/linux/if_ether.h +1 −0
  10. net/dsa/Kconfig +13 −7
  11. net/dsa/Makefile +2 −1
  12. net/dsa/slave.c +34 −0
  13. net/dsa/tag_rtl8_4.c +178 −0
Documentation/devicetree/bindings/net/dsa/realtek-smi.txt+87−0
@@ -9,6 +9,7 @@ SMI-based Realtek devices. · 8 unmodified lines
99 Required properties:
1010
1111 - compatible: must be exactly one of:
12+ "realtek,rtl8365mb" (4+1 ports)
1213 "realtek,rtl8366"
1314 "realtek,rtl8366rb" (4+1 ports)
1415 "realtek,rtl8366s" (4+1 ports)
@@ -62,6 +63,8 @@ and subnodes of DSA switches. · 47 unmodified lines
6263
6364 Examples:
6465
66+An example for the RTL8366RB:
67+
6568 switch {
6669 compatible = "realtek,rtl8366rb";
6770 /* 22 = MDIO (has input reads), 21 = MDC (clock, output only) */
@@ -151,3 +154,87 @@ switch { · 83 unmodified lines
151154 };
152155 };
153156 };
157+
158+An example for the RTL8365MB-VC:
159+
160+switch {
161+ compatible = "realtek,rtl8365mb";
162+ mdc-gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
163+ mdio-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
164+ reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
165+
166+ switch_intc: interrupt-controller {
167+ interrupt-parent = <&gpio5>;
168+ interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
169+ interrupt-controller;
170+ #address-cells = <0>;
171+ #interrupt-cells = <1>;
172+ };
173+
174+ ports {
175+ #address-cells = <1>;
176+ #size-cells = <0>;
177+ reg = <0>;
178+ port@0 {
179+ reg = <0>;
180+ label = "swp0";
181+ phy-handle = <&ethphy0>;
182+ };
183+ port@1 {
184+ reg = <1>;
185+ label = "swp1";
186+ phy-handle = <&ethphy1>;
187+ };
188+ port@2 {
189+ reg = <2>;
190+ label = "swp2";
191+ phy-handle = <&ethphy2>;
192+ };
193+ port@3 {
194+ reg = <3>;
195+ label = "swp3";
196+ phy-handle = <&ethphy3>;
197+ };
198+ port@6 {
199+ reg = <6>;
200+ label = "cpu";
201+ ethernet = <&fec1>;
202+ phy-mode = "rgmii";
203+ tx-internal-delay-ps = <2000>;
204+ rx-internal-delay-ps = <2000>;
205+
206+ fixed-link {
207+ speed = <1000>;
208+ full-duplex;
209+ pause;
210+ };
211+ };
212+ };
213+
214+ mdio {
215+ compatible = "realtek,smi-mdio";
216+ #address-cells = <1>;
217+ #size-cells = <0>;
218+
219+ ethphy0: phy@0 {
220+ reg = <0>;
221+ interrupt-parent = <&switch_intc>;
222+ interrupts = <0>;
223+ };
224+ ethphy1: phy@1 {
225+ reg = <1>;
226+ interrupt-parent = <&switch_intc>;
227+ interrupts = <1>;
228+ };
229+ ethphy2: phy@2 {
230+ reg = <2>;
231+ interrupt-parent = <&switch_intc>;
232+ interrupts = <2>;
233+ };
234+ ethphy3: phy@3 {
235+ reg = <3>;
236+ interrupt-parent = <&switch_intc>;
237+ interrupts = <3>;
238+ };
239+ };
240+};
drivers/net/dsa/Kconfig+1−0
@@ -70,6 +70,7 @@ config NET_DSA_QCA8K · 69 unmodified lines
7070 config NET_DSA_REALTEK_SMI
7171 tristate "Realtek SMI Ethernet switch family support"
7272 select NET_DSA_TAG_RTL4_A
73+ select NET_DSA_TAG_RTL8_4
7374 select FIXED_PHY
7475 select IRQ_DOMAIN
7576 select REALTEK_PHY
drivers/net/dsa/Makefile+1−1
@@ -10,7 +10,7 @@ obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o · 9 unmodified lines
1010 obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
1111 obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
1212 obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
13−realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o
13+realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o rtl8365mb.o
1414 obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
1515 obj-$(CONFIG_NET_DSA_SMSC_LAN9303_I2C) += lan9303_i2c.o
1616 obj-$(CONFIG_NET_DSA_SMSC_LAN9303_MDIO) += lan9303_mdio.o
drivers/net/dsa/realtek-smi-core.c+4−0
@@ -501,6 +501,10 @@ static const struct of_device_id realtek_smi_of_match[] = { · 500 unmodified lines
501501 .compatible = "realtek,rtl8366s",
502502 .data = NULL,
503503 },
504+ {
505+ .compatible = "realtek,rtl8365mb",
506+ .data = &rtl8365mb_variant,
507+ },
504508 { /* sentinel */ },
505509 };
506510 MODULE_DEVICE_TABLE(of, realtek_smi_of_match);
drivers/net/dsa/realtek-smi-core.h+1−0
@@ -140,5 +140,6 @@ int rtl8366_get_sset_count(struct dsa_switch *ds, int port, int sset); · 139 unmodified lines
140140 void rtl8366_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);
141141
142142 extern const struct realtek_smi_variant rtl8366rb_variant;
143+extern const struct realtek_smi_variant rtl8365mb_variant;
143144
144145 #endif /* _REALTEK_SMI_H */
drivers/net/dsa/rtl8365mb.c+1982−0
@@ -0,0 +1,1982 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/* Realtek SMI subdriver for the Realtek RTL8365MB-VC ethernet switch.
3+ *
4+ * Copyright (C) 2021 Alvin Šipraga <alsi@bang-olufsen.dk>
5+ * Copyright (C) 2021 Michael Rasmussen <mir@bang-olufsen.dk>
6+ *
7+ * The RTL8365MB-VC is a 4+1 port 10/100/1000M switch controller. It includes 4
8+ * integrated PHYs for the user facing ports, and an extension interface which
9+ * can be connected to the CPU - or another PHY - via either MII, RMII, or
10+ * RGMII. The switch is configured via the Realtek Simple Management Interface
11+ * (SMI), which uses the MDIO/MDC lines.
12+ *
13+ * Below is a simplified block diagram of the chip and its relevant interfaces.
14+ *
15+ * .-----------------------------------.
16+ * | |
17+ * UTP <---------------> Giga PHY <-> PCS <-> P0 GMAC |
18+ * UTP <---------------> Giga PHY <-> PCS <-> P1 GMAC |
19+ * UTP <---------------> Giga PHY <-> PCS <-> P2 GMAC |
20+ * UTP <---------------> Giga PHY <-> PCS <-> P3 GMAC |
21+ * | |
22+ * CPU/PHY <-MII/RMII/RGMII---> Extension <---> Extension |
23+ * | interface 1 GMAC 1 |
24+ * | |
25+ * SMI driver/ <-MDC/SCL---> Management ~~~~~~~~~~~~~~ |
26+ * EEPROM <-MDIO/SDA--> interface ~REALTEK ~~~~~ |
27+ * | ~RTL8365MB ~~~ |
28+ * | ~GXXXC TAIWAN~ |
29+ * GPIO <--------------> Reset ~~~~~~~~~~~~~~ |
30+ * | |
31+ * Interrupt <----------> Link UP/DOWN events |
32+ * controller | |
33+ * '-----------------------------------'
34+ *
35+ * The driver uses DSA to integrate the 4 user and 1 extension ports into the
36+ * kernel. Netdevices are created for the user ports, as are PHY devices for
37+ * their integrated PHYs. The device tree firmware should also specify the link
38+ * partner of the extension port - either via a fixed-link or other phy-handle.
39+ * See the device tree bindings for more detailed information. Note that the
40+ * driver has only been tested with a fixed-link, but in principle it should not
41+ * matter.
42+ *
43+ * NOTE: Currently, only the RGMII interface is implemented in this driver.
44+ *
45+ * The interrupt line is asserted on link UP/DOWN events. The driver creates a
46+ * custom irqchip to handle this interrupt and demultiplex the events by reading
47+ * the status registers via SMI. Interrupts are then propagated to the relevant
48+ * PHY device.
49+ *
50+ * The EEPROM contains initial register values which the chip will read over I2C
51+ * upon hardware reset. It is also possible to omit the EEPROM. In both cases,
52+ * the driver will manually reprogram some registers using jam tables to reach
53+ * an initial state defined by the vendor driver.
54+ *
55+ * This Linux driver is written based on an OS-agnostic vendor driver from
56+ * Realtek. The reference GPL-licensed sources can be found in the OpenWrt
57+ * source tree under the name rtl8367c. The vendor driver claims to support a
58+ * number of similar switch controllers from Realtek, but the only hardware we
59+ * have is the RTL8365MB-VC. Moreover, there does not seem to be any chip under
60+ * the name RTL8367C. Although one wishes that the 'C' stood for some kind of
61+ * common hardware revision, there exist examples of chips with the suffix -VC
62+ * which are explicitly not supported by the rtl8367c driver and which instead
63+ * require the rtl8367d vendor driver. With all this uncertainty, the driver has
64+ * been modestly named rtl8365mb. Future implementors may wish to rename things
65+ * accordingly.
66+ *
67+ * In the same family of chips, some carry up to 8 user ports and up to 2
68+ * extension ports. Where possible this driver tries to make things generic, but
69+ * more work must be done to support these configurations. According to
70+ * documentation from Realtek, the family should include the following chips:
71+ *
72+ * - RTL8363NB
73+ * - RTL8363NB-VB
74+ * - RTL8363SC
75+ * - RTL8363SC-VB
76+ * - RTL8364NB
77+ * - RTL8364NB-VB
78+ * - RTL8365MB-VC
79+ * - RTL8366SC
80+ * - RTL8367RB-VB
81+ * - RTL8367SB
82+ * - RTL8367S
83+ * - RTL8370MB
84+ * - RTL8310SR
85+ *
86+ * Some of the register logic for these additional chips has been skipped over
87+ * while implementing this driver. It is therefore not possible to assume that
88+ * things will work out-of-the-box for other chips, and a careful review of the
89+ * vendor driver may be needed to expand support. The RTL8365MB-VC seems to be
90+ * one of the simpler chips.
91+ */
92+
93+#include <linux/bitfield.h>
94+#include <linux/bitops.h>
95+#include <linux/interrupt.h>
96+#include <linux/irqdomain.h>
97+#include <linux/mutex.h>
98+#include <linux/of_irq.h>
99+#include <linux/regmap.h>
100+#include <linux/if_bridge.h>
101+
102+#include "realtek-smi-core.h"
103+
104+/* Chip-specific data and limits */
105+#define RTL8365MB_CHIP_ID_8365MB_VC 0x6367
106+#define RTL8365MB_CPU_PORT_NUM_8365MB_VC 6
107+#define RTL8365MB_LEARN_LIMIT_MAX_8365MB_VC 2112
108+
109+/* Family-specific data and limits */
110+#define RTL8365MB_NUM_PHYREGS 32
111+#define RTL8365MB_PHYREGMAX (RTL8365MB_NUM_PHYREGS - 1)
112+#define RTL8365MB_MAX_NUM_PORTS (RTL8365MB_CPU_PORT_NUM_8365MB_VC + 1)
113+
114+/* Chip identification registers */
115+#define RTL8365MB_CHIP_ID_REG 0x1300
116+
117+#define RTL8365MB_CHIP_VER_REG 0x1301
118+
119+#define RTL8365MB_MAGIC_REG 0x13C2
120+#define RTL8365MB_MAGIC_VALUE 0x0249
121+
122+/* Chip reset register */
123+#define RTL8365MB_CHIP_RESET_REG 0x1322
124+#define RTL8365MB_CHIP_RESET_SW_MASK 0x0002
125+#define RTL8365MB_CHIP_RESET_HW_MASK 0x0001
126+
127+/* Interrupt polarity register */
128+#define RTL8365MB_INTR_POLARITY_REG 0x1100
129+#define RTL8365MB_INTR_POLARITY_MASK 0x0001
130+#define RTL8365MB_INTR_POLARITY_HIGH 0
131+#define RTL8365MB_INTR_POLARITY_LOW 1
132+
133+/* Interrupt control/status register - enable/check specific interrupt types */
134+#define RTL8365MB_INTR_CTRL_REG 0x1101
135+#define RTL8365MB_INTR_STATUS_REG 0x1102
136+#define RTL8365MB_INTR_SLIENT_START_2_MASK 0x1000
137+#define RTL8365MB_INTR_SLIENT_START_MASK 0x0800
138+#define RTL8365MB_INTR_ACL_ACTION_MASK 0x0200
139+#define RTL8365MB_INTR_CABLE_DIAG_FIN_MASK 0x0100
140+#define RTL8365MB_INTR_INTERRUPT_8051_MASK 0x0080
141+#define RTL8365MB_INTR_LOOP_DETECTION_MASK 0x0040
142+#define RTL8365MB_INTR_GREEN_TIMER_MASK 0x0020
143+#define RTL8365MB_INTR_SPECIAL_CONGEST_MASK 0x0010
144+#define RTL8365MB_INTR_SPEED_CHANGE_MASK 0x0008
145+#define RTL8365MB_INTR_LEARN_OVER_MASK 0x0004
146+#define RTL8365MB_INTR_METER_EXCEEDED_MASK 0x0002
147+#define RTL8365MB_INTR_LINK_CHANGE_MASK 0x0001
148+#define RTL8365MB_INTR_ALL_MASK \
149+ (RTL8365MB_INTR_SLIENT_START_2_MASK | \
150+ RTL8365MB_INTR_SLIENT_START_MASK | \
151+ RTL8365MB_INTR_ACL_ACTION_MASK | \
152+ RTL8365MB_INTR_CABLE_DIAG_FIN_MASK | \
153+ RTL8365MB_INTR_INTERRUPT_8051_MASK | \
154+ RTL8365MB_INTR_LOOP_DETECTION_MASK | \
155+ RTL8365MB_INTR_GREEN_TIMER_MASK | \
156+ RTL8365MB_INTR_SPECIAL_CONGEST_MASK | \
157+ RTL8365MB_INTR_SPEED_CHANGE_MASK | \
158+ RTL8365MB_INTR_LEARN_OVER_MASK | \
159+ RTL8365MB_INTR_METER_EXCEEDED_MASK | \
160+ RTL8365MB_INTR_LINK_CHANGE_MASK)
161+
162+/* Per-port interrupt type status registers */
163+#define RTL8365MB_PORT_LINKDOWN_IND_REG 0x1106
164+#define RTL8365MB_PORT_LINKDOWN_IND_MASK 0x07FF
165+
166+#define RTL8365MB_PORT_LINKUP_IND_REG 0x1107
167+#define RTL8365MB_PORT_LINKUP_IND_MASK 0x07FF
168+
169+/* PHY indirect access registers */
170+#define RTL8365MB_INDIRECT_ACCESS_CTRL_REG 0x1F00
171+#define RTL8365MB_INDIRECT_ACCESS_CTRL_RW_MASK 0x0002
172+#define RTL8365MB_INDIRECT_ACCESS_CTRL_RW_READ 0
173+#define RTL8365MB_INDIRECT_ACCESS_CTRL_RW_WRITE 1
174+#define RTL8365MB_INDIRECT_ACCESS_CTRL_CMD_MASK 0x0001
175+#define RTL8365MB_INDIRECT_ACCESS_CTRL_CMD_VALUE 1
176+#define RTL8365MB_INDIRECT_ACCESS_STATUS_REG 0x1F01
177+#define RTL8365MB_INDIRECT_ACCESS_ADDRESS_REG 0x1F02
178+#define RTL8365MB_INDIRECT_ACCESS_ADDRESS_OCPADR_5_1_MASK GENMASK(4, 0)
179+#define RTL8365MB_INDIRECT_ACCESS_ADDRESS_PHYNUM_MASK GENMASK(6, 5)
180+#define RTL8365MB_INDIRECT_ACCESS_ADDRESS_OCPADR_9_6_MASK GENMASK(11, 8)
181+#define RTL8365MB_PHY_BASE 0x2000
182+#define RTL8365MB_INDIRECT_ACCESS_WRITE_DATA_REG 0x1F03
183+#define RTL8365MB_INDIRECT_ACCESS_READ_DATA_REG 0x1F04
184+
185+/* PHY OCP address prefix register */
186+#define RTL8365MB_GPHY_OCP_MSB_0_REG 0x1D15
187+#define RTL8365MB_GPHY_OCP_MSB_0_CFG_CPU_OCPADR_MASK 0x0FC0
188+#define RTL8365MB_PHY_OCP_ADDR_PREFIX_MASK 0xFC00
189+
190+/* The PHY OCP addresses of PHY registers 0~31 start here */
191+#define RTL8365MB_PHY_OCP_ADDR_PHYREG_BASE 0xA400
192+
193+/* EXT port interface mode values - used in DIGITAL_INTERFACE_SELECT */
194+#define RTL8365MB_EXT_PORT_MODE_DISABLE 0
195+#define RTL8365MB_EXT_PORT_MODE_RGMII 1
196+#define RTL8365MB_EXT_PORT_MODE_MII_MAC 2
197+#define RTL8365MB_EXT_PORT_MODE_MII_PHY 3
198+#define RTL8365MB_EXT_PORT_MODE_TMII_MAC 4
199+#define RTL8365MB_EXT_PORT_MODE_TMII_PHY 5
200+#define RTL8365MB_EXT_PORT_MODE_GMII 6
201+#define RTL8365MB_EXT_PORT_MODE_RMII_MAC 7
202+#define RTL8365MB_EXT_PORT_MODE_RMII_PHY 8
203+#define RTL8365MB_EXT_PORT_MODE_SGMII 9
204+#define RTL8365MB_EXT_PORT_MODE_HSGMII 10
205+#define RTL8365MB_EXT_PORT_MODE_1000X_100FX 11
206+#define RTL8365MB_EXT_PORT_MODE_1000X 12
207+#define RTL8365MB_EXT_PORT_MODE_100FX 13
208+
209+/* EXT port interface mode configuration registers 0~1 */
210+#define RTL8365MB_DIGITAL_INTERFACE_SELECT_REG0 0x1305
211+#define RTL8365MB_DIGITAL_INTERFACE_SELECT_REG1 0x13C3
212+#define RTL8365MB_DIGITAL_INTERFACE_SELECT_REG(_extport) \
213+ (RTL8365MB_DIGITAL_INTERFACE_SELECT_REG0 + \
214+ ((_extport) >> 1) * (0x13C3 - 0x1305))
215+#define RTL8365MB_DIGITAL_INTERFACE_SELECT_MODE_MASK(_extport) \
216+ (0xF << (((_extport) % 2)))
217+#define RTL8365MB_DIGITAL_INTERFACE_SELECT_MODE_OFFSET(_extport) \
218+ (((_extport) % 2) * 4)
219+
220+/* EXT port RGMII TX/RX delay configuration registers 1~2 */
221+#define RTL8365MB_EXT_RGMXF_REG1 0x1307
222+#define RTL8365MB_EXT_RGMXF_REG2 0x13C5
223+#define RTL8365MB_EXT_RGMXF_REG(_extport) \
224+ (RTL8365MB_EXT_RGMXF_REG1 + \
225+ (((_extport) >> 1) * (0x13C5 - 0x1307)))
226+#define RTL8365MB_EXT_RGMXF_RXDELAY_MASK 0x0007
227+#define RTL8365MB_EXT_RGMXF_TXDELAY_MASK 0x0008
228+
229+/* External port speed values - used in DIGITAL_INTERFACE_FORCE */
230+#define RTL8365MB_PORT_SPEED_10M 0
231+#define RTL8365MB_PORT_SPEED_100M 1
232+#define RTL8365MB_PORT_SPEED_1000M 2
233+
234+/* EXT port force configuration registers 0~2 */
235+#define RTL8365MB_DIGITAL_INTERFACE_FORCE_REG0 0x1310
236+#define RTL8365MB_DIGITAL_INTERFACE_FORCE_REG1 0x1311
237+#define RTL8365MB_DIGITAL_INTERFACE_FORCE_REG2 0x13C4
238+#define RTL8365MB_DIGITAL_INTERFACE_FORCE_REG(_extport) \
239+ (RTL8365MB_DIGITAL_INTERFACE_FORCE_REG0 + \
240+ ((_extport) & 0x1) + \
241+ ((((_extport) >> 1) & 0x1) * (0x13C4 - 0x1310)))
242+#define RTL8365MB_DIGITAL_INTERFACE_FORCE_EN_MASK 0x1000
243+#define RTL8365MB_DIGITAL_INTERFACE_FORCE_NWAY_MASK 0x0080
244+#define RTL8365MB_DIGITAL_INTERFACE_FORCE_TXPAUSE_MASK 0x0040
245+#define RTL8365MB_DIGITAL_INTERFACE_FORCE_RXPAUSE_MASK 0x0020
246+#define RTL8365MB_DIGITAL_INTERFACE_FORCE_LINK_MASK 0x0010
247+#define RTL8365MB_DIGITAL_INTERFACE_FORCE_DUPLEX_MASK 0x0004
248+#define RTL8365MB_DIGITAL_INTERFACE_FORCE_SPEED_MASK 0x0003
249+
250+/* CPU port mask register - controls which ports are treated as CPU ports */
251+#define RTL8365MB_CPU_PORT_MASK_REG 0x1219
252+#define RTL8365MB_CPU_PORT_MASK_MASK 0x07FF
253+
254+/* CPU control register */
255+#define RTL8365MB_CPU_CTRL_REG 0x121A
256+#define RTL8365MB_CPU_CTRL_TRAP_PORT_EXT_MASK 0x0400
257+#define RTL8365MB_CPU_CTRL_TAG_FORMAT_MASK 0x0200
258+#define RTL8365MB_CPU_CTRL_RXBYTECOUNT_MASK 0x0080
259+#define RTL8365MB_CPU_CTRL_TAG_POSITION_MASK 0x0040
260+#define RTL8365MB_CPU_CTRL_TRAP_PORT_MASK 0x0038
261+#define RTL8365MB_CPU_CTRL_INSERTMODE_MASK 0x0006
262+#define RTL8365MB_CPU_CTRL_EN_MASK 0x0001
263+
264+/* Maximum packet length register */
265+#define RTL8365MB_CFG0_MAX_LEN_REG 0x088C
266+#define RTL8365MB_CFG0_MAX_LEN_MASK 0x3FFF
267+
268+/* Port learning limit registers */
269+#define RTL8365MB_LUT_PORT_LEARN_LIMIT_BASE 0x0A20
270+#define RTL8365MB_LUT_PORT_LEARN_LIMIT_REG(_physport) \
271+ (RTL8365MB_LUT_PORT_LEARN_LIMIT_BASE + (_physport))
272+
273+/* Port isolation (forwarding mask) registers */
274+#define RTL8365MB_PORT_ISOLATION_REG_BASE 0x08A2
275+#define RTL8365MB_PORT_ISOLATION_REG(_physport) \
276+ (RTL8365MB_PORT_ISOLATION_REG_BASE + (_physport))
277+#define RTL8365MB_PORT_ISOLATION_MASK 0x07FF
278+
279+/* MSTP port state registers - indexed by tree instancrSTI (tree ine */
280+#define RTL8365MB_MSTI_CTRL_BASE 0x0A00
281+#define RTL8365MB_MSTI_CTRL_REG(_msti, _physport) \
282+ (RTL8365MB_MSTI_CTRL_BASE + ((_msti) << 1) + ((_physport) >> 3))
283+#define RTL8365MB_MSTI_CTRL_PORT_STATE_OFFSET(_physport) ((_physport) << 1)
284+#define RTL8365MB_MSTI_CTRL_PORT_STATE_MASK(_physport) \
285+ (0x3 << RTL8365MB_MSTI_CTRL_PORT_STATE_OFFSET((_physport)))
286+
287+/* MIB counter value registers */
288+#define RTL8365MB_MIB_COUNTER_BASE 0x1000
289+#define RTL8365MB_MIB_COUNTER_REG(_x) (RTL8365MB_MIB_COUNTER_BASE + (_x))
290+
291+/* MIB counter address register */
292+#define RTL8365MB_MIB_ADDRESS_REG 0x1004
293+#define RTL8365MB_MIB_ADDRESS_PORT_OFFSET 0x007C
294+#define RTL8365MB_MIB_ADDRESS(_p, _x) \
295+ (((RTL8365MB_MIB_ADDRESS_PORT_OFFSET) * (_p) + (_x)) >> 2)
296+
297+#define RTL8365MB_MIB_CTRL0_REG 0x1005
298+#define RTL8365MB_MIB_CTRL0_RESET_MASK 0x0002
299+#define RTL8365MB_MIB_CTRL0_BUSY_MASK 0x0001
300+
301+/* The DSA callback .get_stats64 runs in atomic context, so we are not allowed
302+ * to block. On the other hand, accessing MIB counters absolutely requires us to
303+ * block. The solution is thus to schedule work which polls the MIB counters
304+ * asynchronously and updates some private data, which the callback can then
305+ * fetch atomically. Three seconds should be a good enough polling interval.
306+ */
307+#define RTL8365MB_STATS_INTERVAL_JIFFIES (3 * HZ)
308+
309+enum rtl8365mb_mib_counter_index {
310+ RTL8365MB_MIB_ifInOctets,
311+ RTL8365MB_MIB_dot3StatsFCSErrors,
312+ RTL8365MB_MIB_dot3StatsSymbolErrors,
313+ RTL8365MB_MIB_dot3InPauseFrames,
314+ RTL8365MB_MIB_dot3ControlInUnknownOpcodes,
315+ RTL8365MB_MIB_etherStatsFragments,
316+ RTL8365MB_MIB_etherStatsJabbers,
317+ RTL8365MB_MIB_ifInUcastPkts,
318+ RTL8365MB_MIB_etherStatsDropEvents,
319+ RTL8365MB_MIB_ifInMulticastPkts,
320+ RTL8365MB_MIB_ifInBroadcastPkts,
321+ RTL8365MB_MIB_inMldChecksumError,
322+ RTL8365MB_MIB_inIgmpChecksumError,
323+ RTL8365MB_MIB_inMldSpecificQuery,
324+ RTL8365MB_MIB_inMldGeneralQuery,
325+ RTL8365MB_MIB_inIgmpSpecificQuery,
326+ RTL8365MB_MIB_inIgmpGeneralQuery,
327+ RTL8365MB_MIB_inMldLeaves,
328+ RTL8365MB_MIB_inIgmpLeaves,
329+ RTL8365MB_MIB_etherStatsOctets,
330+ RTL8365MB_MIB_etherStatsUnderSizePkts,
331+ RTL8365MB_MIB_etherOversizeStats,
332+ RTL8365MB_MIB_etherStatsPkts64Octets,
333+ RTL8365MB_MIB_etherStatsPkts65to127Octets,
334+ RTL8365MB_MIB_etherStatsPkts128to255Octets,
335+ RTL8365MB_MIB_etherStatsPkts256to511Octets,
336+ RTL8365MB_MIB_etherStatsPkts512to1023Octets,
337+ RTL8365MB_MIB_etherStatsPkts1024to1518Octets,
338+ RTL8365MB_MIB_ifOutOctets,
339+ RTL8365MB_MIB_dot3StatsSingleCollisionFrames,
340+ RTL8365MB_MIB_dot3StatsMultipleCollisionFrames,
341+ RTL8365MB_MIB_dot3StatsDeferredTransmissions,
342+ RTL8365MB_MIB_dot3StatsLateCollisions,
343+ RTL8365MB_MIB_etherStatsCollisions,
344+ RTL8365MB_MIB_dot3StatsExcessiveCollisions,
345+ RTL8365MB_MIB_dot3OutPauseFrames,
346+ RTL8365MB_MIB_ifOutDiscards,
347+ RTL8365MB_MIB_dot1dTpPortInDiscards,
348+ RTL8365MB_MIB_ifOutUcastPkts,
349+ RTL8365MB_MIB_ifOutMulticastPkts,
350+ RTL8365MB_MIB_ifOutBroadcastPkts,
351+ RTL8365MB_MIB_outOampduPkts,
352+ RTL8365MB_MIB_inOampduPkts,
353+ RTL8365MB_MIB_inIgmpJoinsSuccess,
354+ RTL8365MB_MIB_inIgmpJoinsFail,
355+ RTL8365MB_MIB_inMldJoinsSuccess,
356+ RTL8365MB_MIB_inMldJoinsFail,
357+ RTL8365MB_MIB_inReportSuppressionDrop,
358+ RTL8365MB_MIB_inLeaveSuppressionDrop,
359+ RTL8365MB_MIB_outIgmpReports,
360+ RTL8365MB_MIB_outIgmpLeaves,
361+ RTL8365MB_MIB_outIgmpGeneralQuery,
362+ RTL8365MB_MIB_outIgmpSpecificQuery,
363+ RTL8365MB_MIB_outMldReports,
364+ RTL8365MB_MIB_outMldLeaves,
365+ RTL8365MB_MIB_outMldGeneralQuery,
366+ RTL8365MB_MIB_outMldSpecificQuery,
367+ RTL8365MB_MIB_inKnownMulticastPkts,
368+ RTL8365MB_MIB_END,
369+};
370+
371+struct rtl8365mb_mib_counter {
372+ u32 offset;
373+ u32 length;
374+ const char *name;
375+};
376+
377+#define RTL8365MB_MAKE_MIB_COUNTER(_offset, _length, _name) \
378+ [RTL8365MB_MIB_ ## _name] = { _offset, _length, #_name }
379+
380+static struct rtl8365mb_mib_counter rtl8365mb_mib_counters[] = {
381+ RTL8365MB_MAKE_MIB_COUNTER(0, 4, ifInOctets),
382+ RTL8365MB_MAKE_MIB_COUNTER(4, 2, dot3StatsFCSErrors),
383+ RTL8365MB_MAKE_MIB_COUNTER(6, 2, dot3StatsSymbolErrors),
384+ RTL8365MB_MAKE_MIB_COUNTER(8, 2, dot3InPauseFrames),
385+ RTL8365MB_MAKE_MIB_COUNTER(10, 2, dot3ControlInUnknownOpcodes),
386+ RTL8365MB_MAKE_MIB_COUNTER(12, 2, etherStatsFragments),
387+ RTL8365MB_MAKE_MIB_COUNTER(14, 2, etherStatsJabbers),
388+ RTL8365MB_MAKE_MIB_COUNTER(16, 2, ifInUcastPkts),
389+ RTL8365MB_MAKE_MIB_COUNTER(18, 2, etherStatsDropEvents),
390+ RTL8365MB_MAKE_MIB_COUNTER(20, 2, ifInMulticastPkts),
391+ RTL8365MB_MAKE_MIB_COUNTER(22, 2, ifInBroadcastPkts),
392+ RTL8365MB_MAKE_MIB_COUNTER(24, 2, inMldChecksumError),
393+ RTL8365MB_MAKE_MIB_COUNTER(26, 2, inIgmpChecksumError),
394+ RTL8365MB_MAKE_MIB_COUNTER(28, 2, inMldSpecificQuery),
395+ RTL8365MB_MAKE_MIB_COUNTER(30, 2, inMldGeneralQuery),
396+ RTL8365MB_MAKE_MIB_COUNTER(32, 2, inIgmpSpecificQuery),
397+ RTL8365MB_MAKE_MIB_COUNTER(34, 2, inIgmpGeneralQuery),
398+ RTL8365MB_MAKE_MIB_COUNTER(36, 2, inMldLeaves),
399+ RTL8365MB_MAKE_MIB_COUNTER(38, 2, inIgmpLeaves),
400+ RTL8365MB_MAKE_MIB_COUNTER(40, 4, etherStatsOctets),
401+ RTL8365MB_MAKE_MIB_COUNTER(44, 2, etherStatsUnderSizePkts),
402+ RTL8365MB_MAKE_MIB_COUNTER(46, 2, etherOversizeStats),
403+ RTL8365MB_MAKE_MIB_COUNTER(48, 2, etherStatsPkts64Octets),
404+ RTL8365MB_MAKE_MIB_COUNTER(50, 2, etherStatsPkts65to127Octets),
405+ RTL8365MB_MAKE_MIB_COUNTER(52, 2, etherStatsPkts128to255Octets),
406+ RTL8365MB_MAKE_MIB_COUNTER(54, 2, etherStatsPkts256to511Octets),
407+ RTL8365MB_MAKE_MIB_COUNTER(56, 2, etherStatsPkts512to1023Octets),
408+ RTL8365MB_MAKE_MIB_COUNTER(58, 2, etherStatsPkts1024to1518Octets),
409+ RTL8365MB_MAKE_MIB_COUNTER(60, 4, ifOutOctets),
410+ RTL8365MB_MAKE_MIB_COUNTER(64, 2, dot3StatsSingleCollisionFrames),
411+ RTL8365MB_MAKE_MIB_COUNTER(66, 2, dot3StatsMultipleCollisionFrames),
412+ RTL8365MB_MAKE_MIB_COUNTER(68, 2, dot3StatsDeferredTransmissions),
413+ RTL8365MB_MAKE_MIB_COUNTER(70, 2, dot3StatsLateCollisions),
414+ RTL8365MB_MAKE_MIB_COUNTER(72, 2, etherStatsCollisions),
415+ RTL8365MB_MAKE_MIB_COUNTER(74, 2, dot3StatsExcessiveCollisions),
416+ RTL8365MB_MAKE_MIB_COUNTER(76, 2, dot3OutPauseFrames),
417+ RTL8365MB_MAKE_MIB_COUNTER(78, 2, ifOutDiscards),
418+ RTL8365MB_MAKE_MIB_COUNTER(80, 2, dot1dTpPortInDiscards),
419+ RTL8365MB_MAKE_MIB_COUNTER(82, 2, ifOutUcastPkts),
420+ RTL8365MB_MAKE_MIB_COUNTER(84, 2, ifOutMulticastPkts),
421+ RTL8365MB_MAKE_MIB_COUNTER(86, 2, ifOutBroadcastPkts),
422+ RTL8365MB_MAKE_MIB_COUNTER(88, 2, outOampduPkts),
423+ RTL8365MB_MAKE_MIB_COUNTER(90, 2, inOampduPkts),
424+ RTL8365MB_MAKE_MIB_COUNTER(92, 4, inIgmpJoinsSuccess),
425+ RTL8365MB_MAKE_MIB_COUNTER(96, 2, inIgmpJoinsFail),
426+ RTL8365MB_MAKE_MIB_COUNTER(98, 2, inMldJoinsSuccess),
427+ RTL8365MB_MAKE_MIB_COUNTER(100, 2, inMldJoinsFail),
428+ RTL8365MB_MAKE_MIB_COUNTER(102, 2, inReportSuppressionDrop),
429+ RTL8365MB_MAKE_MIB_COUNTER(104, 2, inLeaveSuppressionDrop),
430+ RTL8365MB_MAKE_MIB_COUNTER(106, 2, outIgmpReports),
431+ RTL8365MB_MAKE_MIB_COUNTER(108, 2, outIgmpLeaves),
432+ RTL8365MB_MAKE_MIB_COUNTER(110, 2, outIgmpGeneralQuery),
433+ RTL8365MB_MAKE_MIB_COUNTER(112, 2, outIgmpSpecificQuery),
434+ RTL8365MB_MAKE_MIB_COUNTER(114, 2, outMldReports),
435+ RTL8365MB_MAKE_MIB_COUNTER(116, 2, outMldLeaves),
436+ RTL8365MB_MAKE_MIB_COUNTER(118, 2, outMldGeneralQuery),
437+ RTL8365MB_MAKE_MIB_COUNTER(120, 2, outMldSpecificQuery),
438+ RTL8365MB_MAKE_MIB_COUNTER(122, 2, inKnownMulticastPkts),
439+};
440+
441+static_assert(ARRAY_SIZE(rtl8365mb_mib_counters) == RTL8365MB_MIB_END);
442+
443+struct rtl8365mb_jam_tbl_entry {
444+ u16 reg;
445+ u16 val;
446+};
447+
448+/* Lifted from the vendor driver sources */
449+static const struct rtl8365mb_jam_tbl_entry rtl8365mb_init_jam_8365mb_vc[] = {
450+ { 0x13EB, 0x15BB }, { 0x1303, 0x06D6 }, { 0x1304, 0x0700 },
451+ { 0x13E2, 0x003F }, { 0x13F9, 0x0090 }, { 0x121E, 0x03CA },
452+ { 0x1233, 0x0352 }, { 0x1237, 0x00A0 }, { 0x123A, 0x0030 },
453+ { 0x1239, 0x0084 }, { 0x0301, 0x1000 }, { 0x1349, 0x001F },
454+ { 0x18E0, 0x4004 }, { 0x122B, 0x241C }, { 0x1305, 0xC000 },
455+ { 0x13F0, 0x0000 },
456+};
457+
458+static const struct rtl8365mb_jam_tbl_entry rtl8365mb_init_jam_common[] = {
459+ { 0x1200, 0x7FCB }, { 0x0884, 0x0003 }, { 0x06EB, 0x0001 },
460+ { 0x03Fa, 0x0007 }, { 0x08C8, 0x00C0 }, { 0x0A30, 0x020E },
461+ { 0x0800, 0x0000 }, { 0x0802, 0x0000 }, { 0x09DA, 0x0013 },
462+ { 0x1D32, 0x0002 },
463+};
464+
465+enum rtl8365mb_stp_state {
466+ RTL8365MB_STP_STATE_DISABLED = 0,
467+ RTL8365MB_STP_STATE_BLOCKING = 1,
468+ RTL8365MB_STP_STATE_LEARNING = 2,
469+ RTL8365MB_STP_STATE_FORWARDING = 3,
470+};
471+
472+enum rtl8365mb_cpu_insert {
473+ RTL8365MB_CPU_INSERT_TO_ALL = 0,
474+ RTL8365MB_CPU_INSERT_TO_TRAPPING = 1,
475+ RTL8365MB_CPU_INSERT_TO_NONE = 2,
476+};
477+
478+enum rtl8365mb_cpu_position {
479+ RTL8365MB_CPU_POS_AFTER_SA = 0,
480+ RTL8365MB_CPU_POS_BEFORE_CRC = 1,
481+};
482+
483+enum rtl8365mb_cpu_format {
484+ RTL8365MB_CPU_FORMAT_8BYTES = 0,
485+ RTL8365MB_CPU_FORMAT_4BYTES = 1,
486+};
487+
488+enum rtl8365mb_cpu_rxlen {
489+ RTL8365MB_CPU_RXLEN_72BYTES = 0,
490+ RTL8365MB_CPU_RXLEN_64BYTES = 1,
491+};
492+
493+/**
494+ * struct rtl8365mb_cpu - CPU port configuration
495+ * @enable: enable/disable hardware insertion of CPU tag in switch->CPU frames
496+ * @mask: port mask of ports that parse should parse CPU tags
497+ * @trap_port: forward trapped frames to this port
498+ * @insert: CPU tag insertion mode in switch->CPU frames
499+ * @position: position of CPU tag in frame
500+ * @rx_length: minimum CPU RX length
501+ * @format: CPU tag format
502+ *
503+ * Represents the CPU tagging and CPU port configuration of the switch. These
504+ * settings are configurable at runtime.
505+ */
506+struct rtl8365mb_cpu {
507+ bool enable;
508+ u32 mask;
509+ u32 trap_port;
510+ enum rtl8365mb_cpu_insert insert;
511+ enum rtl8365mb_cpu_position position;
512+ enum rtl8365mb_cpu_rxlen rx_length;
513+ enum rtl8365mb_cpu_format format;
514+};
515+
516+/**
517+ * struct rtl8365mb_port - private per-port data
518+ * @smi: pointer to parent realtek_smi data
519+ * @index: DSA port index, same as dsa_port::index
520+ * @stats: link statistics populated by rtl8365mb_stats_poll, ready for atomic
521+ * access via rtl8365mb_get_stats64
522+ * @stats_lock: protect the stats structure during read/update
523+ * @mib_work: delayed work for polling MIB counters
524+ */
525+struct rtl8365mb_port {
526+ struct realtek_smi *smi;
527+ unsigned int index;
528+ struct rtnl_link_stats64 stats;
529+ spinlock_t stats_lock;
530+ struct delayed_work mib_work;
531+};
532+
533+/**
534+ * struct rtl8365mb - private chip-specific driver data
535+ * @smi: pointer to parent realtek_smi data
536+ * @irq: registered IRQ or zero
537+ * @chip_id: chip identifier
538+ * @chip_ver: chip silicon revision
539+ * @port_mask: mask of all ports
540+ * @learn_limit_max: maximum number of L2 addresses the chip can learn
541+ * @cpu: CPU tagging and CPU port configuration for this chip
542+ * @mib_lock: prevent concurrent reads of MIB counters
543+ * @ports: per-port data
544+ * @jam_table: chip-specific initialization jam table
545+ * @jam_size: size of the chip's jam table
546+ *
547+ * Private data for this driver.
548+ */
549+struct rtl8365mb {
550+ struct realtek_smi *smi;
551+ int irq;
552+ u32 chip_id;
553+ u32 chip_ver;
554+ u32 port_mask;
555+ u32 learn_limit_max;
556+ struct rtl8365mb_cpu cpu;
557+ struct mutex mib_lock;
558+ struct rtl8365mb_port ports[RTL8365MB_MAX_NUM_PORTS];
559+ const struct rtl8365mb_jam_tbl_entry *jam_table;
560+ size_t jam_size;
561+};
562+
563+static int rtl8365mb_phy_poll_busy(struct realtek_smi *smi)
564+{
565+ u32 val;
566+
567+ return regmap_read_poll_timeout(smi->map,
568+ RTL8365MB_INDIRECT_ACCESS_STATUS_REG,
569+ val, !val, 10, 100);
570+}
571+
572+static int rtl8365mb_phy_ocp_prepare(struct realtek_smi *smi, int phy,
573+ u32 ocp_addr)
574+{
575+ u32 val;
576+ int ret;
577+
578+ /* Set OCP prefix */
579+ val = FIELD_GET(RTL8365MB_PHY_OCP_ADDR_PREFIX_MASK, ocp_addr);
580+ ret = regmap_update_bits(
581+ smi->map, RTL8365MB_GPHY_OCP_MSB_0_REG,
582+ RTL8365MB_GPHY_OCP_MSB_0_CFG_CPU_OCPADR_MASK,
583+ FIELD_PREP(RTL8365MB_GPHY_OCP_MSB_0_CFG_CPU_OCPADR_MASK, val));
584+ if (ret)
585+ return ret;
586+
587+ /* Set PHY register address */
588+ val = RTL8365MB_PHY_BASE;
589+ val |= FIELD_PREP(RTL8365MB_INDIRECT_ACCESS_ADDRESS_PHYNUM_MASK, phy);
590+ val |= FIELD_PREP(RTL8365MB_INDIRECT_ACCESS_ADDRESS_OCPADR_5_1_MASK,
591+ ocp_addr >> 1);
592+ val |= FIELD_PREP(RTL8365MB_INDIRECT_ACCESS_ADDRESS_OCPADR_9_6_MASK,
593+ ocp_addr >> 6);
594+ ret = regmap_write(smi->map, RTL8365MB_INDIRECT_ACCESS_ADDRESS_REG,
595+ val);
596+ if (ret)
597+ return ret;
598+
599+ return 0;
600+}
601+
602+static int rtl8365mb_phy_ocp_read(struct realtek_smi *smi, int phy,
603+ u32 ocp_addr, u16 *data)
604+{
605+ u32 val;
606+ int ret;
607+
608+ ret = rtl8365mb_phy_poll_busy(smi);
609+ if (ret)
610+ return ret;
611+
612+ ret = rtl8365mb_phy_ocp_prepare(smi, phy, ocp_addr);
613+ if (ret)
614+ return ret;
615+
616+ /* Execute read operation */
617+ val = FIELD_PREP(RTL8365MB_INDIRECT_ACCESS_CTRL_CMD_MASK,
618+ RTL8365MB_INDIRECT_ACCESS_CTRL_CMD_VALUE) |
619+ FIELD_PREP(RTL8365MB_INDIRECT_ACCESS_CTRL_RW_MASK,
620+ RTL8365MB_INDIRECT_ACCESS_CTRL_RW_READ);
621+ ret = regmap_write(smi->map, RTL8365MB_INDIRECT_ACCESS_CTRL_REG, val);
622+ if (ret)
623+ return ret;
624+
625+ ret = rtl8365mb_phy_poll_busy(smi);
626+ if (ret)
627+ return ret;
628+
629+ /* Get PHY register data */
630+ ret = regmap_read(smi->map, RTL8365MB_INDIRECT_ACCESS_READ_DATA_REG,
631+ &val);
632+ if (ret)
633+ return ret;
634+
635+ *data = val & 0xFFFF;
636+
637+ return 0;
638+}
639+
640+static int rtl8365mb_phy_ocp_write(struct realtek_smi *smi, int phy,
641+ u32 ocp_addr, u16 data)
642+{
643+ u32 val;
644+ int ret;
645+
646+ ret = rtl8365mb_phy_poll_busy(smi);
647+ if (ret)
648+ return ret;
649+
650+ ret = rtl8365mb_phy_ocp_prepare(smi, phy, ocp_addr);
651+ if (ret)
652+ return ret;
653+
654+ /* Set PHY register data */
655+ ret = regmap_write(smi->map, RTL8365MB_INDIRECT_ACCESS_WRITE_DATA_REG,
656+ data);
657+ if (ret)
658+ return ret;
659+
660+ /* Execute write operation */
661+ val = FIELD_PREP(RTL8365MB_INDIRECT_ACCESS_CTRL_CMD_MASK,
662+ RTL8365MB_INDIRECT_ACCESS_CTRL_CMD_VALUE) |
663+ FIELD_PREP(RTL8365MB_INDIRECT_ACCESS_CTRL_RW_MASK,
664+ RTL8365MB_INDIRECT_ACCESS_CTRL_RW_WRITE);
665+ ret = regmap_write(smi->map, RTL8365MB_INDIRECT_ACCESS_CTRL_REG, val);
666+ if (ret)
667+ return ret;
668+
669+ ret = rtl8365mb_phy_poll_busy(smi);
670+ if (ret)
671+ return ret;
672+
673+ return 0;
674+}
675+
676+static int rtl8365mb_phy_read(struct realtek_smi *smi, int phy, int regnum)
677+{
678+ u32 ocp_addr;
679+ u16 val;
680+ int ret;
681+
682+ if (regnum > RTL8365MB_PHYREGMAX)
683+ return -EINVAL;
684+
685+ ocp_addr = RTL8365MB_PHY_OCP_ADDR_PHYREG_BASE + regnum * 2;
686+
687+ ret = rtl8365mb_phy_ocp_read(smi, phy, ocp_addr, &val);
688+ if (ret) {
689+ dev_err(smi->dev,
690+ "failed to read PHY%d reg %02x @ %04x, ret %d\n", phy,
691+ regnum, ocp_addr, ret);
692+ return ret;
693+ }
694+
695+ dev_dbg(smi->dev, "read PHY%d register 0x%02x @ %04x, val <- %04x\n",
696+ phy, regnum, ocp_addr, val);
697+
698+ return val;
699+}
700+
701+static int rtl8365mb_phy_write(struct realtek_smi *smi, int phy, int regnum,
702+ u16 val)
703+{
704+ u32 ocp_addr;
705+ int ret;
706+
707+ if (regnum > RTL8365MB_PHYREGMAX)
708+ return -EINVAL;
709+
710+ ocp_addr = RTL8365MB_PHY_OCP_ADDR_PHYREG_BASE + regnum * 2;
711+
712+ ret = rtl8365mb_phy_ocp_write(smi, phy, ocp_addr, val);
713+ if (ret) {
714+ dev_err(smi->dev,
715+ "failed to write PHY%d reg %02x @ %04x, ret %d\n", phy,
716+ regnum, ocp_addr, ret);
717+ return ret;
718+ }
719+
720+ dev_dbg(smi->dev, "write PHY%d register 0x%02x @ %04x, val -> %04x\n",
721+ phy, regnum, ocp_addr, val);
722+
723+ return 0;
724+}
725+
726+static enum dsa_tag_protocol
727+rtl8365mb_get_tag_protocol(struct dsa_switch *ds, int port,
728+ enum dsa_tag_protocol mp)
729+{
730+ return DSA_TAG_PROTO_RTL8_4;
731+}
732+
733+static int rtl8365mb_ext_config_rgmii(struct realtek_smi *smi, int port,
734+ phy_interface_t interface)
735+{
736+ struct device_node *dn;
737+ struct dsa_port *dp;
738+ int tx_delay = 0;
739+ int rx_delay = 0;
740+ int ext_port;
741+ u32 val;
742+ int ret;
743+
744+ if (port == smi->cpu_port) {
745+ ext_port = 1;
746+ } else {
747+ dev_err(smi->dev, "only one EXT port is currently supported\n");
748+ return -EINVAL;
749+ }
750+
751+ dp = dsa_to_port(smi->ds, port);
752+ dn = dp->dn;
753+
754+ /* Set the RGMII TX/RX delay
755+ *
756+ * The Realtek vendor driver indicates the following possible
757+ * configuration settings:
758+ *
759+ * TX delay:
760+ * 0 = no delay, 1 = 2 ns delay
761+ * RX delay:
762+ * 0 = no delay, 7 = maximum delay
763+ * No units are specified, but there are a total of 8 steps.
764+ *
765+ * The vendor driver also states that this must be configured *before*
766+ * forcing the external interface into a particular mode, which is done
767+ * in the rtl8365mb_phylink_mac_link_{up,down} functions.
768+ *
769+ * Only configure an RGMII TX (resp. RX) delay if the
770+ * tx-internal-delay-ps (resp. rx-internal-delay-ps) OF property is
771+ * specified. We ignore the detail of the RGMII interface mode
772+ * (RGMII_{RXID, TXID, etc.}), as this is considered to be a PHY-only
773+ * property.
774+ *
775+ * For the RX delay, we assume that a register value of 4 corresponds to
776+ * 2 ns. But this is just an educated guess, so ignore all other values
777+ * to avoid too much confusion.
778+ */
779+ if (!of_property_read_u32(dn, "tx-internal-delay-ps", &val)) {
780+ val = val / 1000; /* convert to ns */
781+
782+ if (val == 0 || val == 2)
783+ tx_delay = val / 2;
784+ else
785+ dev_warn(smi->dev,
786+ "EXT port TX delay must be 0 or 2 ns\n");
787+ }
788+
789+ if (!of_property_read_u32(dn, "rx-internal-delay-ps", &val)) {
790+ val = val / 1000; /* convert to ns */
791+
792+ if (val == 0 || val == 2)
793+ rx_delay = val * 2;
794+ else
795+ dev_warn(smi->dev,
796+ "EXT port RX delay must be 0 to 2 ns\n");
797+ }
798+
799+ ret = regmap_update_bits(
800+ smi->map, RTL8365MB_EXT_RGMXF_REG(ext_port),
801+ RTL8365MB_EXT_RGMXF_TXDELAY_MASK |
802+ RTL8365MB_EXT_RGMXF_RXDELAY_MASK,
803+ FIELD_PREP(RTL8365MB_EXT_RGMXF_TXDELAY_MASK, tx_delay) |
804+ FIELD_PREP(RTL8365MB_EXT_RGMXF_RXDELAY_MASK, rx_delay));
805+ if (ret)
806+ return ret;
807+
808+ ret = regmap_update_bits(
809+ smi->map, RTL8365MB_DIGITAL_INTERFACE_SELECT_REG(ext_port),
810+ RTL8365MB_DIGITAL_INTERFACE_SELECT_MODE_MASK(ext_port),
811+ RTL8365MB_EXT_PORT_MODE_RGMII
812+ << RTL8365MB_DIGITAL_INTERFACE_SELECT_MODE_OFFSET(
813+ ext_port));
814+ if (ret)
815+ return ret;
816+
817+ return 0;
818+}
819+
820+static int rtl8365mb_ext_config_forcemode(struct realtek_smi *smi, int port,
821+ bool link, int speed, int duplex,
822+ bool tx_pause, bool rx_pause)
823+{
824+ u32 r_tx_pause;
825+ u32 r_rx_pause;
826+ u32 r_duplex;
827+ u32 r_speed;
828+ u32 r_link;
829+ int ext_port;
830+ int val;
831+ int ret;
832+
833+ if (port == smi->cpu_port) {
834+ ext_port = 1;
835+ } else {
836+ dev_err(smi->dev, "only one EXT port is currently supported\n");
837+ return -EINVAL;
838+ }
839+
840+ if (link) {
841+ /* Force the link up with the desired configuration */
842+ r_link = 1;
843+ r_rx_pause = rx_pause ? 1 : 0;
844+ r_tx_pause = tx_pause ? 1 : 0;
845+
846+ if (speed == SPEED_1000) {
847+ r_speed = RTL8365MB_PORT_SPEED_1000M;
848+ } else if (speed == SPEED_100) {
849+ r_speed = RTL8365MB_PORT_SPEED_100M;
850+ } else if (speed == SPEED_10) {
851+ r_speed = RTL8365MB_PORT_SPEED_10M;
852+ } else {
853+ dev_err(smi->dev, "unsupported port speed %s\n",
854+ phy_speed_to_str(speed));
855+ return -EINVAL;
856+ }
857+
858+ if (duplex == DUPLEX_FULL) {
859+ r_duplex = 1;
860+ } else if (duplex == DUPLEX_HALF) {
861+ r_duplex = 0;
862+ } else {
863+ dev_err(smi->dev, "unsupported duplex %s\n",
864+ phy_duplex_to_str(duplex));
865+ return -EINVAL;
866+ }
867+ } else {
868+ /* Force the link down and reset any programmed configuration */
869+ r_link = 0;
870+ r_tx_pause = 0;
871+ r_rx_pause = 0;
872+ r_speed = 0;
873+ r_duplex = 0;
874+ }
875+
876+ val = FIELD_PREP(RTL8365MB_DIGITAL_INTERFACE_FORCE_EN_MASK, 1) |
877+ FIELD_PREP(RTL8365MB_DIGITAL_INTERFACE_FORCE_TXPAUSE_MASK,
878+ r_tx_pause) |
879+ FIELD_PREP(RTL8365MB_DIGITAL_INTERFACE_FORCE_RXPAUSE_MASK,
880+ r_rx_pause) |
881+ FIELD_PREP(RTL8365MB_DIGITAL_INTERFACE_FORCE_LINK_MASK, r_link) |
882+ FIELD_PREP(RTL8365MB_DIGITAL_INTERFACE_FORCE_DUPLEX_MASK,
883+ r_duplex) |
884+ FIELD_PREP(RTL8365MB_DIGITAL_INTERFACE_FORCE_SPEED_MASK, r_speed);
885+ ret = regmap_write(smi->map,
886+ RTL8365MB_DIGITAL_INTERFACE_FORCE_REG(ext_port),
887+ val);
888+ if (ret)
889+ return ret;
890+
891+ return 0;
892+}
893+
894+static bool rtl8365mb_phy_mode_supported(struct dsa_switch *ds, int port,
895+ phy_interface_t interface)
896+{
897+ if (dsa_is_user_port(ds, port) &&
898+ (interface == PHY_INTERFACE_MODE_NA ||
899+ interface == PHY_INTERFACE_MODE_INTERNAL))
900+ /* Internal PHY */
901+ return true;
902+ else if (dsa_is_cpu_port(ds, port) &&
903+ phy_interface_mode_is_rgmii(interface))
904+ /* Extension MAC */
905+ return true;
906+
907+ return false;
908+}
909+
910+static void rtl8365mb_phylink_validate(struct dsa_switch *ds, int port,
911+ unsigned long *supported,
912+ struct phylink_link_state *state)
913+{
914+ struct realtek_smi *smi = ds->priv;
915+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0 };
916+
917+ /* include/linux/phylink.h says:
918+ * When @state->interface is %PHY_INTERFACE_MODE_NA, phylink
919+ * expects the MAC driver to return all supported link modes.
920+ */
921+ if (state->interface != PHY_INTERFACE_MODE_NA &&
922+ !rtl8365mb_phy_mode_supported(ds, port, state->interface)) {
923+ dev_err(smi->dev, "phy mode %s is unsupported on port %d\n",
924+ phy_modes(state->interface), port);
925+ linkmode_zero(supported);
926+ return;
927+ }
928+
929+ phylink_set_port_modes(mask);
930+
931+ phylink_set(mask, Autoneg);
932+ phylink_set(mask, Pause);
933+ phylink_set(mask, Asym_Pause);
934+
935+ phylink_set(mask, 10baseT_Half);
936+ phylink_set(mask, 10baseT_Full);
937+ phylink_set(mask, 100baseT_Half);
938+ phylink_set(mask, 100baseT_Full);
939+ phylink_set(mask, 1000baseT_Full);
940+
941+ linkmode_and(supported, supported, mask);
942+ linkmode_and(state->advertising, state->advertising, mask);
943+}
944+
945+static void rtl8365mb_phylink_mac_config(struct dsa_switch *ds, int port,
946+ unsigned int mode,
947+ const struct phylink_link_state *state)
948+{
949+ struct realtek_smi *smi = ds->priv;
950+ int ret;
951+
952+ if (!rtl8365mb_phy_mode_supported(ds, port, state->interface)) {
953+ dev_err(smi->dev, "phy mode %s is unsupported on port %d\n",
954+ phy_modes(state->interface), port);
955+ return;
956+ }
957+
958+ if (mode != MLO_AN_PHY && mode != MLO_AN_FIXED) {
959+ dev_err(smi->dev,
960+ "port %d supports only conventional PHY or fixed-link\n",
961+ port);
962+ return;
963+ }
964+
965+ if (phy_interface_mode_is_rgmii(state->interface)) {
966+ ret = rtl8365mb_ext_config_rgmii(smi, port, state->interface);
967+ if (ret)
968+ dev_err(smi->dev,
969+ "failed to configure RGMII mode on port %d: %d\n",
970+ port, ret);
971+ return;
972+ }
973+
974+ /* TODO: Implement MII and RMII modes, which the RTL8365MB-VC also
975+ * supports
976+ */
977+}
978+
979+static void rtl8365mb_phylink_mac_link_down(struct dsa_switch *ds, int port,
980+ unsigned int mode,
981+ phy_interface_t interface)
982+{
983+ struct realtek_smi *smi = ds->priv;
984+ struct rtl8365mb_port *p;
985+ struct rtl8365mb *mb;
986+ int ret;
987+
988+ mb = smi->chip_data;
989+ p = &mb->ports[port];
990+ cancel_delayed_work_sync(&p->mib_work);
991+
992+ if (phy_interface_mode_is_rgmii(interface)) {
993+ ret = rtl8365mb_ext_config_forcemode(smi, port, false, 0, 0,
994+ false, false);
995+ if (ret)
996+ dev_err(smi->dev,
997+ "failed to reset forced mode on port %d: %d\n",
998+ port, ret);
999+
1000+ return;
1001+ }
1002+}
1003+
1004+static void rtl8365mb_phylink_mac_link_up(struct dsa_switch *ds, int port,
1005+ unsigned int mode,
1006+ phy_interface_t interface,
1007+ struct phy_device *phydev, int speed,
1008+ int duplex, bool tx_pause,
1009+ bool rx_pause)
1010+{
1011+ struct realtek_smi *smi = ds->priv;
1012+ struct rtl8365mb_port *p;
1013+ struct rtl8365mb *mb;
1014+ int ret;
1015+
1016+ mb = smi->chip_data;
1017+ p = &mb->ports[port];
1018+ schedule_delayed_work(&p->mib_work, 0);
1019+
1020+ if (phy_interface_mode_is_rgmii(interface)) {
1021+ ret = rtl8365mb_ext_config_forcemode(smi, port, true, speed,
1022+ duplex, tx_pause,
1023+ rx_pause);
1024+ if (ret)
1025+ dev_err(smi->dev,
1026+ "failed to force mode on port %d: %d\n", port,
1027+ ret);
1028+
1029+ return;
1030+ }
1031+}
1032+
1033+static void rtl8365mb_port_stp_state_set(struct dsa_switch *ds, int port,
1034+ u8 state)
1035+{
1036+ struct realtek_smi *smi = ds->priv;
1037+ enum rtl8365mb_stp_state val;
1038+ int msti = 0;
1039+
1040+ switch (state) {
1041+ case BR_STATE_DISABLED:
1042+ val = RTL8365MB_STP_STATE_DISABLED;
1043+ break;
1044+ case BR_STATE_BLOCKING:
1045+ case BR_STATE_LISTENING:
1046+ val = RTL8365MB_STP_STATE_BLOCKING;
1047+ break;
1048+ case BR_STATE_LEARNING:
1049+ val = RTL8365MB_STP_STATE_LEARNING;
1050+ break;
1051+ case BR_STATE_FORWARDING:
1052+ val = RTL8365MB_STP_STATE_FORWARDING;
1053+ break;
1054+ default:
1055+ dev_err(smi->dev, "invalid STP state: %u\n", state);
1056+ return;
1057+ }
1058+
1059+ regmap_update_bits(smi->map, RTL8365MB_MSTI_CTRL_REG(msti, port),
1060+ RTL8365MB_MSTI_CTRL_PORT_STATE_MASK(port),
1061+ val << RTL8365MB_MSTI_CTRL_PORT_STATE_OFFSET(port));
1062+}
1063+
1064+static int rtl8365mb_port_set_learning(struct realtek_smi *smi, int port,
1065+ bool enable)
1066+{
1067+ struct rtl8365mb *mb = smi->chip_data;
1068+
1069+ /* Enable/disable learning by limiting the number of L2 addresses the
1070+ * port can learn. Realtek documentation states that a limit of zero
1071+ * disables learning. When enabling learning, set it to the chip's
1072+ * maximum.
1073+ */
1074+ return regmap_write(smi->map, RTL8365MB_LUT_PORT_LEARN_LIMIT_REG(port),
1075+ enable ? mb->learn_limit_max : 0);
1076+}
1077+
1078+static int rtl8365mb_port_set_isolation(struct realtek_smi *smi, int port,
1079+ u32 mask)
1080+{
1081+ return regmap_write(smi->map, RTL8365MB_PORT_ISOLATION_REG(port), mask);
1082+}
1083+
1084+static int rtl8365mb_mib_counter_read(struct realtek_smi *smi, int port,
1085+ u32 offset, u32 length, u64 *mibvalue)
1086+{
1087+ u64 tmpvalue = 0;
1088+ u32 val;
1089+ int ret;
1090+ int i;
1091+
1092+ /* The MIB address is an SRAM address. We request a particular address
1093+ * and then poll the control register before reading the value from some
1094+ * counter registers.
1095+ */
1096+ ret = regmap_write(smi->map, RTL8365MB_MIB_ADDRESS_REG,
1097+ RTL8365MB_MIB_ADDRESS(port, offset));
1098+ if (ret)
1099+ return ret;
1100+
1101+ /* Poll for completion */
1102+ ret = regmap_read_poll_timeout(smi->map, RTL8365MB_MIB_CTRL0_REG, val,
1103+ !(val & RTL8365MB_MIB_CTRL0_BUSY_MASK),
1104+ 10, 100);
1105+ if (ret)
1106+ return ret;
1107+
1108+ /* Presumably this indicates a MIB counter read failure */
1109+ if (val & RTL8365MB_MIB_CTRL0_RESET_MASK)
1110+ return -EIO;
1111+
1112+ /* There are four MIB counter registers each holding a 16 bit word of a
1113+ * MIB counter. Depending on the offset, we should read from the upper
1114+ * two or lower two registers. In case the MIB counter is 4 words, we
1115+ * read from all four registers.
1116+ */
1117+ if (length == 4)
1118+ offset = 3;
1119+ else
1120+ offset = (offset + 1) % 4;
1121+
1122+ /* Read the MIB counter 16 bits at a time */
1123+ for (i = 0; i < length; i++) {
1124+ ret = regmap_read(smi->map,
1125+ RTL8365MB_MIB_COUNTER_REG(offset - i), &val);
1126+ if (ret)
1127+ return ret;
1128+
1129+ tmpvalue = ((tmpvalue) << 16) | (val & 0xFFFF);
1130+ }
1131+
1132+ /* Only commit the result if no error occurred */
1133+ *mibvalue = tmpvalue;
1134+
1135+ return 0;
1136+}
1137+
1138+static void rtl8365mb_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data)
1139+{
1140+ struct realtek_smi *smi = ds->priv;
1141+ struct rtl8365mb *mb;
1142+ int ret;
1143+ int i;
1144+
1145+ mb = smi->chip_data;
1146+
1147+ mutex_lock(&mb->mib_lock);
1148+ for (i = 0; i < RTL8365MB_MIB_END; i++) {
1149+ struct rtl8365mb_mib_counter *mib = &rtl8365mb_mib_counters[i];
1150+
1151+ ret = rtl8365mb_mib_counter_read(smi, port, mib->offset,
1152+ mib->length, &data[i]);
1153+ if (ret) {
1154+ dev_err(smi->dev,
1155+ "failed to read port %d counters: %d\n", port,
1156+ ret);
1157+ break;
1158+ }
1159+ }
1160+ mutex_unlock(&mb->mib_lock);
1161+}
1162+
1163+static void rtl8365mb_get_strings(struct dsa_switch *ds, int port, u32 stringset, u8 *data)
1164+{
1165+ int i;
1166+
1167+ if (stringset != ETH_SS_STATS)
1168+ return;
1169+
1170+ for (i = 0; i < RTL8365MB_MIB_END; i++) {
1171+ struct rtl8365mb_mib_counter *mib = &rtl8365mb_mib_counters[i];
1172+
1173+ strncpy(data + i * ETH_GSTRING_LEN, mib->name, ETH_GSTRING_LEN);
1174+ }
1175+}
1176+
1177+static int rtl8365mb_get_sset_count(struct dsa_switch *ds, int port, int sset)
1178+{
1179+ if (sset != ETH_SS_STATS)
1180+ return -EOPNOTSUPP;
1181+
1182+ return RTL8365MB_MIB_END;
1183+}
1184+
1185+static void rtl8365mb_get_phy_stats(struct dsa_switch *ds, int port,
1186+ struct ethtool_eth_phy_stats *phy_stats)
1187+{
1188+ struct realtek_smi *smi = ds->priv;
1189+ struct rtl8365mb_mib_counter *mib;
1190+ struct rtl8365mb *mb;
1191+
1192+ mb = smi->chip_data;
1193+ mib = &rtl8365mb_mib_counters[RTL8365MB_MIB_dot3StatsSymbolErrors];
1194+
1195+ mutex_lock(&mb->mib_lock);
1196+ rtl8365mb_mib_counter_read(smi, port, mib->offset, mib->length,
1197+ &phy_stats->SymbolErrorDuringCarrier);
1198+ mutex_unlock(&mb->mib_lock);
1199+}
1200+
1201+static void rtl8365mb_get_mac_stats(struct dsa_switch *ds, int port,
1202+ struct ethtool_eth_mac_stats *mac_stats)
1203+{
1204+ u64 cnt[RTL8365MB_MIB_END] = {
1205+ [RTL8365MB_MIB_ifOutOctets] = 1,
1206+ [RTL8365MB_MIB_ifOutUcastPkts] = 1,
1207+ [RTL8365MB_MIB_ifOutMulticastPkts] = 1,
1208+ [RTL8365MB_MIB_ifOutBroadcastPkts] = 1,
1209+ [RTL8365MB_MIB_dot3OutPauseFrames] = 1,
1210+ [RTL8365MB_MIB_ifOutDiscards] = 1,
1211+ [RTL8365MB_MIB_ifInOctets] = 1,
1212+ [RTL8365MB_MIB_ifInUcastPkts] = 1,
1213+ [RTL8365MB_MIB_ifInMulticastPkts] = 1,
1214+ [RTL8365MB_MIB_ifInBroadcastPkts] = 1,
1215+ [RTL8365MB_MIB_dot3InPauseFrames] = 1,
1216+ [RTL8365MB_MIB_dot3StatsSingleCollisionFrames] = 1,
1217+ [RTL8365MB_MIB_dot3StatsMultipleCollisionFrames] = 1,
1218+ [RTL8365MB_MIB_dot3StatsFCSErrors] = 1,
1219+ [RTL8365MB_MIB_dot3StatsDeferredTransmissions] = 1,
1220+ [RTL8365MB_MIB_dot3StatsLateCollisions] = 1,
1221+ [RTL8365MB_MIB_dot3StatsExcessiveCollisions] = 1,
1222+
1223+ };
1224+ struct realtek_smi *smi = ds->priv;
1225+ struct rtl8365mb *mb;
1226+ int ret;
1227+ int i;
1228+
1229+ mb = smi->chip_data;
1230+
1231+ mutex_lock(&mb->mib_lock);
1232+ for (i = 0; i < RTL8365MB_MIB_END; i++) {
1233+ struct rtl8365mb_mib_counter *mib = &rtl8365mb_mib_counters[i];
1234+
1235+ /* Only fetch required MIB counters (marked = 1 above) */
1236+ if (!cnt[i])
1237+ continue;
1238+
1239+ ret = rtl8365mb_mib_counter_read(smi, port, mib->offset,
1240+ mib->length, &cnt[i]);
1241+ if (ret)
1242+ break;
1243+ }
1244+ mutex_unlock(&mb->mib_lock);
1245+
1246+ /* The RTL8365MB-VC exposes MIB objects, which we have to translate into
1247+ * IEEE 802.3 Managed Objects. This is not always completely faithful,
1248+ * but we try out best. See RFC 3635 for a detailed treatment of the
1249+ * subject.
1250+ */
1251+
1252+ mac_stats->FramesTransmittedOK = cnt[RTL8365MB_MIB_ifOutUcastPkts] +
1253+ cnt[RTL8365MB_MIB_ifOutMulticastPkts] +
1254+ cnt[RTL8365MB_MIB_ifOutBroadcastPkts] +
1255+ cnt[RTL8365MB_MIB_dot3OutPauseFrames] -
1256+ cnt[RTL8365MB_MIB_ifOutDiscards];
1257+ mac_stats->SingleCollisionFrames =
1258+ cnt[RTL8365MB_MIB_dot3StatsSingleCollisionFrames];
1259+ mac_stats->MultipleCollisionFrames =
1260+ cnt[RTL8365MB_MIB_dot3StatsMultipleCollisionFrames];
1261+ mac_stats->FramesReceivedOK = cnt[RTL8365MB_MIB_ifInUcastPkts] +
1262+ cnt[RTL8365MB_MIB_ifInMulticastPkts] +
1263+ cnt[RTL8365MB_MIB_ifInBroadcastPkts] +
1264+ cnt[RTL8365MB_MIB_dot3InPauseFrames];
1265+ mac_stats->FrameCheckSequenceErrors =
1266+ cnt[RTL8365MB_MIB_dot3StatsFCSErrors];
1267+ mac_stats->OctetsTransmittedOK = cnt[RTL8365MB_MIB_ifOutOctets] -
1268+ 18 * mac_stats->FramesTransmittedOK;
1269+ mac_stats->FramesWithDeferredXmissions =
1270+ cnt[RTL8365MB_MIB_dot3StatsDeferredTransmissions];
1271+ mac_stats->LateCollisions = cnt[RTL8365MB_MIB_dot3StatsLateCollisions];
1272+ mac_stats->FramesAbortedDueToXSColls =
1273+ cnt[RTL8365MB_MIB_dot3StatsExcessiveCollisions];
1274+ mac_stats->OctetsReceivedOK = cnt[RTL8365MB_MIB_ifInOctets] -
1275+ 18 * mac_stats->FramesReceivedOK;
1276+ mac_stats->MulticastFramesXmittedOK =
1277+ cnt[RTL8365MB_MIB_ifOutMulticastPkts];
1278+ mac_stats->BroadcastFramesXmittedOK =
1279+ cnt[RTL8365MB_MIB_ifOutBroadcastPkts];
1280+ mac_stats->MulticastFramesReceivedOK =
1281+ cnt[RTL8365MB_MIB_ifInMulticastPkts];
1282+ mac_stats->BroadcastFramesReceivedOK =
1283+ cnt[RTL8365MB_MIB_ifInBroadcastPkts];
1284+}
1285+
1286+static void rtl8365mb_get_ctrl_stats(struct dsa_switch *ds, int port,
1287+ struct ethtool_eth_ctrl_stats *ctrl_stats)
1288+{
1289+ struct realtek_smi *smi = ds->priv;
1290+ struct rtl8365mb_mib_counter *mib;
1291+ struct rtl8365mb *mb;
1292+
1293+ mb = smi->chip_data;
1294+ mib = &rtl8365mb_mib_counters[RTL8365MB_MIB_dot3ControlInUnknownOpcodes];
1295+
1296+ mutex_lock(&mb->mib_lock);
1297+ rtl8365mb_mib_counter_read(smi, port, mib->offset, mib->length,
1298+ &ctrl_stats->UnsupportedOpcodesReceived);
1299+ mutex_unlock(&mb->mib_lock);
1300+}
1301+
1302+static void rtl8365mb_stats_update(struct realtek_smi *smi, int port)
1303+{
1304+ u64 cnt[RTL8365MB_MIB_END] = {
1305+ [RTL8365MB_MIB_ifOutOctets] = 1,
1306+ [RTL8365MB_MIB_ifOutUcastPkts] = 1,
1307+ [RTL8365MB_MIB_ifOutMulticastPkts] = 1,
1308+ [RTL8365MB_MIB_ifOutBroadcastPkts] = 1,
1309+ [RTL8365MB_MIB_ifOutDiscards] = 1,
1310+ [RTL8365MB_MIB_ifInOctets] = 1,
1311+ [RTL8365MB_MIB_ifInUcastPkts] = 1,
1312+ [RTL8365MB_MIB_ifInMulticastPkts] = 1,
1313+ [RTL8365MB_MIB_ifInBroadcastPkts] = 1,
1314+ [RTL8365MB_MIB_etherStatsDropEvents] = 1,
1315+ [RTL8365MB_MIB_etherStatsCollisions] = 1,
1316+ [RTL8365MB_MIB_etherStatsFragments] = 1,
1317+ [RTL8365MB_MIB_etherStatsJabbers] = 1,
1318+ [RTL8365MB_MIB_dot3StatsFCSErrors] = 1,
1319+ [RTL8365MB_MIB_dot3StatsLateCollisions] = 1,
1320+ };
1321+ struct rtl8365mb *mb = smi->chip_data;
1322+ struct rtnl_link_stats64 *stats;
1323+ int ret;
1324+ int i;
1325+
1326+ stats = &mb->ports[port].stats;
1327+
1328+ mutex_lock(&mb->mib_lock);
1329+ for (i = 0; i < RTL8365MB_MIB_END; i++) {
1330+ struct rtl8365mb_mib_counter *c = &rtl8365mb_mib_counters[i];
1331+
1332+ /* Only fetch required MIB counters (marked = 1 above) */
1333+ if (!cnt[i])
1334+ continue;
1335+
1336+ ret = rtl8365mb_mib_counter_read(smi, port, c->offset,
1337+ c->length, &cnt[i]);
1338+ if (ret)
1339+ break;
1340+ }
1341+ mutex_unlock(&mb->mib_lock);
1342+
1343+ /* Don't update statistics if there was an error reading the counters */
1344+ if (ret)
1345+ return;
1346+
1347+ spin_lock(&mb->ports[port].stats_lock);
1348+
1349+ stats->rx_packets = cnt[RTL8365MB_MIB_ifInUcastPkts] +
1350+ cnt[RTL8365MB_MIB_ifInMulticastPkts] +
1351+ cnt[RTL8365MB_MIB_ifInBroadcastPkts] -
1352+ cnt[RTL8365MB_MIB_ifOutDiscards];
1353+
1354+ stats->tx_packets = cnt[RTL8365MB_MIB_ifOutUcastPkts] +
1355+ cnt[RTL8365MB_MIB_ifOutMulticastPkts] +
1356+ cnt[RTL8365MB_MIB_ifOutBroadcastPkts];
1357+
1358+ /* if{In,Out}Octets includes FCS - remove it */
1359+ stats->rx_bytes = cnt[RTL8365MB_MIB_ifInOctets] - 4 * stats->rx_packets;
1360+ stats->tx_bytes =
1361+ cnt[RTL8365MB_MIB_ifOutOctets] - 4 * stats->tx_packets;
1362+
1363+ stats->rx_dropped = cnt[RTL8365MB_MIB_etherStatsDropEvents];
1364+ stats->tx_dropped = cnt[RTL8365MB_MIB_ifOutDiscards];
1365+
1366+ stats->multicast = cnt[RTL8365MB_MIB_ifInMulticastPkts];
1367+ stats->collisions = cnt[RTL8365MB_MIB_etherStatsCollisions];
1368+
1369+ stats->rx_length_errors = cnt[RTL8365MB_MIB_etherStatsFragments] +
1370+ cnt[RTL8365MB_MIB_etherStatsJabbers];
1371+ stats->rx_crc_errors = cnt[RTL8365MB_MIB_dot3StatsFCSErrors];
1372+ stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors;
1373+
1374+ stats->tx_aborted_errors = cnt[RTL8365MB_MIB_ifOutDiscards];
1375+ stats->tx_window_errors = cnt[RTL8365MB_MIB_dot3StatsLateCollisions];
1376+ stats->tx_errors = stats->tx_aborted_errors + stats->tx_window_errors;
1377+
1378+ spin_unlock(&mb->ports[port].stats_lock);
1379+}
1380+
1381+static void rtl8365mb_stats_poll(struct work_struct *work)
1382+{
1383+ struct rtl8365mb_port *p = container_of(to_delayed_work(work),
1384+ struct rtl8365mb_port,
1385+ mib_work);
1386+ struct realtek_smi *smi = p->smi;
1387+
1388+ rtl8365mb_stats_update(smi, p->index);
1389+
1390+ schedule_delayed_work(&p->mib_work, RTL8365MB_STATS_INTERVAL_JIFFIES);
1391+}
1392+
1393+static void rtl8365mb_get_stats64(struct dsa_switch *ds, int port,
1394+ struct rtnl_link_stats64 *s)
1395+{
1396+ struct realtek_smi *smi = ds->priv;
1397+ struct rtl8365mb_port *p;
1398+ struct rtl8365mb *mb;
1399+
1400+ mb = smi->chip_data;
1401+ p = &mb->ports[port];
1402+
1403+ spin_lock(&p->stats_lock);
1404+ memcpy(s, &p->stats, sizeof(*s));
1405+ spin_unlock(&p->stats_lock);
1406+}
1407+
1408+static void rtl8365mb_stats_setup(struct realtek_smi *smi)
1409+{
1410+ struct rtl8365mb *mb = smi->chip_data;
1411+ int i;
1412+
1413+ /* Per-chip global mutex to protect MIB counter access, since doing
1414+ * so requires accessing a series of registers in a particular order.
1415+ */
1416+ mutex_init(&mb->mib_lock);
1417+
1418+ for (i = 0; i < smi->num_ports; i++) {
1419+ struct rtl8365mb_port *p = &mb->ports[i];
1420+
1421+ if (dsa_is_unused_port(smi->ds, i))
1422+ continue;
1423+
1424+ /* Per-port spinlock to protect the stats64 data */
1425+ spin_lock_init(&p->stats_lock);
1426+
1427+ /* This work polls the MIB counters and keeps the stats64 data
1428+ * up-to-date.
1429+ */
1430+ INIT_DELAYED_WORK(&p->mib_work, rtl8365mb_stats_poll);
1431+ }
1432+}
1433+
1434+static void rtl8365mb_stats_teardown(struct realtek_smi *smi)
1435+{
1436+ struct rtl8365mb *mb = smi->chip_data;
1437+ int i;
1438+
1439+ for (i = 0; i < smi->num_ports; i++) {
1440+ struct rtl8365mb_port *p = &mb->ports[i];
1441+
1442+ if (dsa_is_unused_port(smi->ds, i))
1443+ continue;
1444+
1445+ cancel_delayed_work_sync(&p->mib_work);
1446+ }
1447+}
1448+
1449+static int rtl8365mb_get_and_clear_status_reg(struct realtek_smi *smi, u32 reg,
1450+ u32 *val)
1451+{
1452+ int ret;
1453+
1454+ ret = regmap_read(smi->map, reg, val);
1455+ if (ret)
1456+ return ret;
1457+
1458+ return regmap_write(smi->map, reg, *val);
1459+}
1460+
1461+static irqreturn_t rtl8365mb_irq(int irq, void *data)
1462+{
1463+ struct realtek_smi *smi = data;
1464+ unsigned long line_changes = 0;
1465+ struct rtl8365mb *mb;
1466+ u32 stat;
1467+ int line;
1468+ int ret;
1469+
1470+ mb = smi->chip_data;
1471+
1472+ ret = rtl8365mb_get_and_clear_status_reg(smi, RTL8365MB_INTR_STATUS_REG,
1473+ &stat);
1474+ if (ret)
1475+ goto out_error;
1476+
1477+ if (stat & RTL8365MB_INTR_LINK_CHANGE_MASK) {
1478+ u32 linkdown_ind;
1479+ u32 linkup_ind;
1480+ u32 val;
1481+
1482+ ret = rtl8365mb_get_and_clear_status_reg(
1483+ smi, RTL8365MB_PORT_LINKUP_IND_REG, &val);
1484+ if (ret)
1485+ goto out_error;
1486+
1487+ linkup_ind = FIELD_GET(RTL8365MB_PORT_LINKUP_IND_MASK, val);
1488+
1489+ ret = rtl8365mb_get_and_clear_status_reg(
1490+ smi, RTL8365MB_PORT_LINKDOWN_IND_REG, &val);
1491+ if (ret)
1492+ goto out_error;
1493+
1494+ linkdown_ind = FIELD_GET(RTL8365MB_PORT_LINKDOWN_IND_MASK, val);
1495+
1496+ line_changes = (linkup_ind | linkdown_ind) & mb->port_mask;
1497+ }
1498+
1499+ if (!line_changes)
1500+ goto out_none;
1501+
1502+ for_each_set_bit(line, &line_changes, smi->num_ports) {
1503+ int child_irq = irq_find_mapping(smi->irqdomain, line);
1504+
1505+ handle_nested_irq(child_irq);
1506+ }
1507+
1508+ return IRQ_HANDLED;
1509+
1510+out_error:
1511+ dev_err(smi->dev, "failed to read interrupt status: %d\n", ret);
1512+
1513+out_none:
1514+ return IRQ_NONE;
1515+}
1516+
1517+static struct irq_chip rtl8365mb_irq_chip = {
1518+ .name = "rtl8365mb",
1519+ /* The hardware doesn't support masking IRQs on a per-port basis */
1520+};
1521+
1522+static int rtl8365mb_irq_map(struct irq_domain *domain, unsigned int irq,
1523+ irq_hw_number_t hwirq)
1524+{
1525+ irq_set_chip_data(irq, domain->host_data);
1526+ irq_set_chip_and_handler(irq, &rtl8365mb_irq_chip, handle_simple_irq);
1527+ irq_set_nested_thread(irq, 1);
1528+ irq_set_noprobe(irq);
1529+
1530+ return 0;
1531+}
1532+
1533+static void rtl8365mb_irq_unmap(struct irq_domain *d, unsigned int irq)
1534+{
1535+ irq_set_nested_thread(irq, 0);
1536+ irq_set_chip_and_handler(irq, NULL, NULL);
1537+ irq_set_chip_data(irq, NULL);
1538+}
1539+
1540+static const struct irq_domain_ops rtl8365mb_irqdomain_ops = {
1541+ .map = rtl8365mb_irq_map,
1542+ .unmap = rtl8365mb_irq_unmap,
1543+ .xlate = irq_domain_xlate_onecell,
1544+};
1545+
1546+static int rtl8365mb_set_irq_enable(struct realtek_smi *smi, bool enable)
1547+{
1548+ return regmap_update_bits(smi->map, RTL8365MB_INTR_CTRL_REG,
1549+ RTL8365MB_INTR_LINK_CHANGE_MASK,
1550+ FIELD_PREP(RTL8365MB_INTR_LINK_CHANGE_MASK,
1551+ enable ? 1 : 0));
1552+}
1553+
1554+static int rtl8365mb_irq_enable(struct realtek_smi *smi)
1555+{
1556+ return rtl8365mb_set_irq_enable(smi, true);
1557+}
1558+
1559+static int rtl8365mb_irq_disable(struct realtek_smi *smi)
1560+{
1561+ return rtl8365mb_set_irq_enable(smi, false);
1562+}
1563+
1564+static int rtl8365mb_irq_setup(struct realtek_smi *smi)
1565+{
1566+ struct rtl8365mb *mb = smi->chip_data;
1567+ struct device_node *intc;
1568+ u32 irq_trig;
1569+ int virq;
1570+ int irq;
1571+ u32 val;
1572+ int ret;
1573+ int i;
1574+
1575+ intc = of_get_child_by_name(smi->dev->of_node, "interrupt-controller");
1576+ if (!intc) {
1577+ dev_err(smi->dev, "missing child interrupt-controller node\n");
1578+ return -EINVAL;
1579+ }
1580+
1581+ /* rtl8365mb IRQs cascade off this one */
1582+ irq = of_irq_get(intc, 0);
1583+ if (irq <= 0) {
1584+ if (irq != -EPROBE_DEFER)
1585+ dev_err(smi->dev, "failed to get parent irq: %d\n",
1586+ irq);
1587+ ret = irq ? irq : -EINVAL;
1588+ goto out_put_node;
1589+ }
1590+
1591+ smi->irqdomain = irq_domain_add_linear(intc, smi->num_ports,
1592+ &rtl8365mb_irqdomain_ops, smi);
1593+ if (!smi->irqdomain) {
1594+ dev_err(smi->dev, "failed to add irq domain\n");
1595+ ret = -ENOMEM;
1596+ goto out_put_node;
1597+ }
1598+
1599+ for (i = 0; i < smi->num_ports; i++) {
1600+ virq = irq_create_mapping(smi->irqdomain, i);
1601+ if (!virq) {
1602+ dev_err(smi->dev,
1603+ "failed to create irq domain mapping\n");
1604+ ret = -EINVAL;
1605+ goto out_remove_irqdomain;
1606+ }
1607+
1608+ irq_set_parent(virq, irq);
1609+ }
1610+
1611+ /* Configure chip interrupt signal polarity */
1612+ irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq));
1613+ switch (irq_trig) {
1614+ case IRQF_TRIGGER_RISING:
1615+ case IRQF_TRIGGER_HIGH:
1616+ val = RTL8365MB_INTR_POLARITY_HIGH;
1617+ break;
1618+ case IRQF_TRIGGER_FALLING:
1619+ case IRQF_TRIGGER_LOW:
1620+ val = RTL8365MB_INTR_POLARITY_LOW;
1621+ break;
1622+ default:
1623+ dev_err(smi->dev, "unsupported irq trigger type %u\n",
1624+ irq_trig);
1625+ ret = -EINVAL;
1626+ goto out_remove_irqdomain;
1627+ }
1628+
1629+ ret = regmap_update_bits(smi->map, RTL8365MB_INTR_POLARITY_REG,
1630+ RTL8365MB_INTR_POLARITY_MASK,
1631+ FIELD_PREP(RTL8365MB_INTR_POLARITY_MASK, val));
1632+ if (ret)
1633+ goto out_remove_irqdomain;
1634+
1635+ /* Disable the interrupt in case the chip has it enabled on reset */
1636+ ret = rtl8365mb_irq_disable(smi);
1637+ if (ret)
1638+ goto out_remove_irqdomain;
1639+
1640+ /* Clear the interrupt status register */
1641+ ret = regmap_write(smi->map, RTL8365MB_INTR_STATUS_REG,
1642+ RTL8365MB_INTR_ALL_MASK);
1643+ if (ret)
1644+ goto out_remove_irqdomain;
1645+
1646+ ret = request_threaded_irq(irq, NULL, rtl8365mb_irq, IRQF_ONESHOT,
1647+ "rtl8365mb", smi);
1648+ if (ret) {
1649+ dev_err(smi->dev, "failed to request irq: %d\n", ret);
1650+ goto out_remove_irqdomain;
1651+ }
1652+
1653+ /* Store the irq so that we know to free it during teardown */
1654+ mb->irq = irq;
1655+
1656+ ret = rtl8365mb_irq_enable(smi);
1657+ if (ret)
1658+ goto out_free_irq;
1659+
1660+ of_node_put(intc);
1661+
1662+ return 0;
1663+
1664+out_free_irq:
1665+ free_irq(mb->irq, smi);
1666+ mb->irq = 0;
1667+
1668+out_remove_irqdomain:
1669+ for (i = 0; i < smi->num_ports; i++) {
1670+ virq = irq_find_mapping(smi->irqdomain, i);
1671+ irq_dispose_mapping(virq);
1672+ }
1673+
1674+ irq_domain_remove(smi->irqdomain);
1675+ smi->irqdomain = NULL;
1676+
1677+out_put_node:
1678+ of_node_put(intc);
1679+
1680+ return ret;
1681+}
1682+
1683+static void rtl8365mb_irq_teardown(struct realtek_smi *smi)
1684+{
1685+ struct rtl8365mb *mb = smi->chip_data;
1686+ int virq;
1687+ int i;
1688+
1689+ if (mb->irq) {
1690+ free_irq(mb->irq, smi);
1691+ mb->irq = 0;
1692+ }
1693+
1694+ if (smi->irqdomain) {
1695+ for (i = 0; i < smi->num_ports; i++) {
1696+ virq = irq_find_mapping(smi->irqdomain, i);
1697+ irq_dispose_mapping(virq);
1698+ }
1699+
1700+ irq_domain_remove(smi->irqdomain);
1701+ smi->irqdomain = NULL;
1702+ }
1703+}
1704+
1705+static int rtl8365mb_cpu_config(struct realtek_smi *smi)
1706+{
1707+ struct rtl8365mb *mb = smi->chip_data;
1708+ struct rtl8365mb_cpu *cpu = &mb->cpu;
1709+ u32 val;
1710+ int ret;
1711+
1712+ ret = regmap_update_bits(smi->map, RTL8365MB_CPU_PORT_MASK_REG,
1713+ RTL8365MB_CPU_PORT_MASK_MASK,
1714+ FIELD_PREP(RTL8365MB_CPU_PORT_MASK_MASK,
1715+ cpu->mask));
1716+ if (ret)
1717+ return ret;
1718+
1719+ val = FIELD_PREP(RTL8365MB_CPU_CTRL_EN_MASK, cpu->enable ? 1 : 0) |
1720+ FIELD_PREP(RTL8365MB_CPU_CTRL_INSERTMODE_MASK, cpu->insert) |
1721+ FIELD_PREP(RTL8365MB_CPU_CTRL_TAG_POSITION_MASK, cpu->position) |
1722+ FIELD_PREP(RTL8365MB_CPU_CTRL_RXBYTECOUNT_MASK, cpu->rx_length) |
1723+ FIELD_PREP(RTL8365MB_CPU_CTRL_TAG_FORMAT_MASK, cpu->format) |
1724+ FIELD_PREP(RTL8365MB_CPU_CTRL_TRAP_PORT_MASK, cpu->trap_port) |
1725+ FIELD_PREP(RTL8365MB_CPU_CTRL_TRAP_PORT_EXT_MASK,
1726+ cpu->trap_port >> 3);
1727+ ret = regmap_write(smi->map, RTL8365MB_CPU_CTRL_REG, val);
1728+ if (ret)
1729+ return ret;
1730+
1731+ return 0;
1732+}
1733+
1734+static int rtl8365mb_switch_init(struct realtek_smi *smi)
1735+{
1736+ struct rtl8365mb *mb = smi->chip_data;
1737+ int ret;
1738+ int i;
1739+
1740+ /* Do any chip-specific init jam before getting to the common stuff */
1741+ if (mb->jam_table) {
1742+ for (i = 0; i < mb->jam_size; i++) {
1743+ ret = regmap_write(smi->map, mb->jam_table[i].reg,
1744+ mb->jam_table[i].val);
1745+ if (ret)
1746+ return ret;
1747+ }
1748+ }
1749+
1750+ /* Common init jam */
1751+ for (i = 0; i < ARRAY_SIZE(rtl8365mb_init_jam_common); i++) {
1752+ ret = regmap_write(smi->map, rtl8365mb_init_jam_common[i].reg,
1753+ rtl8365mb_init_jam_common[i].val);
1754+ if (ret)
1755+ return ret;
1756+ }
1757+
1758+ return 0;
1759+}
1760+
1761+static int rtl8365mb_reset_chip(struct realtek_smi *smi)
1762+{
1763+ u32 val;
1764+
1765+ realtek_smi_write_reg_noack(smi, RTL8365MB_CHIP_RESET_REG,
1766+ FIELD_PREP(RTL8365MB_CHIP_RESET_HW_MASK,
1767+ 1));
1768+
1769+ /* Realtek documentation says the chip needs 1 second to reset. Sleep
1770+ * for 100 ms before accessing any registers to prevent ACK timeouts.
1771+ */
1772+ msleep(100);
1773+ return regmap_read_poll_timeout(smi->map, RTL8365MB_CHIP_RESET_REG, val,
1774+ !(val & RTL8365MB_CHIP_RESET_HW_MASK),
1775+ 20000, 1e6);
1776+}
1777+
1778+static int rtl8365mb_setup(struct dsa_switch *ds)
1779+{
1780+ struct realtek_smi *smi = ds->priv;
1781+ struct rtl8365mb *mb;
1782+ int ret;
1783+ int i;
1784+
1785+ mb = smi->chip_data;
1786+
1787+ ret = rtl8365mb_reset_chip(smi);
1788+ if (ret) {
1789+ dev_err(smi->dev, "failed to reset chip: %d\n", ret);
1790+ goto out_error;
1791+ }
1792+
1793+ /* Configure switch to vendor-defined initial state */
1794+ ret = rtl8365mb_switch_init(smi);
1795+ if (ret) {
1796+ dev_err(smi->dev, "failed to initialize switch: %d\n", ret);
1797+ goto out_error;
1798+ }
1799+
1800+ /* Set up cascading IRQs */
1801+ ret = rtl8365mb_irq_setup(smi);
1802+ if (ret == -EPROBE_DEFER)
1803+ return ret;
1804+ else if (ret)
1805+ dev_info(smi->dev, "no interrupt support\n");
1806+
1807+ /* Configure CPU tagging */
1808+ ret = rtl8365mb_cpu_config(smi);
1809+ if (ret)
1810+ goto out_teardown_irq;
1811+
1812+ /* Configure ports */
1813+ for (i = 0; i < smi->num_ports; i++) {
1814+ struct rtl8365mb_port *p = &mb->ports[i];
1815+
1816+ if (dsa_is_unused_port(smi->ds, i))
1817+ continue;
1818+
1819+ /* Set up per-port private data */
1820+ p->smi = smi;
1821+ p->index = i;
1822+
1823+ /* Forward only to the CPU */
1824+ ret = rtl8365mb_port_set_isolation(smi, i, BIT(smi->cpu_port));
1825+ if (ret)
1826+ goto out_teardown_irq;
1827+
1828+ /* Disable learning */
1829+ ret = rtl8365mb_port_set_learning(smi, i, false);
1830+ if (ret)
1831+ goto out_teardown_irq;
1832+
1833+ /* Set the initial STP state of all ports to DISABLED, otherwise
1834+ * ports will still forward frames to the CPU despite being
1835+ * administratively down by default.
1836+ */
1837+ rtl8365mb_port_stp_state_set(smi->ds, i, BR_STATE_DISABLED);
1838+ }
1839+
1840+ /* Set maximum packet length to 1536 bytes */
1841+ ret = regmap_update_bits(smi->map, RTL8365MB_CFG0_MAX_LEN_REG,
1842+ RTL8365MB_CFG0_MAX_LEN_MASK,
1843+ FIELD_PREP(RTL8365MB_CFG0_MAX_LEN_MASK, 1536));
1844+ if (ret)
1845+ goto out_teardown_irq;
1846+
1847+ ret = realtek_smi_setup_mdio(smi);
1848+ if (ret) {
1849+ dev_err(smi->dev, "could not set up MDIO bus\n");
1850+ goto out_teardown_irq;
1851+ }
1852+
1853+ /* Start statistics counter polling */
1854+ rtl8365mb_stats_setup(smi);
1855+
1856+ return 0;
1857+
1858+out_teardown_irq:
1859+ rtl8365mb_irq_teardown(smi);
1860+
1861+out_error:
1862+ return ret;
1863+}
1864+
1865+static void rtl8365mb_teardown(struct dsa_switch *ds)
1866+{
1867+ struct realtek_smi *smi = ds->priv;
1868+
1869+ rtl8365mb_stats_teardown(smi);
1870+ rtl8365mb_irq_teardown(smi);
1871+}
1872+
1873+static int rtl8365mb_get_chip_id_and_ver(struct regmap *map, u32 *id, u32 *ver)
1874+{
1875+ int ret;
1876+
1877+ /* For some reason we have to write a magic value to an arbitrary
1878+ * register whenever accessing the chip ID/version registers.
1879+ */
1880+ ret = regmap_write(map, RTL8365MB_MAGIC_REG, RTL8365MB_MAGIC_VALUE);
1881+ if (ret)
1882+ return ret;
1883+
1884+ ret = regmap_read(map, RTL8365MB_CHIP_ID_REG, id);
1885+ if (ret)
1886+ return ret;
1887+
1888+ ret = regmap_read(map, RTL8365MB_CHIP_VER_REG, ver);
1889+ if (ret)
1890+ return ret;
1891+
1892+ /* Reset magic register */
1893+ ret = regmap_write(map, RTL8365MB_MAGIC_REG, 0);
1894+ if (ret)
1895+ return ret;
1896+
1897+ return 0;
1898+}
1899+
1900+static int rtl8365mb_detect(struct realtek_smi *smi)
1901+{
1902+ struct rtl8365mb *mb = smi->chip_data;
1903+ u32 chip_id;
1904+ u32 chip_ver;
1905+ int ret;
1906+
1907+ ret = rtl8365mb_get_chip_id_and_ver(smi->map, &chip_id, &chip_ver);
1908+ if (ret) {
1909+ dev_err(smi->dev, "failed to read chip id and version: %d\n",
1910+ ret);
1911+ return ret;
1912+ }
1913+
1914+ switch (chip_id) {
1915+ case RTL8365MB_CHIP_ID_8365MB_VC:
1916+ dev_info(smi->dev,
1917+ "found an RTL8365MB-VC switch (ver=0x%04x)\n",
1918+ chip_ver);
1919+
1920+ smi->cpu_port = RTL8365MB_CPU_PORT_NUM_8365MB_VC;
1921+ smi->num_ports = smi->cpu_port + 1;
1922+
1923+ mb->smi = smi;
1924+ mb->chip_id = chip_id;
1925+ mb->chip_ver = chip_ver;
1926+ mb->port_mask = BIT(smi->num_ports) - 1;
1927+ mb->learn_limit_max = RTL8365MB_LEARN_LIMIT_MAX_8365MB_VC;
1928+ mb->jam_table = rtl8365mb_init_jam_8365mb_vc;
1929+ mb->jam_size = ARRAY_SIZE(rtl8365mb_init_jam_8365mb_vc);
1930+
1931+ mb->cpu.enable = 1;
1932+ mb->cpu.mask = BIT(smi->cpu_port);
1933+ mb->cpu.trap_port = smi->cpu_port;
1934+ mb->cpu.insert = RTL8365MB_CPU_INSERT_TO_ALL;
1935+ mb->cpu.position = RTL8365MB_CPU_POS_AFTER_SA;
1936+ mb->cpu.rx_length = RTL8365MB_CPU_RXLEN_64BYTES;
1937+ mb->cpu.format = RTL8365MB_CPU_FORMAT_8BYTES;
1938+
1939+ break;
1940+ default:
1941+ dev_err(smi->dev,
1942+ "found an unknown Realtek switch (id=0x%04x, ver=0x%04x)\n",
1943+ chip_id, chip_ver);
1944+ return -ENODEV;
1945+ }
1946+
1947+ return 0;
1948+}
1949+
1950+static const struct dsa_switch_ops rtl8365mb_switch_ops = {
1951+ .get_tag_protocol = rtl8365mb_get_tag_protocol,
1952+ .setup = rtl8365mb_setup,
1953+ .teardown = rtl8365mb_teardown,
1954+ .phylink_validate = rtl8365mb_phylink_validate,
1955+ .phylink_mac_config = rtl8365mb_phylink_mac_config,
1956+ .phylink_mac_link_down = rtl8365mb_phylink_mac_link_down,
1957+ .phylink_mac_link_up = rtl8365mb_phylink_mac_link_up,
1958+ .port_stp_state_set = rtl8365mb_port_stp_state_set,
1959+ .get_strings = rtl8365mb_get_strings,
1960+ .get_ethtool_stats = rtl8365mb_get_ethtool_stats,
1961+ .get_sset_count = rtl8365mb_get_sset_count,
1962+ .get_eth_phy_stats = rtl8365mb_get_phy_stats,
1963+ .get_eth_mac_stats = rtl8365mb_get_mac_stats,
1964+ .get_eth_ctrl_stats = rtl8365mb_get_ctrl_stats,
1965+ .get_stats64 = rtl8365mb_get_stats64,
1966+};
1967+
1968+static const struct realtek_smi_ops rtl8365mb_smi_ops = {
1969+ .detect = rtl8365mb_detect,
1970+ .phy_read = rtl8365mb_phy_read,
1971+ .phy_write = rtl8365mb_phy_write,
1972+};
1973+
1974+const struct realtek_smi_variant rtl8365mb_variant = {
1975+ .ds_ops = &rtl8365mb_switch_ops,
1976+ .ops = &rtl8365mb_smi_ops,
1977+ .clk_delay = 10,
1978+ .cmd_read = 0xb9,
1979+ .cmd_write = 0xb8,
1980+ .chip_data_sz = sizeof(struct rtl8365mb),
1981+};
1982+EXPORT_SYMBOL_GPL(rtl8365mb_variant);
drivers/net/phy/realtek.c+8−0
@@ -1023,6 +1023,14 @@ static struct phy_driver realtek_drvs[] = { · 1022 unmodified lines
10231023 .resume = genphy_resume,
10241024 .read_page = rtl821x_read_page,
10251025 .write_page = rtl821x_write_page,
1026+ }, {
1027+ PHY_ID_MATCH_EXACT(0x001cc942),
1028+ .name = "RTL8365MB-VC Gigabit Ethernet",
1029+ /* Interrupt handling analogous to RTL8366RB */
1030+ .config_intr = genphy_no_config_intr,
1031+ .handle_interrupt = genphy_handle_interrupt_no_ack,
1032+ .suspend = genphy_suspend,
1033+ .resume = genphy_resume,
10261034 },
10271035 };
10281036
include/net/dsa.h+8−0
@@ -51,6 +51,7 @@ struct phylink_link_state; · 50 unmodified lines
5151 #define DSA_TAG_PROTO_SEVILLE_VALUE 21
5252 #define DSA_TAG_PROTO_BRCM_LEGACY_VALUE 22
5353 #define DSA_TAG_PROTO_SJA1110_VALUE 23
54+#define DSA_TAG_PROTO_RTL8_4_VALUE 24
5455
5556 enum dsa_tag_protocol {
5657 DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
@@ -77,6 +78,7 @@ enum dsa_tag_protocol { · 20 unmodified lines
7778 DSA_TAG_PROTO_OCELOT_8021Q = DSA_TAG_PROTO_OCELOT_8021Q_VALUE,
7879 DSA_TAG_PROTO_SEVILLE = DSA_TAG_PROTO_SEVILLE_VALUE,
7980 DSA_TAG_PROTO_SJA1110 = DSA_TAG_PROTO_SJA1110_VALUE,
81+ DSA_TAG_PROTO_RTL8_4 = DSA_TAG_PROTO_RTL8_4_VALUE,
8082 };
8183
8284 struct dsa_switch;
@@ -645,6 +647,12 @@ struct dsa_switch_ops { · 562 unmodified lines
645647 int (*get_sset_count)(struct dsa_switch *ds, int port, int sset);
646648 void (*get_ethtool_phy_stats)(struct dsa_switch *ds,
647649 int port, uint64_t *data);
650+ void (*get_eth_phy_stats)(struct dsa_switch *ds, int port,
651+ struct ethtool_eth_phy_stats *phy_stats);
652+ void (*get_eth_mac_stats)(struct dsa_switch *ds, int port,
653+ struct ethtool_eth_mac_stats *mac_stats);
654+ void (*get_eth_ctrl_stats)(struct dsa_switch *ds, int port,
655+ struct ethtool_eth_ctrl_stats *ctrl_stats);
648656 void (*get_stats64)(struct dsa_switch *ds, int port,
649657 struct rtnl_link_stats64 *s);
650658 void (*self_test)(struct dsa_switch *ds, int port,
include/uapi/linux/if_ether.h+1−0
@@ -86,6 +86,7 @@ · 85 unmodified lines
8686 * over Ethernet
8787 */
8888 #define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
89+#define ETH_P_REALTEK 0x8899 /* Multiple proprietary protocols */
8990 #define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
9091 #define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
9192 #define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */
net/dsa/Kconfig+13−7
@@ -92,13 +92,6 @@ config NET_DSA_TAG_KSZ · 91 unmodified lines
9292 Say Y if you want to enable support for tagging frames for the
9393 Microchip 8795/9477/9893 families of switches.
9494
95−config NET_DSA_TAG_RTL4_A
96− tristate "Tag driver for Realtek 4 byte protocol A tags"
97− help
98− Say Y or M if you want to enable support for tagging frames for the
99− Realtek switches with 4 byte protocol A tags, sich as found in
100− the Realtek RTL8366RB.
101−
10295 config NET_DSA_TAG_OCELOT
10396 tristate "Tag driver for Ocelot family of switches, using NPI port"
10497 select PACKING
@@ -126,6 +119,19 @@ config NET_DSA_TAG_QCA · 21 unmodified lines
126119 Say Y or M if you want to enable support for tagging frames for
127120 the Qualcomm Atheros QCA8K switches.
128121
122+config NET_DSA_TAG_RTL4_A
123+ tristate "Tag driver for Realtek 4 byte protocol A tags"
124+ help
125+ Say Y or M if you want to enable support for tagging frames for the
126+ Realtek switches with 4 byte protocol A tags, sich as found in
127+ the Realtek RTL8366RB.
128+
129+config NET_DSA_TAG_RTL8_4
130+ tristate "Tag driver for Realtek 8 byte protocol 4 tags"
131+ help
132+ Say Y or M if you want to enable support for tagging frames for Realtek
133+ switches with 8 byte protocol 4 tags, such as the Realtek RTL8365MB-VC.
134+
129135 config NET_DSA_TAG_LAN9303
130136 tristate "Tag driver for SMSC/Microchip LAN9303 family of switches"
131137 help
net/dsa/Makefile+2−1
@@ -10,12 +10,13 @@ obj-$(CONFIG_NET_DSA_TAG_DSA_COMMON) += tag_dsa.o · 9 unmodified lines
1010 obj-$(CONFIG_NET_DSA_TAG_GSWIP) += tag_gswip.o
1111 obj-$(CONFIG_NET_DSA_TAG_HELLCREEK) += tag_hellcreek.o
1212 obj-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz.o
13−obj-$(CONFIG_NET_DSA_TAG_RTL4_A) += tag_rtl4_a.o
1413 obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o
1514 obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o
1615 obj-$(CONFIG_NET_DSA_TAG_OCELOT) += tag_ocelot.o
1716 obj-$(CONFIG_NET_DSA_TAG_OCELOT_8021Q) += tag_ocelot_8021q.o
1817 obj-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o
18+obj-$(CONFIG_NET_DSA_TAG_RTL4_A) += tag_rtl4_a.o
19+obj-$(CONFIG_NET_DSA_TAG_RTL8_4) += tag_rtl8_4.o
1920 obj-$(CONFIG_NET_DSA_TAG_SJA1105) += tag_sja1105.o
2021 obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o
2122 obj-$(CONFIG_NET_DSA_TAG_XRS700X) += tag_xrs700x.o
net/dsa/slave.c+34−0
@@ -789,6 +789,37 @@ static int dsa_slave_get_sset_count(struct net_device *dev, int sset) · 788 unmodified lines
789789 return -EOPNOTSUPP;
790790 }
791791
792+static void dsa_slave_get_eth_phy_stats(struct net_device *dev,
793+ struct ethtool_eth_phy_stats *phy_stats)
794+{
795+ struct dsa_port *dp = dsa_slave_to_port(dev);
796+ struct dsa_switch *ds = dp->ds;
797+
798+ if (ds->ops->get_eth_phy_stats)
799+ ds->ops->get_eth_phy_stats(ds, dp->index, phy_stats);
800+}
801+
802+static void dsa_slave_get_eth_mac_stats(struct net_device *dev,
803+ struct ethtool_eth_mac_stats *mac_stats)
804+{
805+ struct dsa_port *dp = dsa_slave_to_port(dev);
806+ struct dsa_switch *ds = dp->ds;
807+
808+ if (ds->ops->get_eth_mac_stats)
809+ ds->ops->get_eth_mac_stats(ds, dp->index, mac_stats);
810+}
811+
812+static void
813+dsa_slave_get_eth_ctrl_stats(struct net_device *dev,
814+ struct ethtool_eth_ctrl_stats *ctrl_stats)
815+{
816+ struct dsa_port *dp = dsa_slave_to_port(dev);
817+ struct dsa_switch *ds = dp->ds;
818+
819+ if (ds->ops->get_eth_ctrl_stats)
820+ ds->ops->get_eth_ctrl_stats(ds, dp->index, ctrl_stats);
821+}
822+
792823 static void dsa_slave_net_selftest(struct net_device *ndev,
793824 struct ethtool_test *etest, u64 *buf)
794825 {
@@ -1695,6 +1726,9 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = { · 900 unmodified lines
16951726 .get_strings = dsa_slave_get_strings,
16961727 .get_ethtool_stats = dsa_slave_get_ethtool_stats,
16971728 .get_sset_count = dsa_slave_get_sset_count,
1729+ .get_eth_phy_stats = dsa_slave_get_eth_phy_stats,
1730+ .get_eth_mac_stats = dsa_slave_get_eth_mac_stats,
1731+ .get_eth_ctrl_stats = dsa_slave_get_eth_ctrl_stats,
16981732 .set_wol = dsa_slave_set_wol,
16991733 .get_wol = dsa_slave_get_wol,
17001734 .set_eee = dsa_slave_set_eee,
net/dsa/tag_rtl8_4.c+178−0
@@ -0,0 +1,178 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Handler for Realtek 8 byte switch tags
4+ *
5+ * Copyright (C) 2021 Alvin Šipraga <alsi@bang-olufsen.dk>
6+ *
7+ * NOTE: Currently only supports protocol "4" found in the RTL8365MB, hence
8+ * named tag_rtl8_4.
9+ *
10+ * This tag header has the following format:
11+ *
12+ * -------------------------------------------
13+ * | MAC DA | MAC SA | 8 byte tag | Type | ...
14+ * -------------------------------------------
15+ * _______________/ \______________________________________
16+ * / \
17+ * 0 7|8 15
18+ * |-----------------------------------+-----------------------------------|---
19+ * | (16-bit) | ^
20+ * | Realtek EtherType [0x8899] | |
21+ * |-----------------------------------+-----------------------------------| 8
22+ * | (8-bit) | (8-bit) |
23+ * | Protocol [0x04] | REASON | b
24+ * |-----------------------------------+-----------------------------------| y
25+ * | (1) | (1) | (2) | (1) | (3) | (1) | (1) | (1) | (5) | t
26+ * | FID_EN | X | FID | PRI_EN | PRI | KEEP | X | LEARN_DIS | X | e
27+ * |-----------------------------------+-----------------------------------| s
28+ * | (1) | (15-bit) | |
29+ * | ALLOW | TX/RX | v
30+ * |-----------------------------------+-----------------------------------|---
31+ *
32+ * With the following field descriptions:
33+ *
34+ * field | description
35+ * ------------+-------------
36+ * Realtek | 0x8899: indicates that this is a proprietary Realtek tag;
37+ * EtherType | note that Realtek uses the same EtherType for
38+ * | other incompatible tag formats (e.g. tag_rtl4_a.c)
39+ * Protocol | 0x04: indicates that this tag conforms to this format
40+ * X | reserved
41+ * ------------+-------------
42+ * REASON | reason for forwarding packet to CPU
43+ * | 0: packet was forwarded or flooded to CPU
44+ * | 80: packet was trapped to CPU
45+ * FID_EN | 1: packet has an FID
46+ * | 0: no FID
47+ * FID | FID of packet (if FID_EN=1)
48+ * PRI_EN | 1: force priority of packet
49+ * | 0: don't force priority
50+ * PRI | priority of packet (if PRI_EN=1)
51+ * KEEP | preserve packet VLAN tag format
52+ * LEARN_DIS | don't learn the source MAC address of the packet
53+ * ALLOW | 1: treat TX/RX field as an allowance port mask, meaning the
54+ * | packet may only be forwarded to ports specified in the
55+ * | mask
56+ * | 0: no allowance port mask, TX/RX field is the forwarding
57+ * | port mask
58+ * TX/RX | TX (switch->CPU): port number the packet was received on
59+ * | RX (CPU->switch): forwarding port mask (if ALLOW=0)
60+ * | allowance port mask (if ALLOW=1)
61+ */
62+
63+#include <linux/bitfield.h>
64+#include <linux/bits.h>
65+#include <linux/etherdevice.h>
66+
67+#include "dsa_priv.h"
68+
69+/* Protocols supported:
70+ *
71+ * 0x04 = RTL8365MB DSA protocol
72+ */
73+
74+#define RTL8_4_TAG_LEN 8
75+
76+#define RTL8_4_PROTOCOL GENMASK(15, 8)
77+#define RTL8_4_PROTOCOL_RTL8365MB 0x04
78+#define RTL8_4_REASON GENMASK(7, 0)
79+#define RTL8_4_REASON_FORWARD 0
80+#define RTL8_4_REASON_TRAP 80
81+
82+#define RTL8_4_LEARN_DIS BIT(5)
83+
84+#define RTL8_4_TX GENMASK(3, 0)
85+#define RTL8_4_RX GENMASK(10, 0)
86+
87+static struct sk_buff *rtl8_4_tag_xmit(struct sk_buff *skb,
88+ struct net_device *dev)
89+{
90+ struct dsa_port *dp = dsa_slave_to_port(dev);
91+ __be16 *tag;
92+
93+ skb_push(skb, RTL8_4_TAG_LEN);
94+
95+ dsa_alloc_etype_header(skb, RTL8_4_TAG_LEN);
96+ tag = dsa_etype_header_pos_tx(skb);
97+
98+ /* Set Realtek EtherType */
99+ tag[0] = htons(ETH_P_REALTEK);
100+
101+ /* Set Protocol; zero REASON */
102+ tag[1] = htons(FIELD_PREP(RTL8_4_PROTOCOL, RTL8_4_PROTOCOL_RTL8365MB));
103+
104+ /* Zero FID_EN, FID, PRI_EN, PRI, KEEP; set LEARN_DIS */
105+ tag[2] = htons(FIELD_PREP(RTL8_4_LEARN_DIS, 1));
106+
107+ /* Zero ALLOW; set RX (CPU->switch) forwarding port mask */
108+ tag[3] = htons(FIELD_PREP(RTL8_4_RX, BIT(dp->index)));
109+
110+ return skb;
111+}
112+
113+static struct sk_buff *rtl8_4_tag_rcv(struct sk_buff *skb,
114+ struct net_device *dev)
115+{
116+ __be16 *tag;
117+ u16 etype;
118+ u8 reason;
119+ u8 proto;
120+ u8 port;
121+
122+ if (unlikely(!pskb_may_pull(skb, RTL8_4_TAG_LEN)))
123+ return NULL;
124+
125+ tag = dsa_etype_header_pos_rx(skb);
126+
127+ /* Parse Realtek EtherType */
128+ etype = ntohs(tag[0]);
129+ if (unlikely(etype != ETH_P_REALTEK)) {
130+ dev_warn_ratelimited(&dev->dev,
131+ "non-realtek ethertype 0x%04x\n", etype);
132+ return NULL;
133+ }
134+
135+ /* Parse Protocol */
136+ proto = FIELD_GET(RTL8_4_PROTOCOL, ntohs(tag[1]));
137+ if (unlikely(proto != RTL8_4_PROTOCOL_RTL8365MB)) {
138+ dev_warn_ratelimited(&dev->dev,
139+ "unknown realtek protocol 0x%02x\n",
140+ proto);
141+ return NULL;
142+ }
143+
144+ /* Parse REASON */
145+ reason = FIELD_GET(RTL8_4_REASON, ntohs(tag[1]));
146+
147+ /* Parse TX (switch->CPU) */
148+ port = FIELD_GET(RTL8_4_TX, ntohs(tag[3]));
149+ skb->dev = dsa_master_find_slave(dev, 0, port);
150+ if (!skb->dev) {
151+ dev_warn_ratelimited(&dev->dev,
152+ "could not find slave for port %d\n",
153+ port);
154+ return NULL;
155+ }
156+
157+ /* Remove tag and recalculate checksum */
158+ skb_pull_rcsum(skb, RTL8_4_TAG_LEN);
159+
160+ dsa_strip_etype_header(skb, RTL8_4_TAG_LEN);
161+
162+ if (reason != RTL8_4_REASON_TRAP)
163+ dsa_default_offload_fwd_mark(skb);
164+
165+ return skb;
166+}
167+
168+static const struct dsa_device_ops rtl8_4_netdev_ops = {
169+ .name = "rtl8_4",
170+ .proto = DSA_TAG_PROTO_RTL8_4,
171+ .xmit = rtl8_4_tag_xmit,
172+ .rcv = rtl8_4_tag_rcv,
173+ .needed_headroom = RTL8_4_TAG_LEN,
174+};
175+module_dsa_tag_driver(rtl8_4_netdev_ops);
176+
177+MODULE_LICENSE("GPL");
178+MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_RTL8_4);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t