aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPraneeth Bajjuri2021-01-05 14:15:31 -0600
committerPraneeth Bajjuri2021-01-05 14:15:31 -0600
commitb6cc3b3206a67cfa96eb76c223d5f629908e11b1 (patch)
treecad1d6f264954dde9f9dc46bfcbd13cb9f1022e4
parent2fcb7aeeee3091e0e8c905e26dbcd75f98f98374 (diff)
parent41c32273d7f5666a5637a109ec004fd746d5efac (diff)
downloadkernel-b6cc3b3206a67cfa96eb76c223d5f629908e11b1.tar.gz
kernel-b6cc3b3206a67cfa96eb76c223d5f629908e11b1.tar.xz
kernel-b6cc3b3206a67cfa96eb76c223d5f629908e11b1.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.y
* 'ti-linux-5.4.y' of git://git.ti.com/ti-linux-kernel/ti-linux-kernel: (26 commits) can: m_can: Set device to software init mode before closing arm64: dts: ti: k3-j7200-common-proc-board: add mcu cpsw nuss pinmux and phy defs arm64: dts: ti: k3-j7200-mcu: add mcu cpsw nuss node arm64: dts: ti: j7200-main: add timesync_router node arm64: dts: ti: j7200-main: add main navss cpts node arm64: dts: ti: k3-j7200: add DMA support dmaengine: ti: k3-psil: add map for j7200 soc: ti: k3-socinfo: Add entry for J7200 ARM: dts: am57xx-idk: Add hsr ptp tx interrupts ARM: dts: am57xx-idk: Add emac ptp tx interrupts net: ti: prueth: Add support for getting timestamping capabilitues from ethtool net: ti: prueth: Add support for setting and getting hwtimestamp configuration net: ti: prueth: Add support for reading timestamps from rx packets net: ti: prueth: hsr: Add support for timestamping tx packets dt-bindings: net: ti-prueth: Add ptp tx interrupt for hsr net: ti: prueth: dual_emac: Add support for timestamping tx packets dt-bindings: net: ti-prueth: Add ptp tx interrupt for dual emac net: socket: forward extra timestamp of received skb to user space net: socket: accept redundant network info in control message net: socket: pass on redundant net info to sock_recv_errqueue ... Signed-off-by: Praneeth Bajjuri <praneeth@ti.com>
-rw-r--r--Documentation/devicetree/bindings/net/ti-prueth.txt18
-rw-r--r--arch/arm/boot/dts/am571x-idk.dts8
-rw-r--r--arch/arm/boot/dts/am57xx-idk-common.dtsi8
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts63
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-main.dtsi83
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi119
-rw-r--r--drivers/dma/ti/Makefile5
-rw-r--r--drivers/dma/ti/k3-psil-j7200.c172
-rw-r--r--drivers/dma/ti/k3-psil-priv.h1
-rw-r--r--drivers/dma/ti/k3-psil.c1
-rw-r--r--drivers/net/can/m_can/m_can.c3
-rw-r--r--drivers/net/ethernet/ti/icss_switch.h3
-rw-r--r--drivers/net/ethernet/ti/prueth.h12
-rw-r--r--drivers/net/ethernet/ti/prueth_core.c407
-rw-r--r--drivers/net/ethernet/ti/prueth_lre.c26
-rw-r--r--drivers/net/ethernet/ti/prueth_ptp.h82
-rw-r--r--drivers/soc/ti/k3-socinfo.c1
-rw-r--r--include/linux/ptp_classify.h12
-rw-r--r--include/linux/skbuff.h33
-rw-r--r--include/net/sock.h29
-rw-r--r--include/uapi/asm-generic/socket.h6
-rw-r--r--net/core/skbuff.c8
-rw-r--r--net/core/sock.c14
-rw-r--r--net/hsr/hsr_device.c60
-rw-r--r--net/hsr/hsr_forward.c113
-rw-r--r--net/packet/af_packet.c4
-rw-r--r--net/socket.c19
27 files changed, 1271 insertions, 39 deletions
diff --git a/Documentation/devicetree/bindings/net/ti-prueth.txt b/Documentation/devicetree/bindings/net/ti-prueth.txt
index 8d511fcba728..846712bff953 100644
--- a/Documentation/devicetree/bindings/net/ti-prueth.txt
+++ b/Documentation/devicetree/bindings/net/ti-prueth.txt
@@ -48,8 +48,10 @@ Optional properties for children:
48 for small size frames. So use it only if 48 for small size frames. So use it only if
49 specific application uses mostly MTU or near 49 specific application uses mostly MTU or near
50 MTU size frames. 50 MTU size frames.
51- interrupts : Add interrupt sources for Tx if 51 add "emac_ptp_tx" when ptp is needed with Dual EMAC
52 interrupt-names "tx" used. 52 add "hsr_ptp_tx" when ptp is needed with hsr/prp.
53- interrupts : should contain an array of PRUSS system event
54 numbers for each entry in interrupt-names.
53 55
54Example (am572x-idk board, dual-emac): 56Example (am572x-idk board, dual-emac):
55====================================== 57======================================
@@ -64,8 +66,8 @@ Example (am572x-idk board, dual-emac):
64 pruss2_emac0: ethernet-mii0 { 66 pruss2_emac0: ethernet-mii0 {
65 phy-handle = <&pruss2_eth0_phy>; 67 phy-handle = <&pruss2_eth0_phy>;
66 phy-mode = "mii"; 68 phy-mode = "mii";
67 interrupts = <20>, <22>; 69 interrupts = <20>, <22>, <26>, <23>;
68 interrupt-names = "rx", "tx"; 70 interrupt-names = "rx", "tx", "emac_ptp_tx", "hsr_ptp_tx";
69 /* Filled in by bootloader */ 71 /* Filled in by bootloader */
70 local-mac-address = [00 00 00 00 00 00]; 72 local-mac-address = [00 00 00 00 00 00];
71 }; 73 };
@@ -73,8 +75,8 @@ Example (am572x-idk board, dual-emac):
73 pruss2_emac1: ethernet-mii1 { 75 pruss2_emac1: ethernet-mii1 {
74 phy-handle = <&pruss2_eth1_phy>; 76 phy-handle = <&pruss2_eth1_phy>;
75 phy-mode = "mii"; 77 phy-mode = "mii";
76 interrupts = <21>, <23>; 78 interrupts = <21>, <23>, <27>, <24>;
77 interrupt-names = "rx", "tx"; 79 interrupt-names = "rx", "tx", "emac_ptp_tx", "hsr_ptp_tx";
78 /* Filled in by bootloader */ 80 /* Filled in by bootloader */
79 local-mac-address = [00 00 00 00 00 00]; 81 local-mac-address = [00 00 00 00 00 00];
80 }; 82 };
@@ -93,8 +95,8 @@ Example (am572x-idk board, single-emac):
93 pruss2_emac1: ethernet-mii1 { 95 pruss2_emac1: ethernet-mii1 {
94 phy-handle = <&pruss2_eth1_phy>; 96 phy-handle = <&pruss2_eth1_phy>;
95 phy-mode = "mii"; 97 phy-mode = "mii";
96 interrupts = <21>, <23>; 98 interrupts = <21>, <23>, <27>, <24>;
97 interrupt-names = "rx", "tx"; 99 interrupt-names = "rx", "tx", "emac_ptp_tx", "hsr_ptp_tx";
98 /* Filled in by bootloader */ 100 /* Filled in by bootloader */
99 local-mac-address = [00 00 00 00 00 00]; 101 local-mac-address = [00 00 00 00 00 00];
100 }; 102 };
diff --git a/arch/arm/boot/dts/am571x-idk.dts b/arch/arm/boot/dts/am571x-idk.dts
index f7a97f61b9e8..d50c3f99b4b4 100644
--- a/arch/arm/boot/dts/am571x-idk.dts
+++ b/arch/arm/boot/dts/am571x-idk.dts
@@ -188,8 +188,8 @@
188 ethernet-mii0 { 188 ethernet-mii0 {
189 phy-handle = <&pruss1_eth0_phy>; 189 phy-handle = <&pruss1_eth0_phy>;
190 phy-mode = "mii"; 190 phy-mode = "mii";
191 interrupts = <20>; 191 interrupts = <20>, <26>, <23>;
192 interrupt-names = "rx"; 192 interrupt-names = "rx", "emac_ptp_tx", "hsr_ptp_tx";
193 ti,no-half-duplex; 193 ti,no-half-duplex;
194 /* Filled in by bootloader */ 194 /* Filled in by bootloader */
195 local-mac-address = [00 00 00 00 00 00]; 195 local-mac-address = [00 00 00 00 00 00];
@@ -198,8 +198,8 @@
198 ethernet-mii1 { 198 ethernet-mii1 {
199 phy-handle = <&pruss1_eth1_phy>; 199 phy-handle = <&pruss1_eth1_phy>;
200 phy-mode = "mii"; 200 phy-mode = "mii";
201 interrupts = <21>; 201 interrupts = <21>, <27>, <24>;
202 interrupt-names = "rx"; 202 interrupt-names = "rx", "emac_ptp_tx", "hsr_ptp_tx";
203 ti,no-half-duplex; 203 ti,no-half-duplex;
204 /* Filled in by bootloader */ 204 /* Filled in by bootloader */
205 local-mac-address = [00 00 00 00 00 00]; 205 local-mac-address = [00 00 00 00 00 00];
diff --git a/arch/arm/boot/dts/am57xx-idk-common.dtsi b/arch/arm/boot/dts/am57xx-idk-common.dtsi
index 0d9c3e02092e..5b9a9e127634 100644
--- a/arch/arm/boot/dts/am57xx-idk-common.dtsi
+++ b/arch/arm/boot/dts/am57xx-idk-common.dtsi
@@ -172,8 +172,8 @@
172 pruss2_emac0: ethernet-mii0 { 172 pruss2_emac0: ethernet-mii0 {
173 phy-handle = <&pruss2_eth0_phy>; 173 phy-handle = <&pruss2_eth0_phy>;
174 phy-mode = "mii"; 174 phy-mode = "mii";
175 interrupts = <20>; 175 interrupts = <20>, <26>, <23>;
176 interrupt-names = "rx"; 176 interrupt-names = "rx", "emac_ptp_tx", "hsr_ptp_tx";
177 ti,no-half-duplex; 177 ti,no-half-duplex;
178 /* Filled in by bootloader */ 178 /* Filled in by bootloader */
179 local-mac-address = [00 00 00 00 00 00]; 179 local-mac-address = [00 00 00 00 00 00];
@@ -182,8 +182,8 @@
182 pruss2_emac1: ethernet-mii1 { 182 pruss2_emac1: ethernet-mii1 {
183 phy-handle = <&pruss2_eth1_phy>; 183 phy-handle = <&pruss2_eth1_phy>;
184 phy-mode = "mii"; 184 phy-mode = "mii";
185 interrupts = <21>; 185 interrupts = <21>, <27>, <24>;
186 interrupt-names = "rx"; 186 interrupt-names = "rx", "emac_ptp_tx", "hsr_ptp_tx";
187 ti,no-half-duplex; 187 ti,no-half-duplex;
188 /* Filled in by bootloader */ 188 /* Filled in by bootloader */
189 local-mac-address = [00 00 00 00 00 00]; 189 local-mac-address = [00 00 00 00 00 00];
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 e27069317c4e..12c800b187f1 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
@@ -6,6 +6,7 @@
6/dts-v1/; 6/dts-v1/;
7 7
8#include "k3-j7200-som-p0.dtsi" 8#include "k3-j7200-som-p0.dtsi"
9#include <dt-bindings/net/ti-dp83867.h>
9 10
10/ { 11/ {
11 chosen { 12 chosen {
@@ -14,6 +15,32 @@
14 }; 15 };
15}; 16};
16 17
18&wkup_pmx0 {
19 mcu_cpsw_pins_default: mcu_cpsw_pins_default {
20 pinctrl-single,pins = <
21 J721E_WKUP_IOPAD(0x0068, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
22 J721E_WKUP_IOPAD(0x006c, PIN_INPUT, 0) /* MCU_RGMII1_RX_CTL */
23 J721E_WKUP_IOPAD(0x0070, PIN_OUTPUT, 0) /* MCU_RGMII1_TD3 */
24 J721E_WKUP_IOPAD(0x0074, PIN_OUTPUT, 0) /* MCU_RGMII1_TD2 */
25 J721E_WKUP_IOPAD(0x0078, PIN_OUTPUT, 0) /* MCU_RGMII1_TD1 */
26 J721E_WKUP_IOPAD(0x007c, PIN_OUTPUT, 0) /* MCU_RGMII1_TD0 */
27 J721E_WKUP_IOPAD(0x0088, PIN_INPUT, 0) /* MCU_RGMII1_RD3 */
28 J721E_WKUP_IOPAD(0x008c, PIN_INPUT, 0) /* MCU_RGMII1_RD2 */
29 J721E_WKUP_IOPAD(0x0090, PIN_INPUT, 0) /* MCU_RGMII1_RD1 */
30 J721E_WKUP_IOPAD(0x0094, PIN_INPUT, 0) /* MCU_RGMII1_RD0 */
31 J721E_WKUP_IOPAD(0x0080, PIN_INPUT, 0) /* MCU_RGMII1_TXC */
32 J721E_WKUP_IOPAD(0x0084, PIN_INPUT, 0) /* MCU_RGMII1_RXC */
33 >;
34 };
35
36 mcu_mdio_pins_default: mcu_mdio1_pins_default {
37 pinctrl-single,pins = <
38 J721E_WKUP_IOPAD(0x009c, PIN_OUTPUT, 0) /* (L1) MCU_MDIO0_MDC */
39 J721E_WKUP_IOPAD(0x0098, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */
40 >;
41 };
42};
43
17&wkup_uart0 { 44&wkup_uart0 {
18 /* Wakeup UART is used by System firmware */ 45 /* Wakeup UART is used by System firmware */
19 status = "disabled"; 46 status = "disabled";
@@ -62,3 +89,39 @@
62 /* UART not brought out */ 89 /* UART not brought out */
63 status = "disabled"; 90 status = "disabled";
64}; 91};
92
93&mcu_cpsw {
94 pinctrl-names = "default";
95 pinctrl-0 = <&mcu_cpsw_pins_default &mcu_mdio_pins_default>;
96
97 cpts {
98 ti,pps = <3 1>;
99 };
100};
101
102&davinci_mdio {
103 phy0: ethernet-phy@0 {
104 reg = <0>;
105 ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
106 ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
107 };
108};
109
110&cpsw_port1 {
111 phy-mode = "rgmii-rxid";
112 phy-handle = <&phy0>;
113};
114
115#define TS_OFFSET(pa, val) (0x4 + (pa) * 4) (0x10000 | val)
116
117&timesync_router {
118 pinctrl-names = "default";
119 pinctrl-0 = <&mcu_cpts>;
120
121 mcu_cpts: mcu_cpts {
122 pinctrl-single,pins = <
123 /* pps [cpts genf1] in17 -> out25 [cpts hw4_push] */
124 TS_OFFSET(25, 17)
125 >;
126 };
127};
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
index 70c8f7e941fb..0109f5cad461 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
@@ -45,6 +45,31 @@
45 #address-cells = <2>; 45 #address-cells = <2>;
46 #size-cells = <2>; 46 #size-cells = <2>;
47 ranges = <0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>; 47 ranges = <0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>;
48 ti,sci-dev-id = <199>;
49
50 main_navss_intr: interrupt-controller1 {
51 compatible = "ti,sci-intr";
52 ti,intr-trigger-type = <4>;
53 interrupt-controller;
54 interrupt-parent = <&gic500>;
55 #interrupt-cells = <1>;
56 ti,sci = <&dmsc>;
57 ti,sci-dev-id = <213>;
58 ti,interrupt-ranges = <0 64 64>,
59 <64 448 64>,
60 <128 672 64>;
61 };
62
63 main_udmass_inta: interrupt-controller@33d00000 {
64 compatible = "ti,sci-inta";
65 reg = <0x0 0x33d00000 0x0 0x100000>;
66 interrupt-controller;
67 interrupt-parent = <&main_navss_intr>;
68 msi-controller;
69 ti,sci = <&dmsc>;
70 ti,sci-dev-id = <209>;
71 ti,interrupt-ranges = <0 0 256>;
72 };
48 73
49 secure_proxy_main: mailbox@32c00000 { 74 secure_proxy_main: mailbox@32c00000 {
50 compatible = "ti,am654-secure-proxy"; 75 compatible = "ti,am654-secure-proxy";
@@ -56,6 +81,54 @@
56 interrupt-names = "rx_011"; 81 interrupt-names = "rx_011";
57 interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; 82 interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
58 }; 83 };
84
85 main_ringacc: ringacc@3c000000 {
86 compatible = "ti,am654-navss-ringacc";
87 reg = <0x0 0x3c000000 0x0 0x400000>,
88 <0x0 0x38000000 0x0 0x400000>,
89 <0x0 0x31120000 0x0 0x100>,
90 <0x0 0x33000000 0x0 0x40000>;
91 reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target";
92 ti,num-rings = <1024>;
93 ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */
94 ti,sci = <&dmsc>;
95 ti,sci-dev-id = <211>;
96 msi-parent = <&main_udmass_inta>;
97 };
98
99 main_udmap: dma-controller@31150000 {
100 compatible = "ti,j721e-navss-main-udmap";
101 reg = <0x0 0x31150000 0x0 0x100>,
102 <0x0 0x34000000 0x0 0x100000>,
103 <0x0 0x35000000 0x0 0x100000>;
104 reg-names = "gcfg", "rchanrt", "tchanrt";
105 msi-parent = <&main_udmass_inta>;
106 #dma-cells = <1>;
107
108 ti,sci = <&dmsc>;
109 ti,sci-dev-id = <212>;
110 ti,ringacc = <&main_ringacc>;
111
112 ti,sci-rm-range-tchan = <0x0d>, /* TX_CHAN */
113 <0x0f>, /* TX_HCHAN */
114 <0x10>; /* TX_UHCHAN */
115 ti,sci-rm-range-rchan = <0x0a>, /* RX_CHAN */
116 <0x0b>, /* RX_HCHAN */
117 <0x0c>; /* RX_UHCHAN */
118 ti,sci-rm-range-rflow = <0x00>; /* GP RFLOW */
119 };
120
121 cpts@310d0000 {
122 compatible = "ti,j721e-cpts";
123 reg = <0x0 0x310d0000 0x0 0x400>;
124 reg-names = "cpts";
125 clocks = <&k3_clks 201 1>;
126 clock-names = "cpts";
127 interrupts-extended = <&main_navss_intr 391>;
128 interrupt-names = "cpts";
129 ti,cpts-periodic-outputs = <6>;
130 ti,cpts-ext-ts-inputs = <8>;
131 };
59 }; 132 };
60 133
61 main_pmx0: pinmux@11c000 { 134 main_pmx0: pinmux@11c000 {
@@ -196,4 +269,14 @@
196 clocks = <&k3_clks 286 2>; 269 clocks = <&k3_clks 286 2>;
197 clock-names = "fclk"; 270 clock-names = "fclk";
198 }; 271 };
272
273 timesync_router: timesync_router@a40000 {
274 compatible = "pinctrl-single";
275 reg = <0x0 0xa40000 0x0 0x800>;
276 #address-cells = <1>;
277 #size-cells = <0>;
278 #pinctrl-cells = <1>;
279 pinctrl-single,register-width = <32>;
280 pinctrl-single,function-mask = <0x000107ff>;
281 };
199}; 282};
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 670e4c7cd9fe..9b6d2ac98edb 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
@@ -34,6 +34,20 @@
34 }; 34 };
35 }; 35 };
36 36
37 mcu_conf: syscon@40f00000 {
38 compatible = "syscon", "simple-mfd";
39 reg = <0x0 0x40f00000 0x0 0x20000>;
40 #address-cells = <1>;
41 #size-cells = <1>;
42 ranges = <0x0 0x0 0x40f00000 0x20000>;
43
44 phy_gmii_sel: phy@4040 {
45 compatible = "ti,am654-phy-gmii-sel";
46 reg = <0x4040 0x4>;
47 #phy-cells = <1>;
48 };
49 };
50
37 chipid@43000014 { 51 chipid@43000014 {
38 compatible = "ti,am654-chipid"; 52 compatible = "ti,am654-chipid";
39 reg = <0x0 0x43000014 0x0 0x4>; 53 reg = <0x0 0x43000014 0x0 0x4>;
@@ -81,4 +95,109 @@
81 clocks = <&k3_clks 149 2>; 95 clocks = <&k3_clks 149 2>;
82 clock-names = "fclk"; 96 clock-names = "fclk";
83 }; 97 };
98
99 cbass_mcu_navss: navss@28380000 {
100 compatible = "simple-mfd";
101 #address-cells = <2>;
102 #size-cells = <2>;
103 ranges;
104 dma-coherent;
105 dma-ranges;
106
107 ti,sci-dev-id = <232>;
108
109 mcu_ringacc: ringacc@2b800000 {
110 compatible = "ti,am654-navss-ringacc";
111 reg = <0x0 0x2b800000 0x0 0x400000>,
112 <0x0 0x2b000000 0x0 0x400000>,
113 <0x0 0x28590000 0x0 0x100>,
114 <0x0 0x2a500000 0x0 0x40000>;
115 reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target";
116 ti,num-rings = <286>;
117 ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */
118 ti,sci = <&dmsc>;
119 ti,sci-dev-id = <235>;
120 msi-parent = <&main_udmass_inta>;
121 };
122
123 mcu_udmap: dma-controller@285c0000 {
124 compatible = "ti,j721e-navss-mcu-udmap";
125 reg = <0x0 0x285c0000 0x0 0x100>,
126 <0x0 0x2a800000 0x0 0x40000>,
127 <0x0 0x2aa00000 0x0 0x40000>;
128 reg-names = "gcfg", "rchanrt", "tchanrt";
129 msi-parent = <&main_udmass_inta>;
130 #dma-cells = <1>;
131
132 ti,sci = <&dmsc>;
133 ti,sci-dev-id = <236>;
134 ti,ringacc = <&mcu_ringacc>;
135
136 ti,sci-rm-range-tchan = <0x0d>, /* TX_CHAN */
137 <0x0f>; /* TX_HCHAN */
138 ti,sci-rm-range-rchan = <0x0a>, /* RX_CHAN */
139 <0x0b>; /* RX_HCHAN */
140 ti,sci-rm-range-rflow = <0x00>; /* GP RFLOW */
141 };
142 };
143
144 mcu_cpsw: ethernet@46000000 {
145 compatible = "ti,j721e-cpsw-nuss";
146 #address-cells = <2>;
147 #size-cells = <2>;
148 reg = <0x0 0x46000000 0x0 0x200000>;
149 reg-names = "cpsw_nuss";
150 ranges = <0x0 0x0 0x0 0x46000000 0x0 0x200000>;
151 dma-coherent;
152 clocks = <&k3_clks 18 21>;
153 clock-names = "fck";
154 power-domains = <&k3_pds 18 TI_SCI_PD_EXCLUSIVE>;
155
156 dmas = <&mcu_udmap 0xf000>,
157 <&mcu_udmap 0xf001>,
158 <&mcu_udmap 0xf002>,
159 <&mcu_udmap 0xf003>,
160 <&mcu_udmap 0xf004>,
161 <&mcu_udmap 0xf005>,
162 <&mcu_udmap 0xf006>,
163 <&mcu_udmap 0xf007>,
164 <&mcu_udmap 0x7000>;
165 dma-names = "tx0", "tx1", "tx2", "tx3",
166 "tx4", "tx5", "tx6", "tx7",
167 "rx";
168
169 ethernet-ports {
170 #address-cells = <1>;
171 #size-cells = <0>;
172
173 cpsw_port1: port@1 {
174 reg = <1>;
175 ti,mac-only;
176 label = "port1";
177 ti,syscon-efuse = <&mcu_conf 0x200>;
178 phys = <&phy_gmii_sel 1>;
179 };
180 };
181
182 davinci_mdio: mdio@f00 {
183 compatible = "ti,cpsw-mdio","ti,davinci_mdio";
184 reg = <0x0 0xf00 0x0 0x100>;
185 #address-cells = <1>;
186 #size-cells = <0>;
187 clocks = <&k3_clks 18 21>;
188 clock-names = "fck";
189 bus_freq = <1000000>;
190 };
191
192 cpts@3d000 {
193 compatible = "ti,am65-cpts";
194 reg = <0x0 0x3d000 0x0 0x400>;
195 clocks = <&k3_clks 18 2>;
196 clock-names = "cpts";
197 interrupts-extended = <&gic500 GIC_SPI 858 IRQ_TYPE_LEVEL_HIGH>;
198 interrupt-names = "cpts";
199 ti,cpts-ext-ts-inputs = <4>;
200 ti,cpts-periodic-outputs = <2>;
201 };
202 };
84}; 203};
diff --git a/drivers/dma/ti/Makefile b/drivers/dma/ti/Makefile
index 9a29a107e374..0c67254caee6 100644
--- a/drivers/dma/ti/Makefile
+++ b/drivers/dma/ti/Makefile
@@ -4,5 +4,8 @@ obj-$(CONFIG_TI_EDMA) += edma.o
4obj-$(CONFIG_DMA_OMAP) += omap-dma.o 4obj-$(CONFIG_DMA_OMAP) += omap-dma.o
5obj-$(CONFIG_TI_K3_UDMA) += k3-udma.o 5obj-$(CONFIG_TI_K3_UDMA) += k3-udma.o
6obj-$(CONFIG_TI_K3_UDMA_GLUE_LAYER) += k3-udma-glue.o 6obj-$(CONFIG_TI_K3_UDMA_GLUE_LAYER) += k3-udma-glue.o
7obj-$(CONFIG_TI_K3_PSIL) += k3-psil.o k3-psil-am654.o k3-psil-j721e.o 7obj-$(CONFIG_TI_K3_PSIL) += k3-psil.o \
8 k3-psil-am654.o \
9 k3-psil-j721e.o \
10 k3-psil-j7200.o
8obj-$(CONFIG_TI_DMA_CROSSBAR) += dma-crossbar.o 11obj-$(CONFIG_TI_DMA_CROSSBAR) += dma-crossbar.o
diff --git a/drivers/dma/ti/k3-psil-j7200.c b/drivers/dma/ti/k3-psil-j7200.c
new file mode 100644
index 000000000000..19a71bd2be61
--- /dev/null
+++ b/drivers/dma/ti/k3-psil-j7200.c
@@ -0,0 +1,172 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com
4 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
5 */
6
7#include <linux/kernel.h>
8
9#include "k3-psil-priv.h"
10
11#define PSIL_PDMA_XY_TR(x) \
12 { \
13 .thread_id = x, \
14 .ep_config = { \
15 .ep_type = PSIL_EP_PDMA_XY, \
16 }, \
17 }
18
19#define PSIL_PDMA_XY_PKT(x) \
20 { \
21 .thread_id = x, \
22 .ep_config = { \
23 .ep_type = PSIL_EP_PDMA_XY, \
24 .pkt_mode = 1, \
25 }, \
26 }
27
28#define PSIL_PDMA_MCASP(x) \
29 { \
30 .thread_id = x, \
31 .ep_config = { \
32 .ep_type = PSIL_EP_PDMA_XY, \
33 .pdma_acc32 = 1, \
34 .pdma_burst = 1, \
35 }, \
36 }
37
38#define PSIL_ETHERNET(x) \
39 { \
40 .thread_id = x, \
41 .ep_config = { \
42 .ep_type = PSIL_EP_NATIVE, \
43 .pkt_mode = 1, \
44 .needs_epib = 1, \
45 .psd_size = 16, \
46 }, \
47 }
48
49#define PSIL_SA2UL(x, tx) \
50 { \
51 .thread_id = x, \
52 .ep_config = { \
53 .ep_type = PSIL_EP_NATIVE, \
54 .pkt_mode = 1, \
55 .needs_epib = 1, \
56 .psd_size = 64, \
57 .notdpkt = tx, \
58 }, \
59 }
60
61/* PSI-L source thread IDs, used for RX (DMA_DEV_TO_MEM) */
62static struct psil_ep j7200_src_ep_map[] = {
63 /* PDMA_MCASP - McASP0-2 */
64 PSIL_PDMA_MCASP(0x4400),
65 PSIL_PDMA_MCASP(0x4401),
66 PSIL_PDMA_MCASP(0x4402),
67 /* PDMA_SPI_G0 - SPI0-3 */
68 PSIL_PDMA_XY_PKT(0x4600),
69 PSIL_PDMA_XY_PKT(0x4601),
70 PSIL_PDMA_XY_PKT(0x4602),
71 PSIL_PDMA_XY_PKT(0x4603),
72 PSIL_PDMA_XY_PKT(0x4604),
73 PSIL_PDMA_XY_PKT(0x4605),
74 PSIL_PDMA_XY_PKT(0x4606),
75 PSIL_PDMA_XY_PKT(0x4607),
76 PSIL_PDMA_XY_PKT(0x4608),
77 PSIL_PDMA_XY_PKT(0x4609),
78 PSIL_PDMA_XY_PKT(0x460a),
79 PSIL_PDMA_XY_PKT(0x460b),
80 PSIL_PDMA_XY_PKT(0x460c),
81 PSIL_PDMA_XY_PKT(0x460d),
82 PSIL_PDMA_XY_PKT(0x460e),
83 PSIL_PDMA_XY_PKT(0x460f),
84 /* PDMA_SPI_G1 - SPI4-7 */
85 PSIL_PDMA_XY_PKT(0x4610),
86 PSIL_PDMA_XY_PKT(0x4611),
87 PSIL_PDMA_XY_PKT(0x4612),
88 PSIL_PDMA_XY_PKT(0x4613),
89 PSIL_PDMA_XY_PKT(0x4614),
90 PSIL_PDMA_XY_PKT(0x4615),
91 PSIL_PDMA_XY_PKT(0x4616),
92 PSIL_PDMA_XY_PKT(0x4617),
93 PSIL_PDMA_XY_PKT(0x4618),
94 PSIL_PDMA_XY_PKT(0x4619),
95 PSIL_PDMA_XY_PKT(0x461a),
96 PSIL_PDMA_XY_PKT(0x461b),
97 PSIL_PDMA_XY_PKT(0x461c),
98 PSIL_PDMA_XY_PKT(0x461d),
99 PSIL_PDMA_XY_PKT(0x461e),
100 PSIL_PDMA_XY_PKT(0x461f),
101 /* PDMA_USART_G0 - UART0-1 */
102 PSIL_PDMA_XY_PKT(0x4700),
103 PSIL_PDMA_XY_PKT(0x4701),
104 /* PDMA_USART_G1 - UART2-3 */
105 PSIL_PDMA_XY_PKT(0x4702),
106 PSIL_PDMA_XY_PKT(0x4703),
107 /* PDMA_USART_G2 - UART4-9 */
108 PSIL_PDMA_XY_PKT(0x4704),
109 PSIL_PDMA_XY_PKT(0x4705),
110 PSIL_PDMA_XY_PKT(0x4706),
111 PSIL_PDMA_XY_PKT(0x4707),
112 PSIL_PDMA_XY_PKT(0x4708),
113 PSIL_PDMA_XY_PKT(0x4709),
114 /* CPSW5 */
115 PSIL_ETHERNET(0x4a00),
116 /* CPSW0 */
117 PSIL_ETHERNET(0x7000),
118 /* MCU_PDMA_MISC_G0 - SPI0 */
119 PSIL_PDMA_XY_PKT(0x7100),
120 PSIL_PDMA_XY_PKT(0x7101),
121 PSIL_PDMA_XY_PKT(0x7102),
122 PSIL_PDMA_XY_PKT(0x7103),
123 /* MCU_PDMA_MISC_G1 - SPI1-2 */
124 PSIL_PDMA_XY_PKT(0x7200),
125 PSIL_PDMA_XY_PKT(0x7201),
126 PSIL_PDMA_XY_PKT(0x7202),
127 PSIL_PDMA_XY_PKT(0x7203),
128 PSIL_PDMA_XY_PKT(0x7204),
129 PSIL_PDMA_XY_PKT(0x7205),
130 PSIL_PDMA_XY_PKT(0x7206),
131 PSIL_PDMA_XY_PKT(0x7207),
132 /* MCU_PDMA_MISC_G2 - UART0 */
133 PSIL_PDMA_XY_PKT(0x7300),
134 /* MCU_PDMA_ADC - ADC0-1 */
135 PSIL_PDMA_XY_TR(0x7400),
136 PSIL_PDMA_XY_TR(0x7401),
137 /* SA2UL */
138 PSIL_SA2UL(0x7500, 0),
139 PSIL_SA2UL(0x7501, 0),
140};
141
142/* PSI-L destination thread IDs, used for TX (DMA_MEM_TO_DEV) */
143static struct psil_ep j7200_dst_ep_map[] = {
144 /* CPSW5 */
145 PSIL_ETHERNET(0xca00),
146 PSIL_ETHERNET(0xca01),
147 PSIL_ETHERNET(0xca02),
148 PSIL_ETHERNET(0xca03),
149 PSIL_ETHERNET(0xca04),
150 PSIL_ETHERNET(0xca05),
151 PSIL_ETHERNET(0xca06),
152 PSIL_ETHERNET(0xca07),
153 /* CPSW0 */
154 PSIL_ETHERNET(0xf000),
155 PSIL_ETHERNET(0xf001),
156 PSIL_ETHERNET(0xf002),
157 PSIL_ETHERNET(0xf003),
158 PSIL_ETHERNET(0xf004),
159 PSIL_ETHERNET(0xf005),
160 PSIL_ETHERNET(0xf006),
161 PSIL_ETHERNET(0xf007),
162 /* SA2UL */
163 PSIL_SA2UL(0xf500, 1),
164};
165
166struct psil_ep_map j7200_ep_map = {
167 .name = "j7200",
168 .src = j7200_src_ep_map,
169 .src_count = ARRAY_SIZE(j7200_src_ep_map),
170 .dst = j7200_dst_ep_map,
171 .dst_count = ARRAY_SIZE(j7200_dst_ep_map),
172};
diff --git a/drivers/dma/ti/k3-psil-priv.h b/drivers/dma/ti/k3-psil-priv.h
index a1f389ca371e..b4b0fb359eff 100644
--- a/drivers/dma/ti/k3-psil-priv.h
+++ b/drivers/dma/ti/k3-psil-priv.h
@@ -39,5 +39,6 @@ struct psil_endpoint_config *psil_get_ep_config(u32 thread_id);
39/* SoC PSI-L endpoint maps */ 39/* SoC PSI-L endpoint maps */
40extern struct psil_ep_map am654_ep_map; 40extern struct psil_ep_map am654_ep_map;
41extern struct psil_ep_map j721e_ep_map; 41extern struct psil_ep_map j721e_ep_map;
42extern struct psil_ep_map j7200_ep_map;
42 43
43#endif /* K3_PSIL_PRIV_H_ */ 44#endif /* K3_PSIL_PRIV_H_ */
diff --git a/drivers/dma/ti/k3-psil.c b/drivers/dma/ti/k3-psil.c
index 860a999b2aec..b687f0f96097 100644
--- a/drivers/dma/ti/k3-psil.c
+++ b/drivers/dma/ti/k3-psil.c
@@ -19,6 +19,7 @@ static const struct psil_ep_map *soc_ep_map;
19static const struct soc_device_attribute k3_soc_devices[] = { 19static const struct soc_device_attribute k3_soc_devices[] = {
20 { .family = "AM65X", .data = &am654_ep_map }, 20 { .family = "AM65X", .data = &am654_ep_map },
21 { .family = "J721E", .data = &j721e_ep_map }, 21 { .family = "J721E", .data = &j721e_ep_map },
22 { .family = "J7200", .data = &j7200_ep_map },
22 { /* sentinel */ } 23 { /* sentinel */ }
23}; 24};
24 25
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 562c8317e3aa..eeac2547d5e5 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -1366,6 +1366,9 @@ static void m_can_stop(struct net_device *dev)
1366 /* disable all interrupts */ 1366 /* disable all interrupts */
1367 m_can_disable_all_interrupts(cdev); 1367 m_can_disable_all_interrupts(cdev);
1368 1368
1369 /* Set init mode to disengage from the network */
1370 m_can_config_endisable(cdev, true);
1371
1369 /* set the state as STOPPED */ 1372 /* set the state as STOPPED */
1370 cdev->can.state = CAN_STATE_STOPPED; 1373 cdev->can.state = CAN_STATE_STOPPED;
1371} 1374}
diff --git a/drivers/net/ethernet/ti/icss_switch.h b/drivers/net/ethernet/ti/icss_switch.h
index 6b0ffe9895d8..173d710869a2 100644
--- a/drivers/net/ethernet/ti/icss_switch.h
+++ b/drivers/net/ethernet/ti/icss_switch.h
@@ -89,6 +89,9 @@
89#define PRUETH_BD_SHADOW_MASK BIT(14) 89#define PRUETH_BD_SHADOW_MASK BIT(14)
90#define PRUETH_BD_SHADOW_SHIFT 14 90#define PRUETH_BD_SHADOW_SHIFT 14
91 91
92#define PRUETH_BD_TIMESTAMP_MASK BIT(15)
93#define PRUETH_BD_TIMESTAMP_SHIT 15
94
92#define PRUETH_BD_PORT_MASK GENMASK(17, 16) 95#define PRUETH_BD_PORT_MASK GENMASK(17, 16)
93#define PRUETH_BD_PORT_SHIFT 16 96#define PRUETH_BD_PORT_SHIFT 16
94 97
diff --git a/drivers/net/ethernet/ti/prueth.h b/drivers/net/ethernet/ti/prueth.h
index a345f172ac52..ab6fcfe769cb 100644
--- a/drivers/net/ethernet/ti/prueth.h
+++ b/drivers/net/ethernet/ti/prueth.h
@@ -14,6 +14,7 @@
14#include <net/lredev.h> 14#include <net/lredev.h>
15 15
16#include "icss_switch.h" 16#include "icss_switch.h"
17#include "prueth_ptp.h"
17 18
18#define PRUETH_NUMQUEUES 5 19#define PRUETH_NUMQUEUES 5
19 20
@@ -103,6 +104,7 @@ struct prueth_queue_info {
103 * @sv_frame: indicate if the frame is a SV frame for HSR/PRP 104 * @sv_frame: indicate if the frame is a SV frame for HSR/PRP
104 * @lookup_success: src mac found in FDB 105 * @lookup_success: src mac found in FDB
105 * @flood: packet is to be flooded 106 * @flood: packet is to be flooded
107 * @timstamp: Specifies if timestamp is appended to the packet
106 */ 108 */
107struct prueth_packet_info { 109struct prueth_packet_info {
108 bool start_offset; 110 bool start_offset;
@@ -114,6 +116,7 @@ struct prueth_packet_info {
114 bool sv_frame; 116 bool sv_frame;
115 bool lookup_success; 117 bool lookup_success;
116 bool flood; 118 bool flood;
119 bool timestamp;
117}; 120};
118 121
119/** 122/**
@@ -377,6 +380,13 @@ struct prueth_emac {
377 bool nsp_enabled; 380 bool nsp_enabled;
378 381
379 int offload_fwd_mark; 382 int offload_fwd_mark;
383
384 struct sk_buff *ptp_skb[PRUETH_PTP_TS_EVENTS];
385 spinlock_t ptp_skb_lock; /* serialize access */
386 int emac_ptp_tx_irq;
387 int hsr_ptp_tx_irq;
388 bool ptp_tx_enable;
389 bool ptp_rx_enable;
380}; 390};
381 391
382struct prueth_ndev_priority { 392struct prueth_ndev_priority {
@@ -482,6 +492,8 @@ int emac_rx_packet(struct prueth_emac *emac, u16 *bd_rd_ptr,
482 const struct prueth_queue_info *rxqueue); 492 const struct prueth_queue_info *rxqueue);
483int emac_add_del_vid(struct prueth_emac *emac, 493int emac_add_del_vid(struct prueth_emac *emac,
484 bool add, __be16 proto, u16 vid); 494 bool add, __be16 proto, u16 vid);
495irqreturn_t prueth_ptp_tx_irq_handle(int irq, void *dev);
496irqreturn_t prueth_ptp_tx_irq_work(int irq, void *dev);
485 497
486extern const struct prueth_queue_desc queue_descs[][NUM_QUEUES]; 498extern const struct prueth_queue_desc queue_descs[][NUM_QUEUES];
487 499
diff --git a/drivers/net/ethernet/ti/prueth_core.c b/drivers/net/ethernet/ti/prueth_core.c
index c3576155e93a..2a0176ea6101 100644
--- a/drivers/net/ethernet/ti/prueth_core.c
+++ b/drivers/net/ethernet/ti/prueth_core.c
@@ -15,6 +15,7 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/mfd/syscon.h> 16#include <linux/mfd/syscon.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/net_tstamp.h>
18#include <linux/of.h> 19#include <linux/of.h>
19#include <linux/of_irq.h> 20#include <linux/of_irq.h>
20#include <linux/of_mdio.h> 21#include <linux/of_mdio.h>
@@ -22,6 +23,7 @@
22#include <linux/of_platform.h> 23#include <linux/of_platform.h>
23#include <linux/phy.h> 24#include <linux/phy.h>
24#include <linux/pruss.h> 25#include <linux/pruss.h>
26#include <linux/ptp_classify.h>
25#include <linux/regmap.h> 27#include <linux/regmap.h>
26#include <linux/remoteproc.h> 28#include <linux/remoteproc.h>
27#include <net/pkt_cls.h> 29#include <net/pkt_cls.h>
@@ -151,6 +153,39 @@ static inline void prueth_write_reg(struct prueth *prueth,
151 writel_relaxed(val, prueth->mem[region].va + reg); 153 writel_relaxed(val, prueth->mem[region].va + reg);
152} 154}
153 155
156static inline void prueth_ptp_ts_enable(struct prueth_emac *emac)
157{
158 void __iomem *sram = emac->prueth->mem[PRUETH_MEM_SHARED_RAM].va;
159 u8 val = 0;
160
161 if (emac->ptp_tx_enable)
162 val = TIMESYNC_CTRL_FORCED_2STEP | TIMESYNC_CTRL_BG_ENABLE;
163
164 writeb(val, sram + TIMESYNC_CTRL_VAR_OFFSET);
165}
166
167static inline void prueth_ptp_tx_ts_enable(struct prueth_emac *emac, bool enable)
168{
169 emac->ptp_tx_enable = enable;
170 prueth_ptp_ts_enable(emac);
171}
172
173static inline bool prueth_ptp_tx_ts_is_enabled(struct prueth_emac *emac)
174{
175 return !!emac->ptp_tx_enable;
176}
177
178static inline void prueth_ptp_rx_ts_enable(struct prueth_emac *emac, bool enable)
179{
180 emac->ptp_rx_enable = enable;
181 prueth_ptp_ts_enable(emac);
182}
183
184static inline bool prueth_ptp_rx_ts_is_enabled(struct prueth_emac *emac)
185{
186 return !!emac->ptp_rx_enable;
187}
188
154static inline 189static inline
155void prueth_set_reg(struct prueth *prueth, enum prueth_mem region, 190void prueth_set_reg(struct prueth *prueth, enum prueth_mem region,
156 unsigned int reg, u32 mask, u32 set) 191 unsigned int reg, u32 mask, u32 set)
@@ -715,6 +750,205 @@ static irqreturn_t emac_rx_hardirq(int irq, void *dev_id)
715 return IRQ_HANDLED; 750 return IRQ_HANDLED;
716} 751}
717 752
753static u8 prueth_ptp_ts_event_type(struct sk_buff *skb)
754{
755 u8 *msgtype, *data, event_type, changed = 0;
756 unsigned int offset = 0, ptp_class;
757 u16 *seqid;
758
759 if (eth_hdr(skb)->h_proto == htons(ETH_P_HSR)) {
760 /* This 6-byte shift is just a trick to skip
761 * the size of a hsr tag so that the same
762 * pruptp_ts_msgtype can be re-used to parse
763 * hsr tagged skbs
764 */
765 skb->data += 6;
766 changed = 6;
767 }
768
769 ptp_class = ptp_classify_raw(skb);
770 data = skb->data;
771 if (ptp_class == PTP_CLASS_NONE) {
772 event_type = PRUETH_PTP_TS_EVENTS;
773 goto exit;
774 }
775
776 if (ptp_class & PTP_CLASS_VLAN)
777 offset += VLAN_HLEN;
778
779 switch (ptp_class & PTP_CLASS_PMASK) {
780 case PTP_CLASS_IPV4:
781 offset += ETH_HLEN + IPV4_HLEN(data + offset) + UDP_HLEN;
782 break;
783 case PTP_CLASS_IPV6:
784 offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
785 break;
786 case PTP_CLASS_L2:
787 offset += ETH_HLEN;
788 break;
789 default:
790 return PRUETH_PTP_TS_EVENTS;
791 }
792
793 if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID + sizeof(*seqid)) {
794 event_type = PRUETH_PTP_TS_EVENTS;
795 goto exit;
796 }
797
798 if (unlikely(ptp_class & PTP_CLASS_V1))
799 msgtype = data + offset + OFF_PTP_CONTROL;
800 else
801 msgtype = data + offset;
802
803 /*
804 * Treat E2E Delay Req/Resp messages sane as P2P peer delay req/resp
805 * in driver here since firmware stores timestamps in the same memory
806 * location for either (since they cannot operate simultaneously
807 * anyway)
808 */
809 switch (*msgtype & 0xf) {
810 case PTP_SYNC_MSG_ID:
811 event_type = PRUETH_PTP_SYNC;
812 break;
813 case PTP_DLY_REQ_MSG_ID:
814 case PTP_PDLY_REQ_MSG_ID:
815 event_type = PRUETH_PTP_DLY_REQ;
816 break;
817 case PTP_DLY_RESP_MSG_ID:
818 case PTP_PDLY_RSP_MSG_ID:
819 event_type = PRUETH_PTP_DLY_RESP;
820 break;
821 default:
822 event_type = PRUETH_PTP_TS_EVENTS;
823 }
824
825exit:
826 skb->data -= changed;
827
828 return event_type;
829}
830
831static void prueth_ptp_tx_ts_reset(struct prueth_emac *emac, u8 event)
832{
833 void __iomem *sram = emac->prueth->mem[PRUETH_MEM_SHARED_RAM].va;
834 u32 ts_notify_offs, ts_offs;
835
836 ts_offs = prueth_tx_ts_offs_get(emac->port_id - 1, event);
837 ts_notify_offs = prueth_tx_ts_notify_offs_get(emac->port_id - 1, event);
838
839 writeb(0, sram + ts_notify_offs);
840 memset_io(sram + ts_offs, 0, sizeof(u64));
841}
842
843static int prueth_ptp_tx_ts_enqueue(struct prueth_emac *emac, struct sk_buff *skb)
844{
845 unsigned long flags;
846 u8 event;
847
848 event = prueth_ptp_ts_event_type(skb);
849 if (event == PRUETH_PTP_TS_EVENTS) {
850 netdev_err(emac->ndev, "invalid PTP event\n");
851 return -EINVAL;
852 }
853
854 spin_lock_irqsave(&emac->ptp_skb_lock, flags);
855 if (emac->ptp_skb[event]) {
856 dev_consume_skb_any(emac->ptp_skb[event]);
857 prueth_ptp_tx_ts_reset(emac, event);
858 netdev_warn(emac->ndev, "Dropped event waiting for tx ts.\n");
859 }
860
861 skb_get(skb);
862 emac->ptp_skb[event] = skb;
863 spin_unlock_irqrestore(&emac->ptp_skb_lock, flags);
864
865 return 0;
866}
867
868irqreturn_t prueth_ptp_tx_irq_handle(int irq, void *dev)
869{
870 struct net_device *ndev = (struct net_device *)dev;
871 struct prueth_emac *emac = netdev_priv(ndev);
872
873 if (unlikely(netif_queue_stopped(ndev)))
874 netif_wake_queue(ndev);
875
876 if (prueth_ptp_tx_ts_is_enabled(emac))
877 return IRQ_WAKE_THREAD;
878
879 return IRQ_HANDLED;
880}
881
882static u64 prueth_ptp_ts_get(struct prueth_emac *emac, u32 ts_offs)
883{
884 void __iomem *sram = emac->prueth->mem[PRUETH_MEM_SHARED_RAM].va;
885 u64 cycles;
886
887 memcpy_fromio(&cycles, sram + ts_offs, sizeof(cycles));
888 memset_io(sram + ts_offs, 0, sizeof(cycles));
889
890 return cycles;
891}
892
893static void prueth_ptp_tx_ts_get(struct prueth_emac *emac, u8 event)
894{
895 struct skb_shared_hwtstamps ssh;
896 struct sk_buff *skb;
897 unsigned long flags;
898 u64 ns;
899
900 /* get the msg from list */
901 spin_lock_irqsave(&emac->ptp_skb_lock, flags);
902 skb = emac->ptp_skb[event];
903 emac->ptp_skb[event] = NULL;
904 spin_unlock_irqrestore(&emac->ptp_skb_lock, flags);
905 if (!skb) {
906 /* In case of HSR, tx timestamp may be generated by
907 * cut-through packets such as SYNC, which does not
908 * have a corresponding queued tx packet. Such a tx
909 * timestamp is consumed by the rx port when processing
910 * the rx timestamp.
911 */
912 if (PRUETH_IS_LRE(emac->prueth))
913 return;
914
915 netdev_err(emac->ndev, "no tx msg %u found waiting for ts\n",
916 event);
917 return;
918 }
919
920 /* get timestamp */
921 ns = prueth_ptp_ts_get(emac,
922 prueth_tx_ts_offs_get(emac->port_id - 1, event));
923 memset(&ssh, 0, sizeof(ssh));
924 ssh.hwtstamp = ns_to_ktime(ns);
925 skb_tstamp_tx(skb, &ssh);
926
927 dev_consume_skb_any(skb);
928}
929
930irqreturn_t prueth_ptp_tx_irq_work(int irq, void *dev)
931{
932 struct prueth_emac *emac = netdev_priv(dev);
933 u32 ts_notify_offs, ts_notify_mask, i;
934 void __iomem *sram;
935
936 /* get and reset the ts notifications */
937 sram = emac->prueth->mem[PRUETH_MEM_SHARED_RAM].va;
938 for (i = 0; i < PRUETH_PTP_TS_EVENTS; i++) {
939 ts_notify_offs = prueth_tx_ts_notify_offs_get(emac->port_id - 1,
940 i);
941 memcpy_fromio(&ts_notify_mask, sram + ts_notify_offs,
942 PRUETH_PTP_TS_NOTIFY_SIZE);
943 memset_io(sram + ts_notify_offs, 0, PRUETH_PTP_TS_NOTIFY_SIZE);
944
945 if (ts_notify_mask & PRUETH_PTP_TS_NOTIFY_MASK)
946 prueth_ptp_tx_ts_get(emac, i);
947 }
948
949 return IRQ_HANDLED;
950}
951
718/** 952/**
719 * prueth_tx_enqueue - queue a packet to firmware for transmission 953 * prueth_tx_enqueue - queue a packet to firmware for transmission
720 * 954 *
@@ -829,6 +1063,12 @@ static int prueth_tx_enqueue(struct prueth_emac *emac, struct sk_buff *skb,
829 memcpy(dst_addr, src_addr, pktlen); 1063 memcpy(dst_addr, src_addr, pktlen);
830 } 1064 }
831 1065
1066 if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
1067 prueth_ptp_tx_ts_is_enabled(emac)) {
1068 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
1069 prueth_ptp_tx_ts_enqueue(emac, skb);
1070 }
1071
832 /* update first buffer descriptor */ 1072 /* update first buffer descriptor */
833 wr_buf_desc = (pktlen << PRUETH_BD_LENGTH_SHIFT) & PRUETH_BD_LENGTH_MASK; 1073 wr_buf_desc = (pktlen << PRUETH_BD_LENGTH_SHIFT) & PRUETH_BD_LENGTH_MASK;
834 if (PRUETH_IS_HSR(prueth)) 1074 if (PRUETH_IS_HSR(prueth))
@@ -882,6 +1122,7 @@ void parse_packet_info(struct prueth *prueth, u32 buffer_descriptor,
882 pkt_info->lookup_success = !!(buffer_descriptor & 1122 pkt_info->lookup_success = !!(buffer_descriptor &
883 PRUETH_BD_LOOKUP_SUCCESS_MASK); 1123 PRUETH_BD_LOOKUP_SUCCESS_MASK);
884 pkt_info->flood = !!(buffer_descriptor & PRUETH_BD_SW_FLOOD_MASK); 1124 pkt_info->flood = !!(buffer_descriptor & PRUETH_BD_SW_FLOOD_MASK);
1125 pkt_info->timestamp = !!(buffer_descriptor & PRUETH_BD_TIMESTAMP_MASK);
885} 1126}
886 1127
887/* get packet from queue 1128/* get packet from queue
@@ -904,9 +1145,11 @@ int emac_rx_packet(struct prueth_emac *emac, u16 *bd_rd_ptr,
904 u8 macid[6]; 1145 u8 macid[6];
905 /* OCMC RAM is not cached and read order is not important */ 1146 /* OCMC RAM is not cached and read order is not important */
906 void *ocmc_ram = (__force void *)emac->prueth->mem[PRUETH_MEM_OCMC].va; 1147 void *ocmc_ram = (__force void *)emac->prueth->mem[PRUETH_MEM_OCMC].va;
1148 struct skb_shared_hwtstamps *ssh;
907 unsigned int actual_pkt_len; 1149 unsigned int actual_pkt_len;
908 u16 start_offset = 0, type; 1150 u16 start_offset = 0, type;
909 u8 offset = 0, *ptr; 1151 u8 offset = 0, *ptr;
1152 u64 ts;
910 1153
911 if (PRUETH_IS_HSR(prueth)) 1154 if (PRUETH_IS_HSR(prueth))
912 start_offset = (pkt_info.start_offset ? 1155 start_offset = (pkt_info.start_offset ?
@@ -989,8 +1232,16 @@ int emac_rx_packet(struct prueth_emac *emac, u16 *bd_rd_ptr,
989 else 1232 else
990 src_addr = ocmc_ram + rxqueue->buffer_offset; 1233 src_addr = ocmc_ram + rxqueue->buffer_offset;
991 memcpy(dst_addr, src_addr, remaining); 1234 memcpy(dst_addr, src_addr, remaining);
1235 src_addr += remaining;
992 } else { 1236 } else {
993 memcpy(dst_addr, src_addr, actual_pkt_len); 1237 memcpy(dst_addr, src_addr, actual_pkt_len);
1238 src_addr += actual_pkt_len;
1239 }
1240
1241 if (pkt_info.timestamp) {
1242 src_addr = (void *)roundup((uintptr_t)src_addr, ICSS_BLOCK_SIZE);
1243 dst_addr = &ts;
1244 memcpy(dst_addr, src_addr, sizeof(ts));
994 } 1245 }
995 1246
996 /* Check if VLAN tag is present since SV payload location will change 1247 /* Check if VLAN tag is present since SV payload location will change
@@ -1000,6 +1251,7 @@ int emac_rx_packet(struct prueth_emac *emac, u16 *bd_rd_ptr,
1000 ptr = nt_dst_addr + PRUETH_ETH_TYPE_OFFSET; 1251 ptr = nt_dst_addr + PRUETH_ETH_TYPE_OFFSET;
1001 type = (*ptr++) << PRUETH_ETH_TYPE_UPPER_SHIFT; 1252 type = (*ptr++) << PRUETH_ETH_TYPE_UPPER_SHIFT;
1002 type |= *ptr++; 1253 type |= *ptr++;
1254 eth_hdr(skb)->h_proto = htons(type);
1003 if (type == ETH_P_8021Q) 1255 if (type == ETH_P_8021Q)
1004 offset = 4; 1256 offset = 4;
1005 } 1257 }
@@ -1047,6 +1299,12 @@ int emac_rx_packet(struct prueth_emac *emac, u16 *bd_rd_ptr,
1047 prueth_sw_learn_fdb(emac, skb->data + ETH_ALEN); 1299 prueth_sw_learn_fdb(emac, skb->data + ETH_ALEN);
1048 } 1300 }
1049 1301
1302 if (prueth_ptp_rx_ts_is_enabled(emac)) {
1303 ssh = skb_hwtstamps(skb);
1304 memset(ssh, 0, sizeof(*ssh));
1305 ssh->hwtstamp = ns_to_ktime(ts);
1306 }
1307
1050 /* send packet up the stack */ 1308 /* send packet up the stack */
1051 skb->protocol = eth_type_trans(skb, ndev); 1309 skb->protocol = eth_type_trans(skb, ndev);
1052 netif_receive_skb(skb); 1310 netif_receive_skb(skb);
@@ -1266,6 +1524,30 @@ static int emac_request_irqs(struct prueth_emac *emac)
1266 return ret; 1524 return ret;
1267 } 1525 }
1268 1526
1527 if (PRUETH_IS_EMAC(emac->prueth) && emac->tx_irq > 0) {
1528 ret = request_irq(emac->tx_irq, emac_tx_hardirq,
1529 IRQF_TRIGGER_HIGH, ndev->name, ndev);
1530 if (ret) {
1531 netdev_err(ndev, "unable to request TX IRQ\n");
1532 free_irq(emac->rx_irq, ndev);
1533 return ret;
1534 }
1535 }
1536
1537 if (emac->emac_ptp_tx_irq) {
1538 ret = request_threaded_irq(emac->emac_ptp_tx_irq,
1539 prueth_ptp_tx_irq_handle,
1540 prueth_ptp_tx_irq_work,
1541 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
1542 ndev->name, ndev);
1543 if (ret) {
1544 netdev_err(ndev, "unable to request PTP TX IRQ\n");
1545 free_irq(emac->rx_irq, ndev);
1546 free_irq(emac->tx_irq, ndev);
1547 }
1548
1549 }
1550
1269 return ret; 1551 return ret;
1270} 1552}
1271 1553
@@ -1395,15 +1677,6 @@ static int emac_ndo_open(struct net_device *ndev)
1395 } 1677 }
1396 } 1678 }
1397 1679
1398 if (PRUETH_IS_EMAC(prueth) && emac->tx_irq > 0) {
1399 ret = request_irq(emac->tx_irq, emac_tx_hardirq,
1400 IRQF_TRIGGER_HIGH, ndev->name, ndev);
1401 if (ret) {
1402 netdev_err(ndev, "unable to request TX IRQ\n");
1403 goto free_rx_irq;
1404 }
1405 }
1406
1407 /* start PHY */ 1680 /* start PHY */
1408 phy_start(emac->phydev); 1681 phy_start(emac->phydev);
1409 1682
@@ -1425,8 +1698,6 @@ static int emac_ndo_open(struct net_device *ndev)
1425 1698
1426 return 0; 1699 return 0;
1427 1700
1428free_rx_irq:
1429 free_irq(emac->rx_irq, ndev);
1430rproc_shutdown: 1701rproc_shutdown:
1431 if (!PRUETH_IS_EMAC(prueth)) 1702 if (!PRUETH_IS_EMAC(prueth))
1432 prueth_sw_shutdown_prus(emac, ndev); 1703 prueth_sw_shutdown_prus(emac, ndev);
@@ -1452,6 +1723,7 @@ static int emac_ndo_stop(struct net_device *ndev)
1452{ 1723{
1453 struct prueth_emac *emac = netdev_priv(ndev); 1724 struct prueth_emac *emac = netdev_priv(ndev);
1454 struct prueth *prueth = emac->prueth; 1725 struct prueth *prueth = emac->prueth;
1726 int i;
1455 1727
1456 mutex_lock(&prueth->mlock); 1728 mutex_lock(&prueth->mlock);
1457 prueth->emac_configured &= ~BIT(emac->port_id); 1729 prueth->emac_configured &= ~BIT(emac->port_id);
@@ -1499,6 +1771,16 @@ static int emac_ndo_stop(struct net_device *ndev)
1499 */ 1771 */
1500 if (PRUETH_IS_EMAC(emac->prueth) || PRUETH_IS_SWITCH(prueth)) { 1772 if (PRUETH_IS_EMAC(emac->prueth) || PRUETH_IS_SWITCH(prueth)) {
1501 free_irq(emac->rx_irq, ndev); 1773 free_irq(emac->rx_irq, ndev);
1774 free_irq(emac->emac_ptp_tx_irq, ndev);
1775 prueth_ptp_tx_ts_enable(emac, 0);
1776 prueth_ptp_rx_ts_enable(emac, 0);
1777 for (i = 0; i < PRUETH_PTP_TS_EVENTS; i++) {
1778 if (emac->ptp_skb[i]) {
1779 prueth_ptp_tx_ts_reset(emac, i);
1780 dev_consume_skb_any(emac->ptp_skb[i]);
1781 emac->ptp_skb[i] = NULL;
1782 }
1783 }
1502 } else { 1784 } else {
1503 /* Free interrupts on last port */ 1785 /* Free interrupts on last port */
1504 prueth_lre_free_irqs(emac); 1786 prueth_lre_free_irqs(emac);
@@ -1900,10 +2182,74 @@ unlock:
1900 spin_unlock_irqrestore(&emac->addr_lock, flags); 2182 spin_unlock_irqrestore(&emac->addr_lock, flags);
1901} 2183}
1902 2184
2185static int emac_hwtstamp_config_set(struct net_device *ndev, struct ifreq *ifr)
2186{
2187 struct prueth_emac *emac = netdev_priv(ndev);
2188 struct hwtstamp_config cfg;
2189
2190 if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
2191 return -EFAULT;
2192
2193 /* reserved for future extensions */
2194 if (cfg.flags)
2195 return -EINVAL;
2196
2197 if (cfg.tx_type != HWTSTAMP_TX_OFF && cfg.tx_type != HWTSTAMP_TX_ON)
2198 return -ERANGE;
2199
2200 switch (cfg.rx_filter) {
2201 case HWTSTAMP_FILTER_NONE:
2202 prueth_ptp_rx_ts_enable(emac, 0);
2203 break;
2204 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
2205 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
2206 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
2207 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
2208 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
2209 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
2210 case HWTSTAMP_FILTER_PTP_V2_EVENT:
2211 case HWTSTAMP_FILTER_PTP_V2_SYNC:
2212 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
2213 prueth_ptp_rx_ts_enable(emac, 1);
2214 cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
2215 break;
2216 case HWTSTAMP_FILTER_ALL:
2217 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
2218 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
2219 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
2220 default:
2221 return -ERANGE;
2222 }
2223
2224 prueth_ptp_tx_ts_enable(emac, cfg.tx_type == HWTSTAMP_TX_ON);
2225
2226 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
2227}
2228static int emac_hwtstamp_config_get(struct net_device *ndev, struct ifreq *ifr)
2229{
2230 struct prueth_emac *emac = netdev_priv(ndev);
2231 struct hwtstamp_config cfg;
2232
2233 cfg.flags = 0;
2234 cfg.tx_type = prueth_ptp_tx_ts_is_enabled(emac) ?
2235 HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
2236 cfg.rx_filter = prueth_ptp_rx_ts_is_enabled(emac) ?
2237 HWTSTAMP_FILTER_PTP_V2_EVENT : HWTSTAMP_FILTER_NONE;
2238
2239 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
2240}
2241
1903static int emac_ndo_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) 2242static int emac_ndo_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
1904{ 2243{
1905 struct prueth_emac *emac = netdev_priv(ndev); 2244 struct prueth_emac *emac = netdev_priv(ndev);
1906 2245
2246 switch (cmd) {
2247 case SIOCSHWTSTAMP:
2248 return emac_hwtstamp_config_set(ndev, ifr);
2249 case SIOCGHWTSTAMP:
2250 return emac_hwtstamp_config_get(ndev, ifr);
2251 }
2252
1907 return phy_mii_ioctl(emac->phydev, ifr, cmd); 2253 return phy_mii_ioctl(emac->phydev, ifr, cmd);
1908} 2254}
1909 2255
@@ -2304,13 +2650,37 @@ static void emac_get_regs(struct net_device *ndev, struct ethtool_regs *regs,
2304 } 2650 }
2305} 2651}
2306 2652
2653static int emac_get_ts_info(struct net_device *ndev,
2654 struct ethtool_ts_info *info)
2655{
2656 struct prueth_emac *emac = netdev_priv(ndev);
2657
2658 if ((PRUETH_IS_EMAC(emac->prueth) && !emac->emac_ptp_tx_irq) ||
2659 (PRUETH_IS_LRE(emac->prueth) && !emac->hsr_ptp_tx_irq))
2660 return ethtool_op_get_ts_info(ndev, info);
2661
2662 info->so_timestamping =
2663 SOF_TIMESTAMPING_TX_HARDWARE |
2664 SOF_TIMESTAMPING_TX_SOFTWARE |
2665 SOF_TIMESTAMPING_RX_HARDWARE |
2666 SOF_TIMESTAMPING_RX_SOFTWARE |
2667 SOF_TIMESTAMPING_SOFTWARE |
2668 SOF_TIMESTAMPING_RAW_HARDWARE;
2669
2670 info->phc_index = ptp_clock_index(icss_iep_get_ptp_clock(emac->prueth->iep));
2671 info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
2672 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
2673
2674 return 0;
2675}
2676
2307/* Ethtool support for EMAC adapter */ 2677/* Ethtool support for EMAC adapter */
2308static const struct ethtool_ops emac_ethtool_ops = { 2678static const struct ethtool_ops emac_ethtool_ops = {
2309 .get_drvinfo = emac_get_drvinfo, 2679 .get_drvinfo = emac_get_drvinfo,
2310 .get_link_ksettings = emac_get_link_ksettings, 2680 .get_link_ksettings = emac_get_link_ksettings,
2311 .set_link_ksettings = emac_set_link_ksettings, 2681 .set_link_ksettings = emac_set_link_ksettings,
2312 .get_link = ethtool_op_get_link, 2682 .get_link = ethtool_op_get_link,
2313 .get_ts_info = ethtool_op_get_ts_info, 2683 .get_ts_info = emac_get_ts_info,
2314 .get_sset_count = emac_get_sset_count, 2684 .get_sset_count = emac_get_sset_count,
2315 .get_strings = emac_get_strings, 2685 .get_strings = emac_get_strings,
2316 .get_ethtool_stats = emac_get_ethtool_stats, 2686 .get_ethtool_stats = emac_get_ethtool_stats,
@@ -2410,10 +2780,23 @@ static int prueth_netdev_init(struct prueth *prueth,
2410 dev_dbg(prueth->dev, "tx irq not configured\n"); 2780 dev_dbg(prueth->dev, "tx irq not configured\n");
2411 } 2781 }
2412 2782
2783 emac->emac_ptp_tx_irq = of_irq_get_byname(eth_node, "emac_ptp_tx");
2784 if (emac->emac_ptp_tx_irq < 0) {
2785 emac->emac_ptp_tx_irq = 0;
2786 dev_err(prueth->dev, "could not get ptp tx irq. Skipping PTP support\n");
2787 }
2788
2789 emac->hsr_ptp_tx_irq = of_irq_get_byname(eth_node, "hsr_ptp_tx");
2790 if (emac->hsr_ptp_tx_irq < 0) {
2791 emac->hsr_ptp_tx_irq = 0;
2792 dev_err(prueth->dev, "could not get hsr ptp tx irq. Skipping PTP support\n");
2793 }
2794
2413 emac->msg_enable = netif_msg_init(debug_level, PRUETH_EMAC_DEBUG); 2795 emac->msg_enable = netif_msg_init(debug_level, PRUETH_EMAC_DEBUG);
2414 spin_lock_init(&emac->lock); 2796 spin_lock_init(&emac->lock);
2415 spin_lock_init(&emac->nsp_lock); 2797 spin_lock_init(&emac->nsp_lock);
2416 spin_lock_init(&emac->addr_lock); 2798 spin_lock_init(&emac->addr_lock);
2799 spin_lock_init(&emac->ptp_skb_lock);
2417 2800
2418 /* get mac address from DT and set private and netdev addr */ 2801 /* get mac address from DT and set private and netdev addr */
2419 mac_addr = of_get_mac_address(eth_node); 2802 mac_addr = of_get_mac_address(eth_node);
diff --git a/drivers/net/ethernet/ti/prueth_lre.c b/drivers/net/ethernet/ti/prueth_lre.c
index 15ab6b9e2141..275138c09a93 100644
--- a/drivers/net/ethernet/ti/prueth_lre.c
+++ b/drivers/net/ethernet/ti/prueth_lre.c
@@ -858,6 +858,19 @@ int prueth_lre_request_irqs(struct prueth_emac *emac)
858 struct prueth *prueth = emac->prueth; 858 struct prueth *prueth = emac->prueth;
859 int ret; 859 int ret;
860 860
861 if (emac->hsr_ptp_tx_irq) {
862 ret = request_threaded_irq(emac->hsr_ptp_tx_irq,
863 prueth_ptp_tx_irq_handle,
864 prueth_ptp_tx_irq_work,
865 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
866 emac->ndev->name, emac->ndev);
867 if (ret) {
868 netdev_err(emac->ndev, "unable to request PTP TX IRQ\n");
869 return ret;
870 }
871
872 }
873
861 /* HSR/PRP. Request irq when first port is initialized */ 874 /* HSR/PRP. Request irq when first port is initialized */
862 if (prueth->emac_configured) 875 if (prueth->emac_configured)
863 return 0; 876 return 0;
@@ -866,17 +879,24 @@ int prueth_lre_request_irqs(struct prueth_emac *emac)
866 IRQF_TRIGGER_HIGH, "eth_hp_int", prueth->hp); 879 IRQF_TRIGGER_HIGH, "eth_hp_int", prueth->hp);
867 if (ret) { 880 if (ret) {
868 netdev_err(emac->ndev, "unable to request RX HPQ IRQ\n"); 881 netdev_err(emac->ndev, "unable to request RX HPQ IRQ\n");
869 return ret; 882 goto free_ptp_irq;
870 } 883 }
871 884
872 ret = request_irq(prueth->rx_lpq_irq, prueth_lre_emac_rx_hardirq, 885 ret = request_irq(prueth->rx_lpq_irq, prueth_lre_emac_rx_hardirq,
873 IRQF_TRIGGER_HIGH, "eth_lp_int", prueth->lp); 886 IRQF_TRIGGER_HIGH, "eth_lp_int", prueth->lp);
874 if (ret) { 887 if (ret) {
875 netdev_err(emac->ndev, "unable to request RX LPQ IRQ\n"); 888 netdev_err(emac->ndev, "unable to request RX LPQ IRQ\n");
876 free_irq(prueth->rx_hpq_irq, prueth->hp); 889 goto free_rx_hpq_irq;
877 return ret;
878 } 890 }
879 891
892 return 0;
893
894free_rx_hpq_irq:
895 free_irq(prueth->rx_hpq_irq, prueth->hp);
896free_ptp_irq:
897 if (emac->hsr_ptp_tx_irq)
898 free_irq(emac->hsr_ptp_tx_irq, emac->ndev);
899
880 return ret; 900 return ret;
881} 901}
882 902
diff --git a/drivers/net/ethernet/ti/prueth_ptp.h b/drivers/net/ethernet/ti/prueth_ptp.h
new file mode 100644
index 000000000000..03c84ff5dad9
--- /dev/null
+++ b/drivers/net/ethernet/ti/prueth_ptp.h
@@ -0,0 +1,82 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
4 */
5#ifndef PRUETH_PTP_H
6#define PRUETH_PTP_H
7
8#define RX_SYNC_TIMESTAMP_OFFSET_P1 0x8 /* 8 bytes */
9#define RX_PDELAY_REQ_TIMESTAMP_OFFSET_P1 0x14 /* 12 bytes */
10#define RX_PDELAY_RESP_TIMESTAMP_OFFSET_P1 0x20 /* 12 bytes */
11#define RX_SYNC_TIMESTAMP_OFFSET_P2 0x2c /* 12 bytes */
12#define RX_PDELAY_REQ_TIMESTAMP_OFFSET_P2 0x38 /* 12 bytes */
13#define RX_PDELAY_RESP_TIMESTAMP_OFFSET_P2 0x44 /* 12 bytes */
14#define TIMESYNC_DOMAIN_NUMBER_LIST 0x50 /* 2 bytes */
15#define P1_SMA_LINE_DELAY_OFFSET 0x52 /* 4 bytes */
16#define P2_SMA_LINE_DELAY_OFFSET 0x56 /* 4 bytes */
17#define TIMESYNC_SECONDS_COUNT_OFFSET 0x5a /* 6 bytes */
18#define TIMESYNC_TC_RCF_OFFSET 0x60 /* 4 bytes */
19#define DUT_IS_MASTER_OFFSET 0x64 /* 1 byte */
20#define MASTER_PORT_NUM_OFFSET 0x65 /* 1 byte */
21#define SYNC_MASTER_MAC_OFFSET 0x66 /* 6 bytes */
22#define TX_TS_NOTIFICATION_OFFSET_SYNC_P1 0x6c /* 1 byte */
23#define TX_TS_NOTIFICATION_OFFSET_PDEL_REQ_P1 0x6d /* 1 byte */
24#define TX_TS_NOTIFICATION_OFFSET_PDEL_RES_P1 0x6e /* 1 byte */
25#define TX_TS_NOTIFICATION_OFFSET_SYNC_P2 0x6f /* 1 byte */
26#define TX_TS_NOTIFICATION_OFFSET_PDEL_REQ_P2 0x70 /* 1 byte */
27#define TX_TS_NOTIFICATION_OFFSET_PDEL_RES_P2 0x71 /* 1 byte */
28#define TX_SYNC_TIMESTAMP_OFFSET_P1 0x72 /* 12 bytes */
29#define TX_PDELAY_REQ_TIMESTAMP_OFFSET_P1 0x7e /* 12 bytes */
30#define TX_PDELAY_RESP_TIMESTAMP_OFFSET_P1 0x8a /* 12 bytes */
31#define TX_SYNC_TIMESTAMP_OFFSET_P2 0x96 /* 12 bytes */
32#define TX_PDELAY_REQ_TIMESTAMP_OFFSET_P2 0xa2 /* 12 bytes */
33#define TX_PDELAY_RESP_TIMESTAMP_OFFSET_P2 0xae /* 12 bytes */
34#define TIMESYNC_CTRL_VAR_OFFSET 0xba /* 1 byte */
35#define DISABLE_SWITCH_SYNC_RELAY_OFFSET 0xbb /* 1 byte */
36#define MII_RX_CORRECTION_OFFSET 0xbc /* 2 bytes */
37#define MII_TX_CORRECTION_OFFSET 0xbe /* 2 bytes */
38#define TIMESYNC_CMP1_CMP_OFFSET 0xc1 /* 8 bytes */
39#define TIMESYNC_SYNC0_CMP_OFFSET 0xc9 /* 8 bytes */
40#define TIMESYNC_CMP1_PERIOD_OFFSET 0xd1 /* 4 bytes */
41#define TIMESYNC_SYNC0_WIDTH_OFFSET 0xd5 /* 4 bytes */
42#define SINGLE_STEP_IEP_OFFSET_P1 0xd9 /* 8 bytes */
43#define SINGLE_STEP_SECONDS_OFFSET_P1 0xe1 /* 8 bytes */
44#define SINGLE_STEP_IEP_OFFSET_P2 0xe9 /* 8 bytes */
45#define SINGLE_STEP_SECONDS_OFFSET_P2 0xf1 /* 8 bytes */
46#define LINK_LOCAL_FRAME_HAS_HSR_TAG 0xf9 /* 1 bytes */
47#define PTP_PREV_TX_TIMESTAMP_P1 0x101 /* 8 bytes */
48#define PTP_PREV_TX_TIMESTAMP_P2 0x109 /* 8 bytes */
49#define PTP_CLK_IDENTITY_OFFSET 0x111 /* 8 bytes */
50#define PTP_SCRATCH_MEM 0x119 /* 16 byte */
51#define PTP_IPV4_UDP_E2E_ENABLE 0x129 /* 1 byte */
52
53enum {
54 PRUETH_PTP_SYNC,
55 PRUETH_PTP_DLY_REQ,
56 PRUETH_PTP_DLY_RESP,
57 PRUETH_PTP_TS_EVENTS,
58};
59
60#define PRUETH_PTP_TS_SIZE 12
61#define PRUETH_PTP_TS_NOTIFY_SIZE 1
62#define PRUETH_PTP_TS_NOTIFY_MASK 0xff
63
64/* Bit definitions for TIMESYNC_CTRL */
65#define TIMESYNC_CTRL_BG_ENABLE BIT(0)
66#define TIMESYNC_CTRL_FORCED_2STEP BIT(1)
67
68static inline u32 prueth_tx_ts_offs_get(u8 port, u8 event)
69{
70 return TX_SYNC_TIMESTAMP_OFFSET_P1 + port *
71 PRUETH_PTP_TS_EVENTS * PRUETH_PTP_TS_SIZE +
72 event * PRUETH_PTP_TS_SIZE;
73}
74
75static inline u32 prueth_tx_ts_notify_offs_get(u8 port, u8 event)
76{
77 return TX_TS_NOTIFICATION_OFFSET_SYNC_P1 +
78 PRUETH_PTP_TS_EVENTS * PRUETH_PTP_TS_NOTIFY_SIZE * port +
79 event * PRUETH_PTP_TS_NOTIFY_SIZE;
80}
81
82#endif /* PRUETH_PTP_H */
diff --git a/drivers/soc/ti/k3-socinfo.c b/drivers/soc/ti/k3-socinfo.c
index eeb2b78eaffc..5d2745b84f81 100644
--- a/drivers/soc/ti/k3-socinfo.c
+++ b/drivers/soc/ti/k3-socinfo.c
@@ -40,6 +40,7 @@ static const struct k3_soc_id {
40} k3_soc_ids[] = { 40} k3_soc_ids[] = {
41 { 0xBB5A, "AM65X" }, 41 { 0xBB5A, "AM65X" },
42 { 0xBB64, "J721E" }, 42 { 0xBB64, "J721E" },
43 { 0xBB6D, "J7200" },
43}; 44};
44 45
45int __init partno_to_names(unsigned int partno, 46int __init partno_to_names(unsigned int partno,
diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h
index dd00fa41f7e7..dc9420cd4ed3 100644
--- a/include/linux/ptp_classify.h
+++ b/include/linux/ptp_classify.h
@@ -34,6 +34,18 @@
34#define PTP_EV_PORT 319 34#define PTP_EV_PORT 319
35#define PTP_GEN_BIT 0x08 /* indicates general message, if set in message type */ 35#define PTP_GEN_BIT 0x08 /* indicates general message, if set in message type */
36 36
37/* PTP message types */
38#define PTP_SYNC_MSG_ID 0x0
39#define PTP_DLY_REQ_MSG_ID 0x1
40#define PTP_PDLY_REQ_MSG_ID 0x2
41#define PTP_PDLY_RSP_MSG_ID 0x3
42#define PTP_FOLLOW_UP_MSG_ID 0x8
43#define PTP_DLY_RESP_MSG_ID 0x9
44#define PTP_PDLY_RESP_FLW_UP_MSG_ID 0xa
45#define PTP_ANNOUNCE_MSG_ID 0xb
46#define PTP_SIGNAL_MSG_ID 0xc
47#define PTP_MGMT_MSG_ID 0xd
48
37#define OFF_PTP_SOURCE_UUID 22 /* PTPv1 only */ 49#define OFF_PTP_SOURCE_UUID 22 /* PTPv1 only */
38#define OFF_PTP_SEQUENCE_ID 30 50#define OFF_PTP_SEQUENCE_ID 30
39#define OFF_PTP_CONTROL 32 /* PTPv1 only */ 51#define OFF_PTP_CONTROL 32 /* PTPv1 only */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 542d881978ef..5857872fcd2b 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -505,6 +505,27 @@ int skb_zerocopy_iter_stream(struct sock *sk, struct sk_buff *skb,
505 struct msghdr *msg, int len, 505 struct msghdr *msg, int len,
506 struct ubuf_info *uarg); 506 struct ubuf_info *uarg);
507 507
508/* Bit fields of redundant info io_port */
509#define PTP_MSG_IN (0x3 << 6)
510#define PTP_EVT_OUT (0x2 << 6)
511#define DIRECTED_TX (0x1 << 6)
512#define PORT_B BIT(1)
513#define PORT_A BIT(0)
514
515struct skb_redundant_info {
516 __u8 io_port; /* tx/rx port of the skb */
517 __u8 pathid; /* pathid in tag */
518 __u16 ethertype; /* ethertype in tag */
519 __u16 lsdu_size; /* lsdu size in tag */
520 __u16 seqnr; /* seqnr in tag */
521};
522
523#define REDINFO_T(skb) (skb_redinfo(skb)->io_port & (0x3 << 6))
524#define REDINFO_PORTS(skb) (skb_redinfo(skb)->io_port & 0x3)
525#define REDINFO_PATHID(skb) (skb_redinfo(skb)->pathid)
526#define REDINFO_SEQNR(skb) (skb_redinfo(skb)->seqnr)
527#define REDINFO_LSDU_SIZE(skb) (skb_redinfo(skb)->lsdu_size)
528
508/* This data is invariant across clones and lives at 529/* This data is invariant across clones and lives at
509 * the end of the header data, ie. at skb->end. 530 * the end of the header data, ie. at skb->end.
510 */ 531 */
@@ -519,6 +540,8 @@ struct skb_shared_info {
519 struct sk_buff *frag_list; 540 struct sk_buff *frag_list;
520 struct skb_shared_hwtstamps hwtstamps; 541 struct skb_shared_hwtstamps hwtstamps;
521 unsigned int gso_type; 542 unsigned int gso_type;
543 struct skb_shared_hwtstamps red_hwtstamps;
544 struct skb_redundant_info redinfo;
522 u32 tskey; 545 u32 tskey;
523 546
524 /* 547 /*
@@ -1489,6 +1512,16 @@ static inline void skb_list_del_init(struct sk_buff *skb)
1489 __list_del_entry(&skb->list); 1512 __list_del_entry(&skb->list);
1490 skb_mark_not_on_list(skb); 1513 skb_mark_not_on_list(skb);
1491} 1514}
1515static inline struct skb_redundant_info *skb_redinfo(struct sk_buff *skb)
1516{
1517 return &skb_shinfo(skb)->redinfo;
1518}
1519
1520static inline struct skb_shared_hwtstamps *
1521skb_redinfo_hwtstamps(struct sk_buff *skb)
1522{
1523 return &skb_shinfo(skb)->red_hwtstamps;
1524}
1492 1525
1493/** 1526/**
1494 * skb_queue_empty - check if a queue is empty 1527 * skb_queue_empty - check if a queue is empty
diff --git a/include/net/sock.h b/include/net/sock.h
index 338ecd0490d4..3f3ac13d7647 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1652,12 +1652,14 @@ struct sockcm_cookie {
1652 u64 transmit_time; 1652 u64 transmit_time;
1653 u32 mark; 1653 u32 mark;
1654 u16 tsflags; 1654 u16 tsflags;
1655 struct skb_redundant_info redinfo;
1655}; 1656};
1656 1657
1657static inline void sockcm_init(struct sockcm_cookie *sockc, 1658static inline void sockcm_init(struct sockcm_cookie *sockc,
1658 const struct sock *sk) 1659 const struct sock *sk)
1659{ 1660{
1660 *sockc = (struct sockcm_cookie) { .tsflags = sk->sk_tsflags }; 1661 *sockc = (struct sockcm_cookie) { .tsflags = sk->sk_tsflags };
1662 memset(&sockc->redinfo, 0, sizeof(sockc->redinfo));
1661} 1663}
1662 1664
1663int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg, 1665int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg,
@@ -2375,6 +2377,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
2375 struct sk_buff *skb); 2377 struct sk_buff *skb);
2376void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, 2378void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
2377 struct sk_buff *skb); 2379 struct sk_buff *skb);
2380void __sock_recv_redinfo_timestamp(struct msghdr *msg, struct sock *sk,
2381 struct sk_buff *skb);
2378 2382
2379static inline void 2383static inline void
2380sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) 2384sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
@@ -2457,6 +2461,31 @@ static inline void skb_setup_tx_timestamp(struct sk_buff *skb, __u16 tsflags)
2457 &skb_shinfo(skb)->tskey); 2461 &skb_shinfo(skb)->tskey);
2458} 2462}
2459 2463
2464static inline void sock_recv_redundant_info(struct msghdr *msg, struct sock *sk,
2465 struct sk_buff *skb)
2466{
2467 struct skb_redundant_info *sred;
2468
2469 sred = skb_redinfo(skb);
2470 if (sred->lsdu_size)
2471 put_cmsg(msg, SOL_SOCKET, SCM_REDUNDANT, sizeof(*sred), sred);
2472
2473 __sock_recv_redinfo_timestamp(msg, sk, skb);
2474
2475}
2476
2477static inline void sock_tx_redundant_info(const struct sock *sk,
2478 struct skb_redundant_info *redinfo,
2479 struct sk_buff *skb)
2480{
2481 struct skb_redundant_info *sred;
2482
2483 if (redinfo->io_port) {
2484 sred = skb_redinfo(skb);
2485 memcpy(sred, redinfo, sizeof(*sred));
2486 }
2487}
2488
2460/** 2489/**
2461 * sk_eat_skb - Release a skb if it is no longer needed 2490 * sk_eat_skb - Release a skb if it is no longer needed
2462 * @sk: socket to eat this skb from 2491 * @sk: socket to eat this skb from
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index 77f7c1638eb1..990d9c9d7725 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -144,4 +144,10 @@
144 144
145#endif 145#endif
146 146
147#define SO_REDUNDANT 80
148#define SCM_REDUNDANT SO_REDUNDANT
149
150#define SO_RED_TIMESTAMPING 81
151#define SCM_RED_TIMESTAMPING SO_RED_TIMESTAMPING
152
147#endif /* __ASM_GENERIC_SOCKET_H */ 153#endif /* __ASM_GENERIC_SOCKET_H */
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 973a71f4bc89..c9a4a8ff84ad 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -4573,6 +4573,7 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
4573{ 4573{
4574 struct sk_buff *skb; 4574 struct sk_buff *skb;
4575 bool tsonly, opt_stats = false; 4575 bool tsonly, opt_stats = false;
4576 struct skb_redundant_info *sred, *orig_sred;
4576 4577
4577 if (!sk) 4578 if (!sk)
4578 return; 4579 return;
@@ -4607,6 +4608,13 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
4607 skb_shinfo(skb)->tskey = skb_shinfo(orig_skb)->tskey; 4608 skb_shinfo(skb)->tskey = skb_shinfo(orig_skb)->tskey;
4608 } 4609 }
4609 4610
4611 /* FIXME: should check sk flags */
4612 orig_sred = skb_redinfo(orig_skb);
4613 if (orig_sred->lsdu_size) {
4614 sred = skb_redinfo(skb);
4615 memcpy(sred, orig_sred, sizeof(*sred));
4616 }
4617
4610 if (hwtstamps) 4618 if (hwtstamps)
4611 *skb_hwtstamps(skb) = *hwtstamps; 4619 *skb_hwtstamps(skb) = *hwtstamps;
4612 else 4620 else
diff --git a/net/core/sock.c b/net/core/sock.c
index 69c02ac06c59..6eb478f11381 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2270,6 +2270,7 @@ EXPORT_SYMBOL(sock_alloc_send_skb);
2270int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg, 2270int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg,
2271 struct sockcm_cookie *sockc) 2271 struct sockcm_cookie *sockc)
2272{ 2272{
2273 struct skb_redundant_info *cred;
2273 u32 tsflags; 2274 u32 tsflags;
2274 2275
2275 switch (cmsg->cmsg_type) { 2276 switch (cmsg->cmsg_type) {
@@ -2302,6 +2303,15 @@ int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg,
2302 case SCM_RIGHTS: 2303 case SCM_RIGHTS:
2303 case SCM_CREDENTIALS: 2304 case SCM_CREDENTIALS:
2304 break; 2305 break;
2306 case SCM_REDUNDANT:
2307 if (cmsg->cmsg_len !=
2308 CMSG_LEN(sizeof(struct skb_redundant_info)))
2309 return -EINVAL;
2310
2311 cred = (struct skb_redundant_info *)CMSG_DATA(cmsg);
2312 memcpy(&sockc->redinfo, cred,
2313 sizeof(struct skb_redundant_info));
2314 break;
2305 default: 2315 default:
2306 return -EINVAL; 2316 return -EINVAL;
2307 } 2317 }
@@ -3070,6 +3080,7 @@ int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
3070 struct sock_exterr_skb *serr; 3080 struct sock_exterr_skb *serr;
3071 struct sk_buff *skb; 3081 struct sk_buff *skb;
3072 int copied, err; 3082 int copied, err;
3083 struct skb_redundant_info *sred;
3073 3084
3074 err = -EAGAIN; 3085 err = -EAGAIN;
3075 skb = sock_dequeue_err_skb(sk); 3086 skb = sock_dequeue_err_skb(sk);
@@ -3087,6 +3098,9 @@ int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
3087 3098
3088 sock_recv_timestamp(msg, sk, skb); 3099 sock_recv_timestamp(msg, sk, skb);
3089 3100
3101 sred = skb_redinfo(skb);
3102 put_cmsg(msg, SOL_SOCKET, SCM_REDUNDANT, sizeof(*sred), sred);
3103
3090 serr = SKB_EXT_ERR(skb); 3104 serr = SKB_EXT_ERR(skb);
3091 put_cmsg(msg, level, type, sizeof(serr->ee), &serr->ee); 3105 put_cmsg(msg, level, type, sizeof(serr->ee), &serr->ee);
3092 3106
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
index 7716dc97733f..361d68842bb8 100644
--- a/net/hsr/hsr_device.c
+++ b/net/hsr/hsr_device.c
@@ -12,12 +12,19 @@
12#include <linux/etherdevice.h> 12#include <linux/etherdevice.h>
13#include <linux/rtnetlink.h> 13#include <linux/rtnetlink.h>
14#include <linux/pkt_sched.h> 14#include <linux/pkt_sched.h>
15#include <linux/net_tstamp.h>
15#include "hsr_device.h" 16#include "hsr_device.h"
16#include "hsr_slave.h" 17#include "hsr_slave.h"
17#include "hsr_framereg.h" 18#include "hsr_framereg.h"
18#include "hsr_main.h" 19#include "hsr_main.h"
19#include "hsr_forward.h" 20#include "hsr_forward.h"
20 21
22static inline bool is_slave_port(struct hsr_port *p)
23{
24 return (p->type == HSR_PT_SLAVE_A) ||
25 (p->type == HSR_PT_SLAVE_B);
26}
27
21static bool is_admin_up(struct net_device *dev) 28static bool is_admin_up(struct net_device *dev)
22{ 29{
23 return dev && (dev->flags & IFF_UP); 30 return dev && (dev->flags & IFF_UP);
@@ -687,6 +694,31 @@ err:
687 return ret; 694 return ret;
688} 695}
689 696
697static int hsr_dev_ioctl(struct net_device *hsr_dev, struct ifreq *req, int cmd)
698{
699 struct hsr_priv *priv = netdev_priv(hsr_dev);
700 const struct net_device_ops *ops;
701 struct hsr_port *port;
702 int ret = -ENOTSUPP;
703
704 if (cmd != SIOCSHWTSTAMP && cmd != SIOCGHWTSTAMP)
705 return ret;
706
707 hsr_for_each_port(priv, port) {
708 if (is_slave_port(port)) {
709 ops = port->dev->netdev_ops;
710 if (ops && ops->ndo_do_ioctl) {
711 ret = ops->ndo_do_ioctl(port->dev, req, cmd);
712
713 if (cmd == SIOCGHWTSTAMP || cmd < 0)
714 return ret;
715 }
716 }
717 }
718
719 return ret;
720}
721
690static int hsr_ndo_vlan_rx_kill_vid(struct net_device *dev, 722static int hsr_ndo_vlan_rx_kill_vid(struct net_device *dev,
691 __be16 proto, u16 vid) 723 __be16 proto, u16 vid)
692{ 724{
@@ -724,6 +756,33 @@ static const struct net_device_ops hsr_device_ops = {
724 .ndo_set_rx_mode = hsr_ndo_set_rx_mode, 756 .ndo_set_rx_mode = hsr_ndo_set_rx_mode,
725 .ndo_vlan_rx_add_vid = hsr_ndo_vlan_rx_add_vid, 757 .ndo_vlan_rx_add_vid = hsr_ndo_vlan_rx_add_vid,
726 .ndo_vlan_rx_kill_vid = hsr_ndo_vlan_rx_kill_vid, 758 .ndo_vlan_rx_kill_vid = hsr_ndo_vlan_rx_kill_vid,
759 .ndo_do_ioctl = hsr_dev_ioctl,
760};
761
762static int hsr_get_ts_info(struct net_device *dev,
763 struct ethtool_ts_info *info)
764{
765 struct hsr_priv *priv = netdev_priv(dev);
766 struct hsr_port *port;
767 const struct ethtool_ops *ops;
768 int ret = -ENOTSUPP;
769
770 hsr_for_each_port(priv, port) {
771 if (is_slave_port(port)) {
772 ops = port->dev->ethtool_ops;
773 if (ops && ops->get_ts_info) {
774 ret = ops->get_ts_info(port->dev, info);
775 return ret;
776 }
777 }
778 }
779
780 return ret;
781}
782
783static const struct ethtool_ops hsr_ethtool_ops = {
784 .get_link = ethtool_op_get_link,
785 .get_ts_info = hsr_get_ts_info,
727}; 786};
728 787
729static struct device_type hsr_type = { 788static struct device_type hsr_type = {
@@ -738,6 +797,7 @@ void hsr_dev_setup(struct net_device *dev)
738 dev->min_mtu = 0; 797 dev->min_mtu = 0;
739 dev->header_ops = &hsr_header_ops; 798 dev->header_ops = &hsr_header_ops;
740 dev->netdev_ops = &hsr_device_ops; 799 dev->netdev_ops = &hsr_device_ops;
800 dev->ethtool_ops = &hsr_ethtool_ops;
741 SET_NETDEV_DEVTYPE(dev, &hsr_type); 801 SET_NETDEV_DEVTYPE(dev, &hsr_type);
742 dev->priv_flags |= IFF_NO_QUEUE; 802 dev->priv_flags |= IFF_NO_QUEUE;
743 803
diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
index afe7bee853cc..d556f4a3d7a0 100644
--- a/net/hsr/hsr_forward.c
+++ b/net/hsr/hsr_forward.c
@@ -29,8 +29,19 @@ struct hsr_frame_info {
29 bool is_local_dest; 29 bool is_local_dest;
30 bool is_local_exclusive; 30 bool is_local_exclusive;
31 bool is_from_san; 31 bool is_from_san;
32 struct skb_redundant_info *sred;
32}; 33};
33 34
35static inline int is_hsr_l2ptp(struct sk_buff *skb)
36{
37 struct hsr_ethhdr *hsr_ethhdr;
38
39 hsr_ethhdr = (struct hsr_ethhdr *)skb_mac_header(skb);
40
41 return (hsr_ethhdr->ethhdr.h_proto == htons(ETH_P_HSR) &&
42 hsr_ethhdr->hsr_tag.encap_proto == htons(ETH_P_1588));
43}
44
34/* The uses I can see for these HSR supervision frames are: 45/* The uses I can see for these HSR supervision frames are:
35 * 1) Use the frames that are sent after node initialization ("HSR_TLV.Type = 46 * 1) Use the frames that are sent after node initialization ("HSR_TLV.Type =
36 * 22") to reset any sequence_nr counters belonging to that node. Useful if 47 * 22") to reset any sequence_nr counters belonging to that node. Useful if
@@ -274,7 +285,11 @@ static void hsr_fill_tag(struct sk_buff *skb, struct hsr_frame_info *frame,
274 else 285 else
275 hsr_ethhdr = (struct hsr_ethhdr *)pc; 286 hsr_ethhdr = (struct hsr_ethhdr *)pc;
276 287
277 hsr_set_path_id(hsr_ethhdr, port); 288 if (REDINFO_T(skb) == DIRECTED_TX)
289 set_hsr_tag_path(&hsr_ethhdr->hsr_tag, REDINFO_PATHID(skb));
290 else
291 hsr_set_path_id(hsr_ethhdr, port);
292
278 set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, lsdu_size); 293 set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, lsdu_size);
279 hsr_ethhdr->hsr_tag.sequence_nr = htons(frame->sequence_nr); 294 hsr_ethhdr->hsr_tag.sequence_nr = htons(frame->sequence_nr);
280 hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto; 295 hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto;
@@ -289,6 +304,9 @@ static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o,
289 int movelen; 304 int movelen;
290 unsigned char *dst, *src; 305 unsigned char *dst, *src;
291 struct sk_buff *skb; 306 struct sk_buff *skb;
307 struct skb_redundant_info *sred;
308 struct hsr_ethhdr *hsr_ethhdr;
309 u16 s;
292 310
293 if (port->hsr->prot_version > HSR_V1) { 311 if (port->hsr->prot_version > HSR_V1) {
294 skb = skb_copy_expand(skb_o, skb_headroom(skb_o), 312 skb = skb_copy_expand(skb_o, skb_headroom(skb_o),
@@ -321,6 +339,25 @@ static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o,
321 339
322 hsr_fill_tag(skb, frame, port, port->hsr->prot_version); 340 hsr_fill_tag(skb, frame, port, port->hsr->prot_version);
323 341
342 if (REDINFO_T(skb) == DIRECTED_TX)
343 return skb;
344
345 skb_shinfo(skb)->tx_flags = skb_shinfo(skb_o)->tx_flags;
346 skb->sk = skb_o->sk;
347
348 /* TODO: should check socket option instead? */
349 if (is_hsr_l2ptp(skb)) {
350 sred = skb_redinfo(skb);
351 /* assumes no vlan */
352 hsr_ethhdr = (struct hsr_ethhdr *)skb_mac_header(skb);
353 sred->io_port = (PTP_EVT_OUT | BIT(port->type - 1));
354 sred->ethertype = ntohs(hsr_ethhdr->ethhdr.h_proto);
355 s = ntohs(hsr_ethhdr->hsr_tag.path_and_LSDU_size);
356 sred->lsdu_size = s & 0xfff;
357 sred->pathid = (s >> 12) & 0xf;
358 sred->seqnr = hsr_get_skb_sequence_nr(skb);
359 }
360
324 return skb; 361 return skb;
325} 362}
326 363
@@ -418,6 +455,57 @@ static int hsr_xmit(struct sk_buff *skb, struct hsr_port *port,
418 return dev_queue_xmit(skb); 455 return dev_queue_xmit(skb);
419} 456}
420 457
458static void stripped_skb_get_shared_info(struct sk_buff *skb_stripped,
459 struct hsr_frame_info *frame)
460{
461 struct hsr_port *port_rcv = frame->port_rcv;
462 struct skb_redundant_info *sred;
463 struct sk_buff *skb_hsr, *skb;
464 struct hsr_ethhdr *hsr_ethhdr;
465 u16 s;
466
467 if (port_rcv->hsr->prot_version > HSR_V1)
468 return;
469
470 if (!frame->skb_hsr)
471 return;
472
473 skb_hsr = frame->skb_hsr;
474 skb = skb_stripped;
475
476 if (is_hsr_l2ptp(skb_hsr)) {
477 skb_hwtstamps(skb)->hwtstamp = skb_hwtstamps(skb_hsr)->hwtstamp;
478 skb_redinfo_hwtstamps(skb)->hwtstamp =
479 skb_redinfo_hwtstamps(skb_hsr)->hwtstamp;
480
481 sred = skb_redinfo(skb);
482 /* assumes no vlan */
483 hsr_ethhdr = (struct hsr_ethhdr *)skb_mac_header(skb_hsr);
484 sred->io_port = (PTP_MSG_IN | BIT(port_rcv->type - 1));
485 sred->ethertype = ntohs(hsr_ethhdr->ethhdr.h_proto);
486 s = ntohs(hsr_ethhdr->hsr_tag.path_and_LSDU_size);
487 sred->lsdu_size = s & 0xfff;
488 sred->pathid = (s >> 12) & 0xf;
489 sred->seqnr = frame->sequence_nr;
490 }
491}
492
493static unsigned int
494hsr_directed_tx_ports(struct hsr_frame_info *frame)
495{
496 struct sk_buff *skb;
497
498 if (frame->skb_std)
499 skb = frame->skb_std;
500 else
501 return 0;
502
503 if (REDINFO_T(skb) == DIRECTED_TX)
504 return REDINFO_PORTS(skb);
505
506 return 0;
507}
508
421/* Forward the frame through all devices except: 509/* Forward the frame through all devices except:
422 * - Back through the receiving device 510 * - Back through the receiving device
423 * - If it's a HSR frame: through a device where it has passed before 511 * - If it's a HSR frame: through a device where it has passed before
@@ -434,6 +522,7 @@ static void hsr_forward_do(struct hsr_frame_info *frame)
434{ 522{
435 struct hsr_port *port; 523 struct hsr_port *port;
436 struct sk_buff *skb = NULL; 524 struct sk_buff *skb = NULL;
525 unsigned int dir_ports = 0;
437 526
438 hsr_for_each_port(frame->port_rcv->hsr, port) { 527 hsr_for_each_port(frame->port_rcv->hsr, port) {
439 /* Don't send frame back the way it came */ 528 /* Don't send frame back the way it came */
@@ -486,11 +575,18 @@ static void hsr_forward_do(struct hsr_frame_info *frame)
486 port->type == HSR_PT_SLAVE_A))) 575 port->type == HSR_PT_SLAVE_A)))
487 continue; 576 continue;
488 577
489 if (port->type != HSR_PT_MASTER) 578 dir_ports = hsr_directed_tx_ports(frame);
579 if (dir_ports && !(dir_ports & BIT(port->type - 1)))
580 continue;
581
582 if (port->type != HSR_PT_MASTER) {
490 skb = frame_get_tagged_skb(frame, port); 583 skb = frame_get_tagged_skb(frame, port);
491 else 584 } else {
492 skb = frame_get_stripped_skb(frame, port); 585 skb = frame_get_stripped_skb(frame, port);
493 586
587 stripped_skb_get_shared_info(skb, frame);
588 }
589
494 if (!skb) { 590 if (!skb) {
495 frame->port_rcv->dev->stats.rx_dropped++; 591 frame->port_rcv->dev->stats.rx_dropped++;
496 if (frame->port_rcv->type == HSR_PT_SLAVE_A || 592 if (frame->port_rcv->type == HSR_PT_SLAVE_A ||
@@ -573,10 +669,13 @@ static void fill_frame_info_non_prefixed(struct hsr_frame_info *frame,
573 if (port->type != HSR_PT_MASTER) { 669 if (port->type != HSR_PT_MASTER) {
574 frame->is_from_san = true; 670 frame->is_from_san = true;
575 } else { 671 } else {
576 if ((hsr->prot_version == HSR_V1 && 672 if ((REDINFO_T(skb) == DIRECTED_TX) &&
577 hsr->hsr_mode != IEC62439_3_HSR_MODE_T) || 673 (REDINFO_LSDU_SIZE(skb))) {
578 hsr->prot_version == PRP_V1 || 674 frame->sequence_nr = REDINFO_SEQNR(skb);
579 hsr->prot_version == HSR_V0) { 675 } else if ((hsr->prot_version == HSR_V1 &&
676 hsr->hsr_mode != IEC62439_3_HSR_MODE_T) ||
677 hsr->prot_version == PRP_V1 ||
678 hsr->prot_version == HSR_V0) {
580 /* Sequence nr for the master node */ 679 /* Sequence nr for the master node */
581 spin_lock_irqsave(&hsr->seqnr_lock, 680 spin_lock_irqsave(&hsr->seqnr_lock,
582 irqflags); 681 irqflags);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 1d63ab3a878a..c74689da8ee7 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2950,6 +2950,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
2950 2950
2951 skb_setup_tx_timestamp(skb, sockc.tsflags); 2951 skb_setup_tx_timestamp(skb, sockc.tsflags);
2952 2952
2953 sock_tx_redundant_info(sk, &sockc.redinfo, skb);
2954
2953 if (!vnet_hdr.gso_type && (len > dev->mtu + reserve + extra_len) && 2955 if (!vnet_hdr.gso_type && (len > dev->mtu + reserve + extra_len) &&
2954 !packet_extra_vlan_len_allowed(dev, skb)) { 2956 !packet_extra_vlan_len_allowed(dev, skb)) {
2955 err = -EMSGSIZE; 2957 err = -EMSGSIZE;
@@ -3389,6 +3391,8 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
3389 3391
3390 sock_recv_ts_and_drops(msg, sk, skb); 3392 sock_recv_ts_and_drops(msg, sk, skb);
3391 3393
3394 sock_recv_redundant_info(msg, sk, skb);
3395
3392 if (msg->msg_name) { 3396 if (msg->msg_name) {
3393 int copy_len; 3397 int copy_len;
3394 3398
diff --git a/net/socket.c b/net/socket.c
index fb2b39647d01..a163b279d3d5 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -830,6 +830,25 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
830} 830}
831EXPORT_SYMBOL_GPL(__sock_recv_timestamp); 831EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
832 832
833void __sock_recv_redinfo_timestamp(struct msghdr *msg, struct sock *sk,
834 struct sk_buff *skb)
835{
836 struct scm_timestamping tss;
837 int empty = 1;
838 struct skb_shared_hwtstamps *red_shhwtstamps =
839 skb_redinfo_hwtstamps(skb);
840
841 if (red_shhwtstamps &&
842 (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
843 ktime_to_timespec_cond(red_shhwtstamps->hwtstamp, tss.ts + 2))
844 empty = 0;
845
846 if (!empty)
847 put_cmsg(msg, SOL_SOCKET,
848 SCM_RED_TIMESTAMPING, sizeof(tss), &tss);
849}
850EXPORT_SYMBOL_GPL(__sock_recv_redinfo_timestamp);
851
833void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, 852void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
834 struct sk_buff *skb) 853 struct sk_buff *skb)
835{ 854{