aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPraneeth Bajjuri2021-01-05 14:17:04 -0600
committerPraneeth Bajjuri2021-01-05 14:17:04 -0600
commitab9c84991155605c23ec3f2092b2d61dc9f5ec12 (patch)
tree35955b7d0e42727bdaff3504606132b4da1ebb76
parentb6cc3b3206a67cfa96eb76c223d5f629908e11b1 (diff)
parentf90a28cd61121005c9b9b711a0198ef79d415caa (diff)
downloadkernel-android-feature-ti-linux-5.4.y.tar.gz
kernel-android-feature-ti-linux-5.4.y.tar.xz
kernel-android-feature-ti-linux-5.4.y.zip
Merge branch 'ti-linux-5.4.y' of git://git.ti.com/ti-linux-kernel/ti-linux-kernel into android-feature-ti-linux-5.4.yandroid-feature-ti-linux-5.4.y
* 'ti-linux-5.4.y' of git://git.ti.com/ti-linux-kernel/ti-linux-kernel: net: ethernet: ti: icssg_prueth: use ERR_PTR check for mac address arm64: dts: ti: k3-j7200-common-proc-board: Add I2C IO expanders arm64: dts: ti: j7200: Add I2C nodes net: ti: prueth_switch: Dump multicast filter table in switch mode net: ti: prueth_switch: Offload multicast filtering for host port net: ti: prueth_core: Make prueth_init_timer() static ARM: dts: keystone-k2g: Add PRUSS eCAP nodes ARM: dts: am57xx: Add PRUSS eCAP nodes ARM: dts: am437x: Add PRUSS eCAP node ARM: dts: am335x: Add PRUSS eCAP node dt-bindings: soc: ti: pruss: Add eCAP documentation dt-bindings: net: pruss_ecap: Add dt binding documentation Signed-off-by: Praneeth Bajjuri <praneeth@ti.com>
-rw-r--r--Documentation/devicetree/bindings/net/ti,pruss-ecap.yaml30
-rw-r--r--Documentation/devicetree/bindings/soc/ti/ti,pruss.txt19
-rw-r--r--arch/arm/boot/dts/am33xx-l4.dtsi5
-rw-r--r--arch/arm/boot/dts/am4372.dtsi5
-rw-r--r--arch/arm/boot/dts/dra7-pruss.dtsi10
-rw-r--r--arch/arm/boot/dts/keystone-k2g.dtsi10
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts49
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-main.dtsi77
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi33
-rw-r--r--drivers/net/ethernet/ti/icssg_prueth.c2
-rw-r--r--drivers/net/ethernet/ti/prueth.h3
-rw-r--r--drivers/net/ethernet/ti/prueth_core.c40
-rw-r--r--drivers/net/ethernet/ti/prueth_switch.c74
13 files changed, 341 insertions, 16 deletions
diff --git a/Documentation/devicetree/bindings/net/ti,pruss-ecap.yaml b/Documentation/devicetree/bindings/net/ti,pruss-ecap.yaml
new file mode 100644
index 000000000000..998fa293fbf8
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/ti,pruss-ecap.yaml
@@ -0,0 +1,30 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/net/ti,pruss-ecap.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Texas Instruments PRU-ICSS Enhanced Capture (eCAP) event module
8
9maintainers:
10 - Murali Karicheri <m-karicheri2@ti.com>
11
12properties:
13 compatible:
14 const: ti,pruss-ecap
15
16 reg:
17 maxItems: 1
18
19required:
20 - compatible
21 - reg
22
23additionalProperties: false
24
25examples:
26 - |
27 pruss0_ecap: ecap@30000 {
28 compatible = "ti,pruss-ecap";
29 reg = <0x30000 0x60>;
30 };
diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt b/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt
index 6617c68b064f..6bc8d6a06d2a 100644
--- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt
+++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.txt
@@ -157,6 +157,15 @@ MDIO module used within the PRU-ICSS is an instance of the MDIO Controller
157used in TI Davinci SoCs. Please refer to the corresponding binding document, 157used in TI Davinci SoCs. Please refer to the corresponding binding document,
158Documentation/devicetree/bindings/net/davinci-mdio.txt for details. 158Documentation/devicetree/bindings/net/davinci-mdio.txt for details.
159 159
160eCAP Node
161=========
162Each PRUSS includes an Enhanced Capture (eCAP) module that can provide some
163time-stamp features using its capture input. The eCAP module used within the
164PRU-ICSS is similar to other instances used within the PWM subsystems. This
165is typically used for providing interrupt pacing for host traffic on various
166PRU Ethernet usecases such as Dual-EMAC, HSR or PRP. Please refer to the
167corresponding binding document,
168Documentation/devicetree/bindings/net/ti,pruss-ecap.yaml
160 169
161Example: 170Example:
162======== 171========
@@ -213,6 +222,11 @@ Example:
213 clocks = <&pruss_iepclk_mux>; 222 clocks = <&pruss_iepclk_mux>;
214 }; 223 };
215 224
225 pruss_ecap: ecap@30000 {
226 compatible = "ti,pruss-ecap";
227 reg = <0x30000 0x60>;
228 };
229
216 pruss_mii_rt: mii-rt@32000 { 230 pruss_mii_rt: mii-rt@32000 {
217 compatible = "syscon"; 231 compatible = "syscon";
218 reg = <0x32000 0x58>; 232 reg = <0x32000 0x58>;
@@ -314,6 +328,11 @@ Example:
314 clocks = <&pruss1_iepclk_mux>; 328 clocks = <&pruss1_iepclk_mux>;
315 }; 329 };
316 330
331 pruss1_ecap: ecap@30000 {
332 compatible = "ti,pruss-ecap";
333 reg = <0x30000 0x60>;
334 };
335
317 pruss1_mii_rt: mii-rt@32000 { 336 pruss1_mii_rt: mii-rt@32000 {
318 compatible = "syscon"; 337 compatible = "syscon";
319 reg = <0x32000 0x58>; 338 reg = <0x32000 0x58>;
diff --git a/arch/arm/boot/dts/am33xx-l4.dtsi b/arch/arm/boot/dts/am33xx-l4.dtsi
index fc533bcc7542..54605e1bd164 100644
--- a/arch/arm/boot/dts/am33xx-l4.dtsi
+++ b/arch/arm/boot/dts/am33xx-l4.dtsi
@@ -812,6 +812,11 @@
812 clocks = <&pruss_iepclk_mux>; 812 clocks = <&pruss_iepclk_mux>;
813 }; 813 };
814 814
815 pruss_ecap: ecap@30000 {
816 compatible = "ti,pruss-ecap";
817 reg = <0x30000 0x60>;
818 };
819
815 pruss_uart: serial@28000 { 820 pruss_uart: serial@28000 {
816 compatible = "ti,pruss-uart"; 821 compatible = "ti,pruss-uart";
817 reg = <0x28000 0x38>; 822 reg = <0x28000 0x38>;
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index 6fc8984fda3a..3f105a75940a 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -352,6 +352,11 @@
352 clocks = <&pruss1_iepclk_mux>; 352 clocks = <&pruss1_iepclk_mux>;
353 }; 353 };
354 354
355 pruss1_ecap: ecap@30000 {
356 compatible = "ti,pruss-ecap";
357 reg = <0x30000 0x60>;
358 };
359
355 pruss1_mii_rt: mii-rt@32000 { 360 pruss1_mii_rt: mii-rt@32000 {
356 compatible = "syscon"; 361 compatible = "syscon";
357 reg = <0x32000 0x58>; 362 reg = <0x32000 0x58>;
diff --git a/arch/arm/boot/dts/dra7-pruss.dtsi b/arch/arm/boot/dts/dra7-pruss.dtsi
index 5b33830ac40b..5d9d5fd9a7b3 100644
--- a/arch/arm/boot/dts/dra7-pruss.dtsi
+++ b/arch/arm/boot/dts/dra7-pruss.dtsi
@@ -59,6 +59,11 @@
59 clocks = <&pruss1_iepclk_mux>; 59 clocks = <&pruss1_iepclk_mux>;
60 }; 60 };
61 61
62 pruss1_ecap: ecap@30000 {
63 compatible = "ti,pruss-ecap";
64 reg = <0x30000 0x60>;
65 };
66
62 pruss1_mii_rt: mii-rt@32000 { 67 pruss1_mii_rt: mii-rt@32000 {
63 compatible = "syscon"; 68 compatible = "syscon";
64 reg = <0x32000 0x58>; 69 reg = <0x32000 0x58>;
@@ -174,6 +179,11 @@
174 clocks = <&pruss2_iepclk_mux>; 179 clocks = <&pruss2_iepclk_mux>;
175 }; 180 };
176 181
182 pruss2_ecap: ecap@30000 {
183 compatible = "ti,pruss-ecap";
184 reg = <0x30000 0x60>;
185 };
186
177 pruss2_mii_rt: mii-rt@32000 { 187 pruss2_mii_rt: mii-rt@32000 {
178 compatible = "syscon"; 188 compatible = "syscon";
179 reg = <0x32000 0x58>; 189 reg = <0x32000 0x58>;
diff --git a/arch/arm/boot/dts/keystone-k2g.dtsi b/arch/arm/boot/dts/keystone-k2g.dtsi
index 9dcbd9bd0804..b54c833013c8 100644
--- a/arch/arm/boot/dts/keystone-k2g.dtsi
+++ b/arch/arm/boot/dts/keystone-k2g.dtsi
@@ -697,6 +697,11 @@
697 clocks = <&pruss0_iepclk_mux>; 697 clocks = <&pruss0_iepclk_mux>;
698 }; 698 };
699 699
700 pruss0_ecap: ecap@30000 {
701 compatible = "ti,pruss-ecap";
702 reg = <0x30000 0x60>;
703 };
704
700 pruss0_mii_rt: mii-rt@32000 { 705 pruss0_mii_rt: mii-rt@32000 {
701 compatible = "syscon"; 706 compatible = "syscon";
702 reg = <0x32000 0x70>; 707 reg = <0x32000 0x70>;
@@ -792,6 +797,11 @@
792 clocks = <&pruss1_iepclk_mux>; 797 clocks = <&pruss1_iepclk_mux>;
793 }; 798 };
794 799
800 pruss1_ecap: ecap@30000 {
801 compatible = "ti,pruss-ecap";
802 reg = <0x30000 0x60>;
803 };
804
795 pruss1_mii_rt: mii-rt@32000 { 805 pruss1_mii_rt: mii-rt@32000 {
796 compatible = "syscon"; 806 compatible = "syscon";
797 reg = <0x32000 0x70>; 807 reg = <0x32000 0x70>;
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
index 12c800b187f1..f9269bb2a2c4 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
@@ -41,6 +41,22 @@
41 }; 41 };
42}; 42};
43 43
44&main_pmx0 {
45 main_i2c0_pins_default: main-i2c0-pins-default {
46 pinctrl-single,pins = <
47 J721E_IOPAD(0xd4, PIN_INPUT_PULLUP, 0) /* (V3) I2C0_SCL */
48 J721E_IOPAD(0xd8, PIN_INPUT_PULLUP, 0) /* (W2) I2C0_SDA */
49 >;
50 };
51
52 main_i2c1_pins_default: main-i2c1-pins-default {
53 pinctrl-single,pins = <
54 J721E_IOPAD(0xdc, PIN_INPUT_PULLUP, 3) /* (U3) ECAP0_IN_APWM_OUT.I2C1_SCL */
55 J721E_IOPAD(0xe0, PIN_INPUT_PULLUP, 3) /* (T3) EXT_REFCLK1.I2C1_SDA */
56 >;
57 };
58};
59
44&wkup_uart0 { 60&wkup_uart0 {
45 /* Wakeup UART is used by System firmware */ 61 /* Wakeup UART is used by System firmware */
46 status = "disabled"; 62 status = "disabled";
@@ -90,6 +106,39 @@
90 status = "disabled"; 106 status = "disabled";
91}; 107};
92 108
109&main_i2c0 {
110 pinctrl-names = "default";
111 pinctrl-0 = <&main_i2c0_pins_default>;
112 clock-frequency = <400000>;
113
114 exp1: gpio@20 {
115 compatible = "ti,tca6416";
116 reg = <0x20>;
117 gpio-controller;
118 #gpio-cells = <2>;
119 };
120
121 exp2: gpio@22 {
122 compatible = "ti,tca6424";
123 reg = <0x22>;
124 gpio-controller;
125 #gpio-cells = <2>;
126 };
127};
128
129&main_i2c1 {
130 pinctrl-names = "default";
131 pinctrl-0 = <&main_i2c1_pins_default>;
132 clock-frequency = <400000>;
133
134 exp4: gpio@20 {
135 compatible = "ti,tca6408";
136 reg = <0x20>;
137 gpio-controller;
138 #gpio-cells = <2>;
139 };
140};
141
93&mcu_cpsw { 142&mcu_cpsw {
94 pinctrl-names = "default"; 143 pinctrl-names = "default";
95 pinctrl-0 = <&mcu_cpsw_pins_default &mcu_mdio_pins_default>; 144 pinctrl-0 = <&mcu_cpsw_pins_default &mcu_mdio_pins_default>;
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
index 0109f5cad461..a70a04db7c5b 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
@@ -270,6 +270,83 @@
270 clock-names = "fclk"; 270 clock-names = "fclk";
271 }; 271 };
272 272
273 main_i2c0: i2c@2000000 {
274 compatible = "ti,j721e-i2c", "ti,omap4-i2c";
275 reg = <0x0 0x2000000 0x0 0x100>;
276 interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
277 #address-cells = <1>;
278 #size-cells = <0>;
279 clock-names = "fck";
280 clocks = <&k3_clks 187 1>;
281 power-domains = <&k3_pds 187 TI_SCI_PD_SHARED>;
282 };
283
284 main_i2c1: i2c@2010000 {
285 compatible = "ti,j721e-i2c", "ti,omap4-i2c";
286 reg = <0x0 0x2010000 0x0 0x100>;
287 interrupts = <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
288 #address-cells = <1>;
289 #size-cells = <0>;
290 clock-names = "fck";
291 clocks = <&k3_clks 188 1>;
292 power-domains = <&k3_pds 188 TI_SCI_PD_EXCLUSIVE>;
293 };
294
295 main_i2c2: i2c@2020000 {
296 compatible = "ti,j721e-i2c", "ti,omap4-i2c";
297 reg = <0x0 0x2020000 0x0 0x100>;
298 interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>;
299 #address-cells = <1>;
300 #size-cells = <0>;
301 clock-names = "fck";
302 clocks = <&k3_clks 189 1>;
303 power-domains = <&k3_pds 189 TI_SCI_PD_EXCLUSIVE>;
304 };
305
306 main_i2c3: i2c@2030000 {
307 compatible = "ti,j721e-i2c", "ti,omap4-i2c";
308 reg = <0x0 0x2030000 0x0 0x100>;
309 interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>;
310 #address-cells = <1>;
311 #size-cells = <0>;
312 clock-names = "fck";
313 clocks = <&k3_clks 190 1>;
314 power-domains = <&k3_pds 190 TI_SCI_PD_EXCLUSIVE>;
315 };
316
317 main_i2c4: i2c@2040000 {
318 compatible = "ti,j721e-i2c", "ti,omap4-i2c";
319 reg = <0x0 0x2040000 0x0 0x100>;
320 interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>;
321 #address-cells = <1>;
322 #size-cells = <0>;
323 clock-names = "fck";
324 clocks = <&k3_clks 191 1>;
325 power-domains = <&k3_pds 191 TI_SCI_PD_EXCLUSIVE>;
326 };
327
328 main_i2c5: i2c@2050000 {
329 compatible = "ti,j721e-i2c", "ti,omap4-i2c";
330 reg = <0x0 0x2050000 0x0 0x100>;
331 interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
332 #address-cells = <1>;
333 #size-cells = <0>;
334 clock-names = "fck";
335 clocks = <&k3_clks 192 1>;
336 power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
337 };
338
339 main_i2c6: i2c@2060000 {
340 compatible = "ti,j721e-i2c", "ti,omap4-i2c";
341 reg = <0x0 0x2060000 0x0 0x100>;
342 interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
343 #address-cells = <1>;
344 #size-cells = <0>;
345 clock-names = "fck";
346 clocks = <&k3_clks 193 1>;
347 power-domains = <&k3_pds 193 TI_SCI_PD_EXCLUSIVE>;
348 };
349
273 timesync_router: timesync_router@a40000 { 350 timesync_router: timesync_router@a40000 {
274 compatible = "pinctrl-single"; 351 compatible = "pinctrl-single";
275 reg = <0x0 0xa40000 0x0 0x800>; 352 reg = <0x0 0xa40000 0x0 0x800>;
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
index 9b6d2ac98edb..c98797010976 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
@@ -96,6 +96,39 @@
96 clock-names = "fclk"; 96 clock-names = "fclk";
97 }; 97 };
98 98
99 mcu_i2c0: i2c@40b00000 {
100 compatible = "ti,j721e-i2c", "ti,omap4-i2c";
101 reg = <0x0 0x40b00000 0x0 0x100>;
102 interrupts = <GIC_SPI 852 IRQ_TYPE_LEVEL_HIGH>;
103 #address-cells = <1>;
104 #size-cells = <0>;
105 clock-names = "fck";
106 clocks = <&k3_clks 194 1>;
107 power-domains = <&k3_pds 194 TI_SCI_PD_EXCLUSIVE>;
108 };
109
110 mcu_i2c1: i2c@40b10000 {
111 compatible = "ti,j721e-i2c", "ti,omap4-i2c";
112 reg = <0x0 0x40b10000 0x0 0x100>;
113 interrupts = <GIC_SPI 853 IRQ_TYPE_LEVEL_HIGH>;
114 #address-cells = <1>;
115 #size-cells = <0>;
116 clock-names = "fck";
117 clocks = <&k3_clks 195 1>;
118 power-domains = <&k3_pds 195 TI_SCI_PD_EXCLUSIVE>;
119 };
120
121 wkup_i2c0: i2c@42120000 {
122 compatible = "ti,j721e-i2c", "ti,omap4-i2c";
123 reg = <0x0 0x42120000 0x0 0x100>;
124 interrupts = <GIC_SPI 896 IRQ_TYPE_LEVEL_HIGH>;
125 #address-cells = <1>;
126 #size-cells = <0>;
127 clock-names = "fck";
128 clocks = <&k3_clks 197 1>;
129 power-domains = <&k3_pds 197 TI_SCI_PD_SHARED>;
130 };
131
99 cbass_mcu_navss: navss@28380000 { 132 cbass_mcu_navss: navss@28380000 {
100 compatible = "simple-mfd"; 133 compatible = "simple-mfd";
101 #address-cells = <2>; 134 #address-cells = <2>;
diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c
index 5c440493fcf0..9537b029509c 100644
--- a/drivers/net/ethernet/ti/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg_prueth.c
@@ -1939,7 +1939,7 @@ skip_iep:
1939 1939
1940 /* get mac address from DT and set private and netdev addr */ 1940 /* get mac address from DT and set private and netdev addr */
1941 mac_addr = of_get_mac_address(eth_node); 1941 mac_addr = of_get_mac_address(eth_node);
1942 if (mac_addr) 1942 if (!IS_ERR(mac_addr))
1943 ether_addr_copy(ndev->dev_addr, mac_addr); 1943 ether_addr_copy(ndev->dev_addr, mac_addr);
1944 if (!is_valid_ether_addr(ndev->dev_addr)) { 1944 if (!is_valid_ether_addr(ndev->dev_addr)) {
1945 eth_hw_addr_random(ndev); 1945 eth_hw_addr_random(ndev);
diff --git a/drivers/net/ethernet/ti/prueth.h b/drivers/net/ethernet/ti/prueth.h
index ab6fcfe769cb..6720b25a4751 100644
--- a/drivers/net/ethernet/ti/prueth.h
+++ b/drivers/net/ethernet/ti/prueth.h
@@ -505,4 +505,7 @@ static inline void emac_finish_napi(struct prueth_emac *emac,
505 enable_irq(irq); 505 enable_irq(irq);
506} 506}
507 507
508void emac_mc_filter_bin_allow(struct prueth_emac *emac, u8 hash);
509void emac_mc_filter_bin_disallow(struct prueth_emac *emac, u8 hash);
510u8 emac_get_mc_hash(u8 *mac, u8 *mask);
508#endif /* __NET_TI_PRUETH_H */ 511#endif /* __NET_TI_PRUETH_H */
diff --git a/drivers/net/ethernet/ti/prueth_core.c b/drivers/net/ethernet/ti/prueth_core.c
index 2a0176ea6101..e0b71d2ff2c5 100644
--- a/drivers/net/ethernet/ti/prueth_core.c
+++ b/drivers/net/ethernet/ti/prueth_core.c
@@ -349,7 +349,7 @@ static enum hrtimer_restart prueth_timer(struct hrtimer *timer)
349 return ret; 349 return ret;
350} 350}
351 351
352void prueth_init_timer(struct prueth *prueth) 352static void prueth_init_timer(struct prueth *prueth)
353{ 353{
354 hrtimer_init(&prueth->tbl_check_timer, CLOCK_MONOTONIC, 354 hrtimer_init(&prueth->tbl_check_timer, CLOCK_MONOTONIC,
355 HRTIMER_MODE_REL); 355 HRTIMER_MODE_REL);
@@ -2072,7 +2072,7 @@ static void emac_mc_filter_hashmask(struct prueth_emac *emac,
2072 ICSS_EMAC_FW_MULTICAST_FILTER_MASK_SIZE_BYTES); 2072 ICSS_EMAC_FW_MULTICAST_FILTER_MASK_SIZE_BYTES);
2073} 2073}
2074 2074
2075static void emac_mc_filter_bin_allow(struct prueth_emac *emac, u8 hash) 2075static void emac_mc_filter_bin_update(struct prueth_emac *emac, u8 hash, u8 val)
2076{ 2076{
2077 struct prueth *prueth = emac->prueth; 2077 struct prueth *prueth = emac->prueth;
2078 u32 mc_filter_tbl_base = prueth->fw_offsets->mc_filter_tbl; 2078 u32 mc_filter_tbl_base = prueth->fw_offsets->mc_filter_tbl;
@@ -2083,11 +2083,20 @@ static void emac_mc_filter_bin_allow(struct prueth_emac *emac, u8 hash)
2083 ram = prueth->mem[PRUETH_MEM_DRAM1].va; 2083 ram = prueth->mem[PRUETH_MEM_DRAM1].va;
2084 2084
2085 mc_filter_tbl = ram + mc_filter_tbl_base; 2085 mc_filter_tbl = ram + mc_filter_tbl_base;
2086 writeb(ICSS_EMAC_FW_MULTICAST_FILTER_HOST_RCV_ALLOWED, 2086 writeb(val, mc_filter_tbl + hash);
2087 mc_filter_tbl + hash);
2088} 2087}
2089 2088
2090static u8 emac_get_mc_hash(u8 *mac, u8 *mask) 2089void emac_mc_filter_bin_allow(struct prueth_emac *emac, u8 hash)
2090{
2091 emac_mc_filter_bin_update(emac, hash, ICSS_EMAC_FW_MULTICAST_FILTER_HOST_RCV_ALLOWED);
2092}
2093
2094void emac_mc_filter_bin_disallow(struct prueth_emac *emac, u8 hash)
2095{
2096 emac_mc_filter_bin_update(emac, hash, ICSS_EMAC_FW_MULTICAST_FILTER_HOST_RCV_NOT_ALLOWED);
2097}
2098
2099u8 emac_get_mc_hash(u8 *mac, u8 *mask)
2091{ 2100{
2092 int j; 2101 int j;
2093 u8 hash; 2102 u8 hash;
@@ -2117,13 +2126,6 @@ static void emac_ndo_set_rx_mode(struct net_device *ndev)
2117 u32 mask; 2126 u32 mask;
2118 u8 hash; 2127 u8 hash;
2119 2128
2120 if (PRUETH_IS_SWITCH(prueth)) {
2121 netdev_dbg(ndev,
2122 "%s: promisc/mc filtering not supported for switch\n",
2123 __func__);
2124 return;
2125 }
2126
2127 if (promisc && PRUETH_IS_LRE(prueth)) { 2129 if (promisc && PRUETH_IS_LRE(prueth)) {
2128 netdev_dbg(ndev, 2130 netdev_dbg(ndev,
2129 "%s: promisc mode not supported for LRE\n", 2131 "%s: promisc mode not supported for LRE\n",
@@ -2166,7 +2168,7 @@ static void emac_ndo_set_rx_mode(struct net_device *ndev)
2166 goto unlock; 2168 goto unlock;
2167 } 2169 }
2168 2170
2169 if (ndev->flags & IFF_ALLMULTI) 2171 if (ndev->flags & IFF_ALLMULTI && !PRUETH_IS_SWITCH(prueth))
2170 goto unlock; 2172 goto unlock;
2171 2173
2172 emac_mc_filter_ctrl(emac, true); /* all multicast blocked */ 2174 emac_mc_filter_ctrl(emac, true); /* all multicast blocked */
@@ -2178,6 +2180,14 @@ static void emac_ndo_set_rx_mode(struct net_device *ndev)
2178 hash = emac_get_mc_hash(ha->addr, emac->mc_filter_mask); 2180 hash = emac_get_mc_hash(ha->addr, emac->mc_filter_mask);
2179 emac_mc_filter_bin_allow(emac, hash); 2181 emac_mc_filter_bin_allow(emac, hash);
2180 } 2182 }
2183
2184 /* Add bridge device's MC addresses as well */
2185 if (prueth->hw_bridge_dev) {
2186 netdev_for_each_mc_addr(ha, prueth->hw_bridge_dev) {
2187 hash = emac_get_mc_hash(ha->addr, emac->mc_filter_mask);
2188 emac_mc_filter_bin_allow(emac, hash);
2189 }
2190 }
2181unlock: 2191unlock:
2182 spin_unlock_irqrestore(&emac->addr_lock, flags); 2192 spin_unlock_irqrestore(&emac->addr_lock, flags);
2183} 2193}
@@ -2598,7 +2608,7 @@ static int emac_get_regs_len(struct net_device *ndev)
2598 * size will give the entire size of reg dump in case of 2608 * size will give the entire size of reg dump in case of
2599 * Dual-EMAC firmware. 2609 * Dual-EMAC firmware.
2600 */ 2610 */
2601 if (PRUETH_IS_EMAC(prueth)) { 2611 if (PRUETH_IS_EMAC(prueth) || PRUETH_IS_SWITCH(prueth)) {
2602 return ICSS_EMAC_FW_VLAN_FLTR_TBL_BASE_ADDR + 2612 return ICSS_EMAC_FW_VLAN_FLTR_TBL_BASE_ADDR +
2603 ICSS_EMAC_FW_VLAN_FILTER_TABLE_SIZE_BYTES; 2613 ICSS_EMAC_FW_VLAN_FILTER_TABLE_SIZE_BYTES;
2604 } 2614 }
@@ -2628,7 +2638,7 @@ static void emac_get_regs(struct net_device *ndev, struct ethtool_regs *regs,
2628 regs->version = PRUETH_REG_DUMP_GET_VER(prueth); 2638 regs->version = PRUETH_REG_DUMP_GET_VER(prueth);
2629 2639
2630 /* Dump firmware's VLAN and MC tables */ 2640 /* Dump firmware's VLAN and MC tables */
2631 if (PRUETH_IS_EMAC(prueth)) { 2641 if (PRUETH_IS_EMAC(prueth) || PRUETH_IS_SWITCH(prueth)) {
2632 ram = prueth->mem[emac->dram].va; 2642 ram = prueth->mem[emac->dram].va;
2633 memcpy_fromio(reg, ram, emac_get_regs_len(ndev)); 2643 memcpy_fromio(reg, ram, emac_get_regs_len(ndev));
2634 return; 2644 return;
diff --git a/drivers/net/ethernet/ti/prueth_switch.c b/drivers/net/ethernet/ti/prueth_switch.c
index f5891306baad..edb9473928b7 100644
--- a/drivers/net/ethernet/ti/prueth_switch.c
+++ b/drivers/net/ethernet/ti/prueth_switch.c
@@ -1075,6 +1075,68 @@ static int prueth_switchdev_attr_set(struct net_device *ndev,
1075 return err; 1075 return err;
1076} 1076}
1077 1077
1078static int prueth_switchdev_obj_add(struct net_device *ndev,
1079 const struct switchdev_obj *obj,
1080 struct switchdev_trans *trans,
1081 struct netlink_ext_ack *extack)
1082{
1083 struct prueth_emac *emac = netdev_priv(ndev);
1084 struct prueth *prueth = emac->prueth;
1085 struct switchdev_obj_port_mdb *mdb;
1086 int ret = 0;
1087 u8 hash;
1088
1089 if (switchdev_trans_ph_prepare(trans))
1090 return 0;
1091
1092 switch (obj->id) {
1093 case SWITCHDEV_OBJ_ID_HOST_MDB:
1094 mdb = SWITCHDEV_OBJ_PORT_MDB(obj);
1095 dev_dbg(prueth->dev, "MDB add: %s: vid %u:%pM port: %x\n",
1096 ndev->name, mdb->vid, mdb->addr, emac->port_id);
1097 hash = emac_get_mc_hash(mdb->addr, emac->mc_filter_mask);
1098 emac_mc_filter_bin_allow(emac, hash);
1099 break;
1100 default:
1101 ret = -EOPNOTSUPP;
1102 break;
1103 }
1104
1105 return ret;
1106}
1107
1108static int prueth_switchdev_obj_del(struct net_device *ndev,
1109 const struct switchdev_obj *obj)
1110{
1111 struct prueth_emac *emac = netdev_priv(ndev);
1112 struct prueth *prueth = emac->prueth;
1113 struct switchdev_obj_port_mdb *mdb;
1114 struct netdev_hw_addr *ha;
1115 u8 hash, tmp_hash;
1116 int ret = 0;
1117
1118 switch (obj->id) {
1119 case SWITCHDEV_OBJ_ID_HOST_MDB:
1120 mdb = SWITCHDEV_OBJ_PORT_MDB(obj);
1121 dev_dbg(prueth->dev, "MDB del: %s: vid %u:%pM port: %x\n",
1122 ndev->name, mdb->vid, mdb->addr, emac->port_id);
1123 hash = emac_get_mc_hash(mdb->addr, emac->mc_filter_mask);
1124 netdev_for_each_mc_addr(ha, prueth->hw_bridge_dev) {
1125 tmp_hash = emac_get_mc_hash(ha->addr, emac->mc_filter_mask);
1126 /* Another MC address is in the bin. Don't disable. */
1127 if (tmp_hash == hash)
1128 return 0;
1129 }
1130 emac_mc_filter_bin_disallow(emac, hash);
1131 break;
1132 default:
1133 ret = -EOPNOTSUPP;
1134 break;
1135 }
1136
1137 return ret;
1138}
1139
1078/* switchdev notifiers */ 1140/* switchdev notifiers */
1079static int prueth_sw_switchdev_blocking_event(struct notifier_block *unused, 1141static int prueth_sw_switchdev_blocking_event(struct notifier_block *unused,
1080 unsigned long event, void *ptr) 1142 unsigned long event, void *ptr)
@@ -1093,6 +1155,18 @@ static int prueth_sw_switchdev_blocking_event(struct notifier_block *unused,
1093 prueth_sw_port_dev_check, 1155 prueth_sw_port_dev_check,
1094 prueth_switchdev_attr_set); 1156 prueth_switchdev_attr_set);
1095 return notifier_from_errno(err); 1157 return notifier_from_errno(err);
1158
1159 case SWITCHDEV_PORT_OBJ_ADD:
1160 err = switchdev_handle_port_obj_add(ndev, ptr,
1161 prueth_sw_port_dev_check,
1162 prueth_switchdev_obj_add);
1163 return notifier_from_errno(err);
1164
1165 case SWITCHDEV_PORT_OBJ_DEL:
1166 err = switchdev_handle_port_obj_del(ndev, ptr,
1167 prueth_sw_port_dev_check,
1168 prueth_switchdev_obj_del);
1169 return notifier_from_errno(err);
1096 default: 1170 default:
1097 break; 1171 break;
1098 } 1172 }