blob: 953b479a20bc5bb7109af089b43633195da24599 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From eb5556db4c4fb8dff9a7b716c66a1ea3d3e696ce Mon Sep 17 00:00:00 2001
2From: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
3Date: Fri, 29 Nov 2019 11:02:43 +0800
4Subject: [PATCH] net: mscc: ocelot: tsn configuration support
5
6Support TSN configuration for ocelot switch. The TSN configuration
7fucntions are based on tsn netlink interface, it can support Qbv,
8Qbu, Qci, 802.1CB, and Qav configuration now.
9
10Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
11---
12 drivers/net/ethernet/mscc/Makefile | 1 +
13 drivers/net/ethernet/mscc/ocelot.c | 11 +-
14 drivers/net/ethernet/mscc/ocelot.h | 2 +
15 drivers/net/ethernet/mscc/ocelot_ana.h | 25 +-
16 drivers/net/ethernet/mscc/ocelot_dev_gmii.h | 153 +++
17 drivers/net/ethernet/mscc/ocelot_tsn.c | 1572 +++++++++++++++++++++++++++
18 drivers/net/ethernet/mscc/ocelot_tsn.h | 51 +
19 include/soc/mscc/ocelot.h | 52 +-
20 8 files changed, 1857 insertions(+), 10 deletions(-)
21 create mode 100644 drivers/net/ethernet/mscc/ocelot_dev_gmii.h
22 create mode 100644 drivers/net/ethernet/mscc/ocelot_tsn.c
23 create mode 100644 drivers/net/ethernet/mscc/ocelot_tsn.h
24
25--- a/drivers/net/ethernet/mscc/Makefile
26+++ b/drivers/net/ethernet/mscc/Makefile
27@@ -2,4 +2,5 @@
28 obj-$(CONFIG_MSCC_OCELOT_SWITCH) += mscc_ocelot_common.o
29 mscc_ocelot_common-y := ocelot.o ocelot_io.o
30 mscc_ocelot_common-y += ocelot_regs.o ocelot_tc.o ocelot_police.o ocelot_ace.o ocelot_flower.o
31+mscc_ocelot_common-y += ocelot_tsn.o
32 obj-$(CONFIG_MSCC_OCELOT_SWITCH_OCELOT) += ocelot_board.o
33--- a/drivers/net/ethernet/mscc/ocelot.c
34+++ b/drivers/net/ethernet/mscc/ocelot.c
35@@ -780,7 +780,7 @@ static void ocelot_set_rx_mode(struct ne
36 * forwarded to the CPU port.
37 */
38 val = GENMASK(ocelot->num_phys_ports - 1, 0);
39- for (i = ocelot->num_phys_ports + 1; i < PGID_CPU; i++)
40+ for (i = ocelot->num_phys_ports + 1; i < PGID_MCRED; i++)
41 ocelot_write_rix(ocelot, val, ANA_PGID_PGID, i);
42
43 __dev_mc_sync(dev, ocelot_mc_sync, ocelot_mc_unsync);
44@@ -2407,10 +2407,11 @@ int ocelot_init(struct ocelot *ocelot)
45 SYS_FRM_AGING_MAX_AGE(307692), SYS_FRM_AGING);
46
47 /* Setup flooding PGIDs */
48- ocelot_write_rix(ocelot, ANA_FLOODING_FLD_MULTICAST(PGID_MC) |
49- ANA_FLOODING_FLD_BROADCAST(PGID_MC) |
50- ANA_FLOODING_FLD_UNICAST(PGID_UC),
51- ANA_FLOODING, 0);
52+ for (i = 0; i < 8; i++)
53+ ocelot_write_rix(ocelot, ANA_FLOODING_FLD_MULTICAST(PGID_MC) |
54+ ANA_FLOODING_FLD_BROADCAST(PGID_MC) |
55+ ANA_FLOODING_FLD_UNICAST(PGID_UC),
56+ ANA_FLOODING, i);
57 ocelot_write(ocelot, ANA_FLOODING_IPMC_FLD_MC6_DATA(PGID_MCIPV6) |
58 ANA_FLOODING_IPMC_FLD_MC6_CTRL(PGID_MC) |
59 ANA_FLOODING_IPMC_FLD_MC4_DATA(PGID_MCIPV4) |
60--- a/drivers/net/ethernet/mscc/ocelot.h
61+++ b/drivers/net/ethernet/mscc/ocelot.h
62@@ -27,11 +27,13 @@
63 #include "ocelot_qs.h"
64 #include "ocelot_tc.h"
65 #include "ocelot_ptp.h"
66+#include "ocelot_dev_gmii.h"
67
68 #define PGID_AGGR 64
69 #define PGID_SRC 80
70
71 /* Reserved PGIDs */
72+#define PGID_MCRED (PGID_AGGR - 25)
73 #define PGID_CPU (PGID_AGGR - 5)
74 #define PGID_UC (PGID_AGGR - 4)
75 #define PGID_MC (PGID_AGGR - 3)
76--- a/drivers/net/ethernet/mscc/ocelot_ana.h
77+++ b/drivers/net/ethernet/mscc/ocelot_ana.h
78@@ -227,6 +227,11 @@
79 #define ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(x) ((x) & GENMASK(1, 0))
80 #define ANA_TABLES_SFIDACCESS_SFID_TBL_CMD_M GENMASK(1, 0)
81
82+#define SFIDACCESS_CMD_IDLE 0
83+#define SFIDACCESS_CMD_READ 1
84+#define SFIDACCESS_CMD_WRITE 2
85+#define SFIDACCESS_CMD_INIT 3
86+
87 #define ANA_TABLES_SFIDTIDX_SGID_VALID BIT(26)
88 #define ANA_TABLES_SFIDTIDX_SGID(x) (((x) << 18) & GENMASK(25, 18))
89 #define ANA_TABLES_SFIDTIDX_SGID_M GENMASK(25, 18)
90@@ -252,15 +257,23 @@
91 #define ANA_SG_CONFIG_REG_3_LIST_LENGTH_M GENMASK(18, 16)
92 #define ANA_SG_CONFIG_REG_3_LIST_LENGTH_X(x) (((x) & GENMASK(18, 16)) >> 16)
93 #define ANA_SG_CONFIG_REG_3_GATE_ENABLE BIT(20)
94-#define ANA_SG_CONFIG_REG_3_INIT_IPS(x) (((x) << 24) & GENMASK(27, 24))
95-#define ANA_SG_CONFIG_REG_3_INIT_IPS_M GENMASK(27, 24)
96-#define ANA_SG_CONFIG_REG_3_INIT_IPS_X(x) (((x) & GENMASK(27, 24)) >> 24)
97-#define ANA_SG_CONFIG_REG_3_INIT_GATE_STATE BIT(28)
98+#define ANA_SG_CONFIG_REG_3_INIT_IPS(x) (((x) << 21) & GENMASK(24, 21))
99+#define ANA_SG_CONFIG_REG_3_INIT_IPS_M GENMASK(24, 21)
100+#define ANA_SG_CONFIG_REG_3_INIT_IPS_X(x) (((x) & GENMASK(24, 21)) >> 21)
101+#define ANA_SG_CONFIG_REG_3_IPV_VALID BIT(24)
102+#define ANA_SG_CONFIG_REG_3_IPV_INVALID(x) (((x) << 24) & GENMASK(24, 24))
103+#define ANA_SG_CONFIG_REG_3_INIT_IPV(x) (((x) << 21) & GENMASK(23, 21))
104+#define ANA_SG_CONFIG_REG_3_INIT_IPV_M GENMASK(23, 21)
105+#define ANA_SG_CONFIG_REG_3_INIT_IPV_X(x) (((x) & GENMASK(23, 21)) >> 21)
106+#define ANA_SG_CONFIG_REG_3_INIT_GATE_STATE BIT(25)
107
108 #define ANA_SG_GCL_GS_CONFIG_RSZ 0x4
109
110 #define ANA_SG_GCL_GS_CONFIG_IPS(x) ((x) & GENMASK(3, 0))
111 #define ANA_SG_GCL_GS_CONFIG_IPS_M GENMASK(3, 0)
112+#define ANA_SG_GCL_GS_CONFIG_IPV_VALID BIT(3)
113+#define ANA_SG_GCL_GS_CONFIG_IPV(x) ((x) & GENMASK(2, 0))
114+#define ANA_SG_GCL_GS_CONFIG_IPV_M GENMASK(2, 0)
115 #define ANA_SG_GCL_GS_CONFIG_GATE_STATE BIT(4)
116
117 #define ANA_SG_GCL_TI_CONFIG_RSZ 0x4
118@@ -271,6 +284,10 @@
119 #define ANA_SG_STATUS_REG_3_IPS(x) (((x) << 20) & GENMASK(23, 20))
120 #define ANA_SG_STATUS_REG_3_IPS_M GENMASK(23, 20)
121 #define ANA_SG_STATUS_REG_3_IPS_X(x) (((x) & GENMASK(23, 20)) >> 20)
122+#define ANA_SG_STATUS_REG_3_IPV_VALID BIT(23)
123+#define ANA_SG_STATUS_REG_3_IPV(x) (((x) << 20) & GENMASK(22, 20))
124+#define ANA_SG_STATUS_REG_3_IPV_M GENMASK(22, 20)
125+#define ANA_SG_STATUS_REG_3_IPV_X(x) (((x) & GENMASK(22, 20)) >> 20)
126 #define ANA_SG_STATUS_REG_3_CONFIG_PENDING BIT(24)
127
128 #define ANA_PORT_VLAN_CFG_GSZ 0x100
129--- /dev/null
130+++ b/drivers/net/ethernet/mscc/ocelot_dev_gmii.h
131@@ -0,0 +1,153 @@
132+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
133+/* Microsemi Ocelot Switch driver
134+ *
135+ * Copyright (c) 2017 Microsemi Corporation
136+ */
137+
138+#ifndef _MSCC_OCELOT_DEV_GMII_H_
139+#define _MSCC_OCELOT_DEV_GMII_H_
140+
141+#define DEV_GMII_PORT_MODE_CLOCK_CFG 0x0
142+
143+#define DEV_GMII_PORT_MODE_CLOCK_CFG_MAC_TX_RST BIT(5)
144+#define DEV_GMII_PORT_MODE_CLOCK_CFG_MAC_RX_RST BIT(4)
145+#define DEV_GMII_PORT_MODE_CLOCK_CFG_PORT_RST BIT(3)
146+#define DEV_GMII_PORT_MODE_CLOCK_CFG_PHY_RST BIT(2)
147+#define DEV_GMII_PORT_MODE_CLOCK_CFG_LINK_SPEED(x) ((x) & GENMASK(1, 0))
148+#define DEV_GMII_PORT_MODE_CLOCK_CFG_LINK_SPEED_M GENMASK(1, 0)
149+
150+#define DEV_GMII_PORT_MODE_PORT_MISC 0x4
151+
152+#define DEV_GMII_PORT_MODE_PORT_MISC_MPLS_RX_ENA BIT(5)
153+#define DEV_GMII_PORT_MODE_PORT_MISC_FWD_ERROR_ENA BIT(4)
154+#define DEV_GMII_PORT_MODE_PORT_MISC_FWD_PAUSE_ENA BIT(3)
155+#define DEV_GMII_PORT_MODE_PORT_MISC_FWD_CTRL_ENA BIT(2)
156+#define DEV_GMII_PORT_MODE_PORT_MISC_GMII_LOOP_ENA BIT(1)
157+#define DEV_GMII_PORT_MODE_PORT_MISC_DEV_LOOP_ENA BIT(0)
158+
159+#define DEV_GMII_PORT_MODE_EVENTS 0x8
160+
161+#define DEV_GMII_PORT_MODE_EEE_CFG 0xc
162+
163+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_ENA BIT(22)
164+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_AGE(x) (((x) << 15) & GENMASK(21, 15))
165+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_AGE_M GENMASK(21, 15)
166+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_AGE_X(x) (((x) & GENMASK(21, 15)) >> 15)
167+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_WAKEUP(x) (((x) << 8) & GENMASK(14, 8))
168+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_WAKEUP_M GENMASK(14, 8)
169+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_WAKEUP_X(x) (((x) & GENMASK(14, 8)) >> 8)
170+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_HOLDOFF(x) (((x) << 1) & GENMASK(7, 1))
171+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_HOLDOFF_M GENMASK(7, 1)
172+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_HOLDOFF_X(x) (((x) & GENMASK(7, 1)) >> 1)
173+#define DEV_GMII_PORT_MODE_EEE_CFG_PORT_LPI BIT(0)
174+
175+#define DEV_GMII_PORT_MODE_RX_PATH_DELAY 0x10
176+
177+#define DEV_GMII_PORT_MODE_TX_PATH_DELAY 0x14
178+
179+#define DEV_GMII_PORT_MODE_PTP_PREDICT_CFG 0x18
180+
181+#define DEV_GMII_MAC_CFG_STATUS_MAC_ENA_CFG 0x1c
182+
183+#define DEV_GMII_MAC_CFG_STATUS_MAC_ENA_CFG_RX_ENA BIT(4)
184+#define DEV_GMII_MAC_CFG_STATUS_MAC_ENA_CFG_TX_ENA BIT(0)
185+
186+#define DEV_GMII_MAC_CFG_STATUS_MAC_MODE_CFG 0x20
187+
188+#define DEV_GMII_MAC_CFG_STATUS_MAC_MODE_CFG_FC_WORD_SYNC_ENA BIT(8)
189+#define DEV_GMII_MAC_CFG_STATUS_MAC_MODE_CFG_GIGA_MODE_ENA BIT(4)
190+#define DEV_GMII_MAC_CFG_STATUS_MAC_MODE_CFG_FDX_ENA BIT(0)
191+
192+#define DEV_GMII_MAC_CFG_STATUS_MAC_MAXLEN_CFG 0x24
193+
194+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG 0x28
195+
196+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG_TAG_ID(x) (((x) << 16) & GENMASK(31, 16))
197+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG_TAG_ID_M GENMASK(31, 16)
198+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG_TAG_ID_X(x) (((x) & GENMASK(31, 16)) >> 16)
199+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG_PB_ENA BIT(1)
200+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG_VLAN_AWR_ENA BIT(0)
201+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA BIT(2)
202+
203+#define DEV_GMII_MAC_CFG_STATUS_MAC_ADV_CHK_CFG 0x2c
204+
205+#define DEV_GMII_MAC_CFG_STATUS_MAC_ADV_CHK_CFG_LEN_DROP_ENA BIT(0)
206+
207+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG 0x30
208+
209+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_RESTORE_OLD_IPG_CHECK BIT(17)
210+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_REDUCED_TX_IFG BIT(16)
211+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_TX_IFG(x) (((x) << 8) & GENMASK(12, 8))
212+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_TX_IFG_M GENMASK(12, 8)
213+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_TX_IFG_X(x) (((x) & GENMASK(12, 8)) >> 8)
214+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_RX_IFG2(x) (((x) << 4) & GENMASK(7, 4))
215+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_RX_IFG2_M GENMASK(7, 4)
216+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_RX_IFG2_X(x) (((x) & GENMASK(7, 4)) >> 4)
217+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_RX_IFG1(x) ((x) & GENMASK(3, 0))
218+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_RX_IFG1_M GENMASK(3, 0)
219+
220+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG 0x34
221+
222+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_BYPASS_COL_SYNC BIT(26)
223+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_OB_ENA BIT(25)
224+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_WEXC_DIS BIT(24)
225+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_SEED(x) (((x) << 16) & GENMASK(23, 16))
226+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_SEED_M GENMASK(23, 16)
227+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_SEED_X(x) (((x) & GENMASK(23, 16)) >> 16)
228+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_SEED_LOAD BIT(12)
229+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_RETRY_AFTER_EXC_COL_ENA BIT(8)
230+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_LATE_COL_POS(x) ((x) & GENMASK(6, 0))
231+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_LATE_COL_POS_M GENMASK(6, 0)
232+
233+#define DEV_GMII_MAC_CFG_STATUS_MAC_DBG_CFG 0x38
234+
235+#define DEV_GMII_MAC_CFG_STATUS_MAC_DBG_CFG_TBI_MODE BIT(4)
236+#define DEV_GMII_MAC_CFG_STATUS_MAC_DBG_CFG_IFG_CRS_EXT_CHK_ENA BIT(0)
237+
238+#define DEV_GMII_MAC_CFG_STATUS_MAC_FC_MAC_LOW_CFG 0x3c
239+
240+#define DEV_GMII_MAC_CFG_STATUS_MAC_FC_MAC_HIGH_CFG 0x40
241+
242+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY 0x44
243+
244+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_RX_IPG_SHRINK_STICKY BIT(9)
245+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_RX_PREAM_SHRINK_STICKY BIT(8)
246+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_RX_CARRIER_EXT_STICKY BIT(7)
247+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_RX_CARRIER_EXT_ERR_STICKY BIT(6)
248+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_RX_JUNK_STICKY BIT(5)
249+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_TX_RETRANSMIT_STICKY BIT(4)
250+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_TX_JAM_STICKY BIT(3)
251+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_TX_FIFO_OFLW_STICKY BIT(2)
252+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_TX_FRM_LEN_OVR_STICKY BIT(1)
253+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_TX_ABORT_STICKY BIT(0)
254+
255+#define DEV_GMII_MM_CONFIG_ENABLE_CONFIG 0x48
256+
257+#define DEV_GMII_MM_CONFIG_ENABLE_CONFIG_MM_RX_ENA BIT(0)
258+#define DEV_GMII_MM_CONFIG_ENABLE_CONFIG_MM_TX_ENA BIT(4)
259+#define DEV_GMII_MM_CONFIG_ENABLE_CONFIG_KEEP_S_AFTER_D BIT(8)
260+
261+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG 0x4c
262+
263+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_PRM_VERIFY_DIS BIT(0)
264+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_PRM_VERIFY_TIME(x) (((x) << 4) & GENMASK(11, 4))
265+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_PRM_VERIFY_TIME_M GENMASK(11, 4)
266+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_PRM_VERIFY_TIME_X(x) (((x) & GENMASK(11, 4)) >> 4)
267+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_VERIF_TIMER_UNITS(x) (((x) << 12) & GENMASK(13, 12))
268+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_VERIF_TIMER_UNITS_M GENMASK(13, 12)
269+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_VERIF_TIMER_UNITS_X(x) (((x) & GENMASK(13, 12)) >> 12)
270+
271+#define DEV_GMII_MM_STATISTICS_MM_STATUS 0x50
272+
273+#define DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_ACTIVE_STATUS BIT(0)
274+#define DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_ACTIVE_STICKY BIT(4)
275+#define DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_VERIFY_STATE(x) (((x) << 8) & GENMASK(10, 8))
276+#define DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_VERIFY_STATE_M GENMASK(10, 8)
277+#define DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_VERIFY_STATE_X(x) (((x) & GENMASK(10, 8)) >> 8)
278+#define DEV_GMII_MM_STATISTICS_MM_STATUS_UNEXP_RX_PFRM_STICKY BIT(12)
279+#define DEV_GMII_MM_STATISTICS_MM_STATUS_UNEXP_TX_PFRM_STICKY BIT(16)
280+#define DEV_GMII_MM_STATISTICS_MM_STATUS_MM_RX_FRAME_STATUS BIT(20)
281+#define DEV_GMII_MM_STATISTICS_MM_STATUS_MM_TX_FRAME_STATUS BIT(24)
282+#define DEV_GMII_MM_STATISTICS_MM_STATUS_MM_TX_PRMPT_STATUS BIT(28)
283+
284+#endif
285--- /dev/null
286+++ b/drivers/net/ethernet/mscc/ocelot_tsn.c
287@@ -0,0 +1,1572 @@
288+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
289+/* Felix Switch TSN driver
290+ *
291+ * Copyright (c) 2018 Microsemi Corporation
292+ * Copyright 2018-2019 NXP
293+ */
294+
295+#include <linux/io.h>
296+#include <linux/kernel.h>
297+#include <linux/pci.h>
298+#include <linux/iopoll.h>
299+#include "ocelot.h"
300+#include <soc/mscc/ocelot_sys.h>
301+#include "ocelot_ana.h"
302+#include "ocelot_qsys.h"
303+#include "ocelot_rew.h"
304+#include "ocelot_dev_gmii.h"
305+#include "ocelot_tsn.h"
306+
307+#define MSCC_NUM_OUT_PORT 4 /* Number of physical output ports */
308+#define SE_IX_PORT 64
309+
310+/* MSCC TSN parameters limited */
311+#define NUM_MSCC_QOS_PRIO 8
312+#define MSCC_PSFP_SFID_NUM 176
313+#define MSCC_FRER_SSID_NUM 128
314+
315+/* Using the max number of MSCC_PSFP_SFID_NUM and MSCC_FRER_SSID_NUM */
316+#define MSCC_STREAM_HANDLE_NUM MSCC_PSFP_SFID_NUM
317+
318+int streamhandle_map[MSCC_STREAM_HANDLE_NUM] = {0};
319+static struct mscc_switch_capa capa __ro_after_init = {
320+ .num_tas_gcl = 64,
321+ .tas_ct_min = 100,
322+ .tas_ct_max = 1000000000,
323+ .tas_cte_max = 999999999,
324+ .tas_it_max = 999999999,
325+ .tas_it_min = 1000,
326+ .num_hsch = 72,
327+ .num_psfp_sfid = MSCC_PSFP_SFID_NUM,
328+ .num_psfp_sgid = 184,
329+ .psfp_fmi_max = 246,
330+ .psfp_fmi_min = 63,
331+ .num_sgi_gcl = 4,
332+ .sgi_ct_min = 5000,
333+ .sgi_ct_max = 1000000000,
334+ .sgi_cte_max = 999999999,
335+ .qos_pol_max = 383,
336+ /* Maximum allowed value of committed burst size(CBS) is 240 KB */
337+ .pol_cbs_max = 60,
338+ /* Maximum allowed value of excess burst size(EBS) is 240 KB */
339+ .pol_pbs_max = 60,
340+ .num_frer_ssid = MSCC_FRER_SSID_NUM,
341+ .frer_seq_len_min = 1,
342+ .frer_seq_len_max = 28,
343+ .frer_his_len_min = 1,
344+ .frer_his_len_max = 32,
345+ .qos_dscp_max = 63,
346+ .qos_cos_max = NUM_MSCC_QOS_PRIO - 1,
347+ .qos_dp_max = 1,
348+};
349+
350+static int qos_port_tas_gcl_set(struct ocelot *ocelot, const u8 gcl_ix,
351+ struct tsn_qbv_entry *control_list)
352+{
353+ if (gcl_ix >= capa.num_tas_gcl) {
354+ dev_err(ocelot->dev, "Invalid gcl ix %u\n", gcl_ix);
355+ return -EINVAL;
356+ }
357+ if (control_list->time_interval < capa.tas_it_min ||
358+ control_list->time_interval > capa.tas_it_max) {
359+ dev_err(ocelot->dev, "Invalid time_interval %u\n",
360+ control_list->time_interval);
361+
362+ return -EINVAL;
363+ }
364+
365+ ocelot_write(ocelot,
366+ QSYS_GCL_CFG_REG_1_GCL_ENTRY_NUM(gcl_ix) |
367+ QSYS_GCL_CFG_REG_1_GATE_STATE(control_list->gate_state),
368+ QSYS_GCL_CFG_REG_1);
369+
370+ ocelot_write(ocelot,
371+ control_list->time_interval,
372+ QSYS_GCL_CFG_REG_2);
373+
374+ return 0;
375+}
376+
377+static u32 tas_read_status(struct ocelot *ocelot)
378+{
379+ u32 val;
380+
381+ val = ocelot_read(ocelot, QSYS_TAS_PARAM_CFG_CTRL);
382+
383+ return val;
384+}
385+
386+int ocelot_qbv_set(struct ocelot *ocelot, int port_id,
387+ struct tsn_qbv_conf *shaper_config)
388+{
389+ struct tsn_qbv_basic *admin_basic = &shaper_config->admin;
390+ struct tsn_qbv_entry *control_list = admin_basic->control_list;
391+ u32 base_time_nsec = admin_basic->base_time % 1000000000;
392+ u64 base_time_sec = admin_basic->base_time / 1000000000;
393+ u64 cur_time;
394+ u32 val;
395+ u8 speed;
396+ int i;
397+ int ret;
398+
399+ if (admin_basic->control_list_length > capa.num_tas_gcl) {
400+ dev_err(ocelot->dev,
401+ "Invalid admin_control_list_length %u\n",
402+ admin_basic->control_list_length);
403+ return -EINVAL;
404+ }
405+
406+ if ((admin_basic->cycle_time < capa.tas_ct_min ||
407+ admin_basic->cycle_time > capa.tas_ct_max) &&
408+ shaper_config->gate_enabled) {
409+ dev_err(ocelot->dev, "Invalid admin_cycle_time %u ns\n",
410+ admin_basic->cycle_time);
411+ return -EINVAL;
412+ }
413+ if (admin_basic->cycle_time_extension > capa.tas_cte_max) {
414+ dev_err(ocelot->dev,
415+ "Invalid admin_cycle_time_extension %u\n",
416+ admin_basic->cycle_time_extension);
417+ return -EINVAL;
418+ }
419+
420+ cur_time = ocelot_read(ocelot, PTP_CUR_SEC_MSB);
421+ cur_time = cur_time << 32;
422+ cur_time += ocelot_read(ocelot, PTP_CUR_SEC_LSB);
423+
424+ if (base_time_sec < cur_time) {
425+ base_time_sec = cur_time;
426+ base_time_nsec = ocelot_read(ocelot, PTP_CUR_NSEC);
427+ }
428+
429+ /* Select port */
430+ ocelot_rmw(ocelot,
431+ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM(port_id),
432+ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM_M,
433+ QSYS_TAS_PARAM_CFG_CTRL);
434+
435+ val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_8);
436+ if (val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING) {
437+ ocelot_rmw_rix(ocelot, 0, QSYS_TAG_CONFIG_ENABLE,
438+ QSYS_TAG_CONFIG, port_id);
439+ }
440+
441+ if (!shaper_config->gate_enabled)
442+ admin_basic->gate_states = 0xff;
443+
444+ val = ocelot_read_gix(ocelot, ANA_PFC_PFC_CFG, port_id);
445+ speed = ANA_PFC_PFC_CFG_FC_LINK_SPEED(val);
446+
447+ ocelot_rmw_rix(ocelot,
448+ (shaper_config->gate_enabled ?
449+ QSYS_TAG_CONFIG_ENABLE : 0) |
450+ QSYS_TAG_CONFIG_INIT_GATE_STATE(admin_basic->gate_states) |
451+ QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES(0xff) |
452+ QSYS_TAG_CONFIG_LINK_SPEED(speed),
453+ QSYS_TAG_CONFIG_ENABLE |
454+ QSYS_TAG_CONFIG_INIT_GATE_STATE_M |
455+ QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES_M |
456+ QSYS_TAG_CONFIG_LINK_SPEED_M,
457+ QSYS_TAG_CONFIG,
458+ port_id);
459+
460+ ocelot_write_rix(ocelot, shaper_config->maxsdu,
461+ QSYS_PORT_MAX_SDU, port_id);
462+ /* TODO: add queue max SDU set */
463+
464+ if (shaper_config->gate_enabled) {
465+ ocelot_write(ocelot, base_time_nsec,
466+ QSYS_PARAM_CFG_REG_1);
467+
468+ ocelot_write(ocelot, base_time_sec & GENMASK(31, 0),
469+ QSYS_PARAM_CFG_REG_2);
470+
471+ ocelot_write(ocelot,
472+ QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB(base_time_sec >> 32) |
473+ QSYS_PARAM_CFG_REG_3_LIST_LENGTH(admin_basic->control_list_length),
474+ QSYS_PARAM_CFG_REG_3);
475+
476+ ocelot_write(ocelot, admin_basic->cycle_time,
477+ QSYS_PARAM_CFG_REG_4);
478+
479+ ocelot_write(ocelot, admin_basic->cycle_time_extension,
480+ QSYS_PARAM_CFG_REG_5);
481+
482+ for (i = 0; i < admin_basic->control_list_length; i++) {
483+ qos_port_tas_gcl_set(ocelot, i, control_list);
484+ control_list++;
485+ }
486+
487+ /* Start configuration change */
488+ ocelot_rmw(ocelot,
489+ QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
490+ QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
491+ QSYS_TAS_PARAM_CFG_CTRL);
492+
493+ ret = readx_poll_timeout(tas_read_status, ocelot, val,
494+ !(QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE
495+ & val), 10, 100000);
496+ return ret;
497+ }
498+
499+ return 0;
500+}
501+
502+int ocelot_qbv_get(struct ocelot *ocelot, int port_id,
503+ struct tsn_qbv_conf *shaper_config)
504+{
505+ u32 val, reg;
506+ int i;
507+ u32 base_timel;
508+ u32 base_timeh;
509+ struct tsn_qbv_basic *admin = &shaper_config->admin;
510+ struct tsn_qbv_entry *list;
511+
512+ ocelot_rmw(ocelot,
513+ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM(port_id),
514+ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM_M,
515+ QSYS_TAS_PARAM_CFG_CTRL);
516+
517+ val = ocelot_read_rix(ocelot, QSYS_TAG_CONFIG, port_id);
518+ shaper_config->gate_enabled = (val & QSYS_TAG_CONFIG_ENABLE);
519+ admin->gate_states = QSYS_TAG_CONFIG_INIT_GATE_STATE_X(val);
520+
521+ base_timel = ocelot_read(ocelot, QSYS_PARAM_CFG_REG_1);
522+ base_timeh = ocelot_read(ocelot, QSYS_PARAM_CFG_REG_2);
523+ reg = ocelot_read(ocelot, QSYS_PARAM_CFG_REG_3);
524+ admin->base_time = base_timeh |
525+ (((u64)QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB(reg)) << 32);
526+
527+ admin->base_time = (admin->base_time * 1000000000) + base_timel;
528+
529+ admin->control_list_length =
530+ QSYS_PARAM_CFG_REG_3_LIST_LENGTH_X(reg);
531+
532+ admin->cycle_time = ocelot_read(ocelot, QSYS_PARAM_CFG_REG_4);
533+ admin->cycle_time_extension =
534+ ocelot_read(ocelot, QSYS_PARAM_CFG_REG_5);
535+
536+ list = kmalloc_array(admin->control_list_length,
537+ sizeof(struct tsn_qbv_entry), GFP_KERNEL);
538+ admin->control_list = list;
539+
540+ for (i = 0; i < admin->control_list_length; i++) {
541+ ocelot_rmw(ocelot,
542+ QSYS_GCL_CFG_REG_1_GCL_ENTRY_NUM(i),
543+ QSYS_GCL_CFG_REG_1_GCL_ENTRY_NUM_M,
544+ QSYS_GCL_CFG_REG_1);
545+
546+ list->time_interval =
547+ ocelot_read(ocelot, QSYS_GCL_CFG_REG_2);
548+
549+ reg = ocelot_read(ocelot, QSYS_GCL_CFG_REG_1);
550+ list->gate_state = QSYS_GCL_CFG_REG_1_GATE_STATE_X(reg);
551+
552+ list++;
553+ }
554+
555+ return 0;
556+}
557+
558+static int qbv_get_gatelist(struct ocelot *ocelot,
559+ struct tsn_qbv_basic *oper)
560+{
561+ u32 base_timel;
562+ u32 base_timeh;
563+ u32 val;
564+ struct tsn_qbv_entry *glist;
565+ int i;
566+
567+ base_timel = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_1);
568+ base_timeh = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_2);
569+ val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_3);
570+ oper->base_time = base_timeh;
571+ oper->base_time +=
572+ ((u64)QSYS_PARAM_STATUS_REG_3_BASE_TIME_SEC_MSB(val)) <<
573+ 32;
574+ oper->base_time = (oper->base_time * 1000000000) + base_timel;
575+
576+ oper->control_list_length =
577+ QSYS_PARAM_STATUS_REG_3_LIST_LENGTH_X(val);
578+
579+ oper->cycle_time = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_4);
580+ oper->cycle_time_extension = ocelot_read(ocelot,
581+ QSYS_PARAM_STATUS_REG_5);
582+
583+ val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_8);
584+ oper->gate_states = QSYS_PARAM_STATUS_REG_8_OPER_GATE_STATE_X(val);
585+
586+ glist = kmalloc_array(oper->control_list_length,
587+ sizeof(struct tsn_qbv_entry), GFP_KERNEL);
588+
589+ oper->control_list = glist;
590+
591+ for (i = 0; i < oper->control_list_length; i++) {
592+ ocelot_rmw(ocelot,
593+ QSYS_GCL_STATUS_REG_1_GCL_ENTRY_NUM(i),
594+ QSYS_GCL_STATUS_REG_1_GCL_ENTRY_NUM_M,
595+ QSYS_GCL_STATUS_REG_1);
596+
597+ val = ocelot_read(ocelot, QSYS_GCL_STATUS_REG_2);
598+ glist->time_interval = val;
599+ val = ocelot_read(ocelot, QSYS_GCL_STATUS_REG_1);
600+ glist->gate_state =
601+ QSYS_GCL_STATUS_REG_1_GATE_STATE_X(val);
602+
603+ glist++;
604+ }
605+
606+ return 0;
607+}
608+
609+int ocelot_qbv_get_status(struct ocelot *ocelot, int port_id,
610+ struct tsn_qbv_status *qbvstatus)
611+{
612+ struct tsn_qbv_basic *oper = &qbvstatus->oper;
613+ u32 val;
614+ ptptime_t cur_time;
615+
616+ ocelot_rmw(ocelot,
617+ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM(port_id),
618+ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM_M,
619+ QSYS_TAS_PARAM_CFG_CTRL);
620+
621+ qbvstatus->supported_list_max = capa.num_tas_gcl;
622+
623+ val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_8);
624+ qbvstatus->config_pending =
625+ (val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING) ? 1 : 0;
626+
627+ qbvstatus->config_change_time =
628+ ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_7);
629+
630+ qbvstatus->config_change_time +=
631+ ((u64)QSYS_PARAM_STATUS_REG_8_CFG_CHG_TIME_SEC_MSB(val)) <<
632+ 32;
633+
634+ qbvstatus->config_change_time =
635+ (qbvstatus->config_change_time * 1000000000) +
636+ ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_6);
637+
638+ qbvstatus->config_change_error =
639+ ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_9);
640+
641+ cur_time = ocelot_read(ocelot, PTP_CUR_SEC_MSB);
642+ cur_time = cur_time << 32;
643+ cur_time += ocelot_read(ocelot, PTP_CUR_SEC_LSB);
644+ cur_time = (cur_time * 1000000000) +
645+ ocelot_read(ocelot, PTP_CUR_NSEC);
646+
647+ qbvstatus->current_time = cur_time;
648+ qbv_get_gatelist(ocelot, oper);
649+
650+ return 0;
651+}
652+
653+int ocelot_cut_thru_set(struct ocelot *ocelot, int port_id, u8 cut_thru)
654+{
655+ ocelot_write_rix(ocelot, cut_thru, ANA_CUT_THRU_CFG, port_id);
656+
657+ return 0;
658+}
659+
660+static int qos_shaper_conf_set(struct ocelot *ocelot, int port,
661+ u32 port_ix, u8 percent)
662+{
663+ u32 val;
664+ int speed;
665+ u32 cbs = 0;
666+ u32 cir = 0;
667+
668+ if (percent > 100) {
669+ dev_err(ocelot->dev, "percentage %d larger than 100\n",
670+ percent);
671+ return -EINVAL;
672+ }
673+ if (port_ix >= capa.num_hsch) {
674+ dev_err(ocelot->dev,
675+ "CIR_CFG: id %d is exceed num of HSCH instance\n",
676+ port_ix);
677+ return -EINVAL;
678+ }
679+
680+ val = ocelot_read_gix(ocelot, ANA_PFC_PFC_CFG, port);
681+ speed = ANA_PFC_PFC_CFG_FC_LINK_SPEED(val);
682+ switch (speed) {
683+ case OCELOT_SPEED_10:
684+ cir = 10000;
685+ break;
686+ case OCELOT_SPEED_100:
687+ cir = 100000;
688+ break;
689+ case OCELOT_SPEED_1000:
690+ cir = 1000000;
691+ break;
692+ case OCELOT_SPEED_2500:
693+ cir = 2500000;
694+ break;
695+ }
696+
697+ cir = cir * percent / 100;
698+ cir = DIV_ROUND_UP(cir, 100); /* Rate unit is 100 kbps */
699+ cir = (cir ? cir : 1); /* Avoid using zero rate */
700+ cbs = DIV_ROUND_UP(cbs, 4096); /* Burst unit is 4kB */
701+ cbs = (cbs ? cbs : 1); /* Avoid using zero burst size */
702+ cir = min_t(u32, GENMASK(15, 0), cir);
703+ cbs = min_t(u32, GENMASK(6, 0), cbs);
704+ ocelot_write_gix(ocelot,
705+ QSYS_CIR_CFG_CIR_RATE(cir) |
706+ QSYS_CIR_CFG_CIR_BURST(cbs),
707+ QSYS_CIR_CFG,
708+ port_ix);
709+
710+ return 0;
711+}
712+
713+static int qos_shaper_conf_get(struct ocelot *ocelot, int port,
714+ u32 port_ix)
715+{
716+ u32 val;
717+ u32 bandwidth = 0;
718+ u32 cir = 0;
719+ int percentage;
720+ int speed;
721+
722+ if (port_ix >= capa.num_hsch) {
723+ dev_err(ocelot->dev,
724+ "CIR_CFG: id %d is exceed num of HSCH instance\n",
725+ port_ix);
726+ return -EINVAL;
727+ }
728+
729+ val = ocelot_read_gix(ocelot, ANA_PFC_PFC_CFG, port);
730+ speed = ANA_PFC_PFC_CFG_FC_LINK_SPEED(val);
731+ switch (speed) {
732+ case OCELOT_SPEED_10:
733+ bandwidth = 10000;
734+ break;
735+ case OCELOT_SPEED_100:
736+ bandwidth = 100000;
737+ break;
738+ case OCELOT_SPEED_1000:
739+ bandwidth = 1000000;
740+ break;
741+ case OCELOT_SPEED_2500:
742+ bandwidth = 2500000;
743+ break;
744+ }
745+
746+ val = ocelot_read_gix(ocelot, QSYS_CIR_CFG, port_ix);
747+
748+ cir = QSYS_CIR_CFG_CIR_RATE_X(val);
749+ cir *= 100;
750+ percentage = cir * 100 / bandwidth;
751+
752+ return percentage;
753+}
754+
755+int ocelot_cbs_set(struct ocelot *ocelot, int port, u8 tc, u8 bw)
756+{
757+ if (tc > capa.qos_cos_max) {
758+ dev_err(ocelot->dev, "Invalid tc: %u\n", tc);
759+ return -EINVAL;
760+ }
761+
762+ qos_shaper_conf_set(ocelot, port, port * 8 + tc, bw);
763+
764+ ocelot_rmw_gix(ocelot,
765+ QSYS_SE_CFG_SE_AVB_ENA,
766+ QSYS_SE_CFG_SE_AVB_ENA,
767+ QSYS_SE_CFG,
768+ port * 8 + tc);
769+
770+ return 0;
771+}
772+
773+int ocelot_cbs_get(struct ocelot *ocelot, int port, u8 tc)
774+{
775+ int ret;
776+
777+ if (tc > capa.qos_cos_max) {
778+ dev_err(ocelot->dev, "Invalid tc: %u\n", tc);
779+ return -EINVAL;
780+ }
781+
782+ ret = qos_shaper_conf_get(ocelot, port, port * 8 + tc);
783+
784+ return ret;
785+}
786+
787+int ocelot_qbu_set(struct ocelot *ocelot, int port, u8 preemptible)
788+{
789+ struct ocelot_port *ocelot_port = ocelot->ports[port];
790+
791+ ocelot_port_rmwl(ocelot_port,
792+ DEV_GMII_MM_CONFIG_ENABLE_CONFIG_MM_RX_ENA |
793+ DEV_GMII_MM_CONFIG_ENABLE_CONFIG_MM_TX_ENA,
794+ DEV_GMII_MM_CONFIG_ENABLE_CONFIG_MM_RX_ENA |
795+ DEV_GMII_MM_CONFIG_ENABLE_CONFIG_MM_TX_ENA,
796+ DEV_GMII_MM_CONFIG_ENABLE_CONFIG);
797+
798+ ocelot_rmw_rix(ocelot,
799+ QSYS_PREEMPTION_CFG_P_QUEUES(preemptible),
800+ QSYS_PREEMPTION_CFG_P_QUEUES_M,
801+ QSYS_PREEMPTION_CFG,
802+ port);
803+
804+ return 0;
805+}
806+
807+int ocelot_qbu_get(struct ocelot *ocelot, int port,
808+ struct tsn_preempt_status *c)
809+{
810+ struct ocelot_port *ocelot_port = ocelot->ports[port];
811+ u32 val;
812+
813+ val = ocelot_read_rix(ocelot,
814+ QSYS_PREEMPTION_CFG,
815+ port);
816+
817+ c->admin_state = QSYS_PREEMPTION_CFG_P_QUEUES(val);
818+ c->hold_advance = QSYS_PREEMPTION_CFG_HOLD_ADVANCE_X(val);
819+
820+ val = ocelot_port_readl(ocelot_port,
821+ DEV_GMII_MM_STATISTICS_MM_STATUS);
822+ c->preemption_active =
823+ DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_ACTIVE_STATUS & val;
824+
825+ return 0;
826+}
827+
828+int ocelot_cb_streamid_get(struct ocelot *ocelot, int port, u32 index,
829+ struct tsn_cb_streamid *streamid)
830+{
831+ u32 m_index;
832+ u32 bucket;
833+ u32 val, dst, reg;
834+ u64 dmac;
835+ u32 ldmac, hdmac;
836+
837+ if (index >= MSCC_STREAM_HANDLE_NUM) {
838+ dev_err(ocelot->dev,
839+ "Invalid stream handle %u, maximum:%u\n",
840+ index, MSCC_STREAM_HANDLE_NUM - 1);
841+ return -EINVAL;
842+ }
843+
844+ index = streamhandle_map[index];
845+ m_index = index / 4;
846+ bucket = index % 4;
847+ streamid->type = 1;
848+ regmap_field_write(ocelot->regfields[ANA_TABLES_MACTINDX_BUCKET],
849+ bucket);
850+ regmap_field_write(ocelot->regfields[ANA_TABLES_MACTINDX_M_INDEX],
851+ m_index);
852+
853+ /*READ command MACACCESS.VALID(11 bit) must be 0 */
854+ ocelot_write(ocelot,
855+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ),
856+ ANA_TABLES_MACACCESS);
857+
858+ val = ocelot_read(ocelot, ANA_TABLES_MACACCESS);
859+ dst = ANA_TABLES_MACACCESS_DEST_IDX_X(val);
860+ reg = ocelot_read_rix(ocelot, ANA_PGID_PGID, dst);
861+ streamid->ofac_oport = ANA_PGID_PGID_PGID(reg);
862+
863+ /*Get the entry's MAC address and VLAN id*/
864+ ldmac = ocelot_read(ocelot, ANA_TABLES_MACLDATA);
865+ val = ocelot_read(ocelot, ANA_TABLES_MACHDATA);
866+ val &= 0x1fffffff;
867+ hdmac = val & 0xffff;
868+ dmac = hdmac;
869+ dmac = (dmac << 32) | ldmac;
870+ streamid->para.nid.dmac = dmac;
871+
872+ streamid->para.nid.vid = ANA_TABLES_MACHDATA_VID_X(val);
873+
874+ val = ocelot_read(ocelot, ANA_TABLES_STREAMDATA);
875+ if (!(val & ANA_TABLES_STREAMDATA_SFID_VALID))
876+ return -EINVAL;
877+
878+ streamid->handle = ANA_TABLES_STREAMDATA_SFID(val);
879+
880+ return 0;
881+}
882+
883+static int lookup_mactable(struct ocelot *ocelot, u16 vid, u64 mac)
884+{
885+ u32 mach, macl;
886+ u32 reg1, reg2;
887+ u32 index, bucket;
888+
889+ macl = mac & 0xffffffff;
890+ mach = (mac >> 32) & 0xffff;
891+ ocelot_write(ocelot, macl, ANA_TABLES_MACLDATA);
892+ ocelot_write(ocelot, ANA_TABLES_MACHDATA_VID(vid) |
893+ ANA_TABLES_MACHDATA_MACHDATA(mach),
894+ ANA_TABLES_MACHDATA);
895+
896+ ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID |
897+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ),
898+ ANA_TABLES_MACACCESS);
899+
900+ reg1 = ocelot_read(ocelot, ANA_TABLES_MACLDATA);
901+ reg2 = ocelot_read(ocelot, ANA_TABLES_MACHDATA);
902+ if (reg1 == 0 && reg2 == 0)
903+ return -1;
904+
905+ regmap_field_read(ocelot->regfields[ANA_TABLES_MACTINDX_BUCKET],
906+ &bucket);
907+ regmap_field_read(ocelot->regfields[ANA_TABLES_MACTINDX_M_INDEX],
908+ &index);
909+
910+ index = index * 4 + bucket;
911+
912+ return index;
913+}
914+
915+int ocelot_cb_streamid_set(struct ocelot *ocelot, int port,
916+ u32 index, bool enable,
917+ struct tsn_cb_streamid *streamid)
918+{
919+ struct regmap_field *rf;
920+ u16 vid;
921+ u64 mac;
922+ u32 macl, mach;
923+ u32 dst_idx;
924+ int idx;
925+ u32 reg;
926+ int sfid, ssid;
927+ u32 m_index, bucket;
928+
929+ if (!enable) {
930+ if (index >= MSCC_STREAM_HANDLE_NUM) {
931+ dev_err(ocelot->dev,
932+ "Invalid index %u, maximum:%u\n",
933+ index, MSCC_STREAM_HANDLE_NUM - 1);
934+ return -EINVAL;
935+ }
936+ m_index = streamhandle_map[index] / 4;
937+ bucket = streamhandle_map[index] % 4;
938+ rf = ocelot->regfields[ANA_TABLES_MACTINDX_BUCKET];
939+ regmap_field_write(rf, bucket);
940+ rf = ocelot->regfields[ANA_TABLES_MACTINDX_M_INDEX];
941+ regmap_field_write(rf, m_index);
942+
943+ /*READ command MACACCESS.VALID(11 bit) must be 0 */
944+ ocelot_write(ocelot,
945+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ),
946+ ANA_TABLES_MACACCESS);
947+
948+ ocelot_write(ocelot,
949+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_FORGET),
950+ ANA_TABLES_MACACCESS);
951+
952+ streamhandle_map[index] = 0;
953+
954+ return 0;
955+ }
956+
957+ if (streamid->type != 1) {
958+ dev_err(ocelot->dev, "Invalid stream type\n");
959+ return -EINVAL;
960+ }
961+
962+ if (streamid->handle >= MSCC_STREAM_HANDLE_NUM) {
963+ dev_err(ocelot->dev,
964+ "Invalid stream handle %u, maximum:%u\n",
965+ streamid->handle, MSCC_STREAM_HANDLE_NUM - 1);
966+ return -EINVAL;
967+ }
968+
969+ sfid = streamid->handle;
970+ ssid = (streamid->handle < MSCC_FRER_SSID_NUM ?
971+ streamid->handle : (MSCC_FRER_SSID_NUM - 1));
972+
973+ mac = streamid->para.nid.dmac;
974+ macl = mac & 0xffffffff;
975+ mach = (mac >> 32) & 0xffff;
976+ vid = streamid->para.nid.vid;
977+
978+ idx = lookup_mactable(ocelot, vid, mac);
979+
980+ if (idx < 0) {
981+ ocelot_write(ocelot, macl, ANA_TABLES_MACLDATA);
982+ ocelot_write(ocelot, ANA_TABLES_MACHDATA_VID(vid) |
983+ ANA_TABLES_MACHDATA_MACHDATA(mach),
984+ ANA_TABLES_MACHDATA);
985+
986+ ocelot_write(ocelot,
987+ ANA_TABLES_STREAMDATA_SFID_VALID |
988+ ANA_TABLES_STREAMDATA_SFID(sfid) |
989+ ANA_TABLES_STREAMDATA_SSID_VALID |
990+ ANA_TABLES_STREAMDATA_SSID(ssid),
991+ ANA_TABLES_STREAMDATA);
992+
993+ dst_idx = port;
994+ ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID |
995+ ANA_TABLES_MACACCESS_ENTRYTYPE(1) |
996+ ANA_TABLES_MACACCESS_DEST_IDX(dst_idx) |
997+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_LEARN),
998+ ANA_TABLES_MACACCESS);
999+
1000+ ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID |
1001+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ),
1002+ ANA_TABLES_MACACCESS);
1003+
1004+ regmap_field_read(ocelot->regfields[ANA_TABLES_MACTINDX_BUCKET],
1005+ &bucket);
1006+ regmap_field_read(ocelot->regfields[ANA_TABLES_MACTINDX_M_INDEX],
1007+ &m_index);
1008+
1009+ m_index = m_index * 4 + bucket;
1010+ streamhandle_map[streamid->handle] = m_index;
1011+
1012+ return 0;
1013+ }
1014+
1015+ ocelot_write(ocelot,
1016+ ANA_TABLES_STREAMDATA_SFID_VALID |
1017+ ANA_TABLES_STREAMDATA_SFID(sfid) |
1018+ ANA_TABLES_STREAMDATA_SSID_VALID |
1019+ ANA_TABLES_STREAMDATA_SSID(ssid),
1020+ ANA_TABLES_STREAMDATA);
1021+
1022+ reg = ocelot_read(ocelot, ANA_TABLES_MACACCESS);
1023+ dst_idx = ANA_TABLES_MACACCESS_DEST_IDX_X(reg);
1024+ ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID |
1025+ ANA_TABLES_MACACCESS_ENTRYTYPE(1) |
1026+ ANA_TABLES_MACACCESS_DEST_IDX(dst_idx) |
1027+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_WRITE),
1028+ ANA_TABLES_MACACCESS);
1029+
1030+ streamhandle_map[streamid->handle] = idx;
1031+
1032+ return 0;
1033+}
1034+
1035+static int streamid_multi_forward_set(struct ocelot *ocelot, u32 index,
1036+ u8 fwdmask)
1037+{
1038+ u32 m_index;
1039+ u32 bucket;
1040+ u32 val;
1041+ int m, n, i;
1042+ u8 pgid_val, fwdport;
1043+ u32 dst_idx;
1044+
1045+ m_index = index / 4;
1046+ bucket = index % 4;
1047+
1048+ regmap_field_write(ocelot->regfields[ANA_TABLES_MACTINDX_BUCKET],
1049+ bucket);
1050+ regmap_field_write(ocelot->regfields[ANA_TABLES_MACTINDX_M_INDEX],
1051+ m_index);
1052+
1053+ /*READ command MACACCESS.VALID(11 bit) must be 0 */
1054+ ocelot_write(ocelot,
1055+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ),
1056+ ANA_TABLES_MACACCESS);
1057+
1058+ val = ocelot_read(ocelot, ANA_TABLES_MACACCESS);
1059+ fwdport = ANA_TABLES_MACACCESS_DEST_IDX_X(val);
1060+
1061+ if (fwdport >= MSCC_NUM_OUT_PORT) {
1062+ dst_idx = fwdport;
1063+ return 0;
1064+ }
1065+
1066+ fwdmask |= (1 << fwdport);
1067+
1068+ m = ocelot->num_phys_ports - 1;
1069+ for (i = m; i >= MSCC_NUM_OUT_PORT; i--) {
1070+ if (fwdmask & (1 << i)) {
1071+ dst_idx = PGID_MCRED +
1072+ (m - i) * MSCC_NUM_OUT_PORT +
1073+ fwdport;
1074+
1075+ pgid_val = (1 << i) | (1 << fwdport);
1076+ break;
1077+ }
1078+ }
1079+
1080+ if (i < MSCC_NUM_OUT_PORT) {
1081+ m = PGID_MCRED +
1082+ (ocelot->num_phys_ports - MSCC_NUM_OUT_PORT) *
1083+ MSCC_NUM_OUT_PORT;
1084+
1085+ for (; i > 0; i--) {
1086+ if (fwdmask & (1 << i))
1087+ break;
1088+
1089+ m = m + (1 << i) - 1;
1090+ }
1091+ n = fwdmask & ((1 << i) - 1);
1092+ if (n) {
1093+ dst_idx = m + n;
1094+ pgid_val = fwdmask & ((1 << MSCC_NUM_OUT_PORT) - 1);
1095+ } else {
1096+ dst_idx = fwdport;
1097+ }
1098+ }
1099+
1100+ if (dst_idx < PGID_MCRED)
1101+ return 0;
1102+
1103+ ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID |
1104+ ANA_TABLES_MACACCESS_ENTRYTYPE(1) |
1105+ ANA_TABLES_MACACCESS_DEST_IDX(dst_idx) |
1106+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_WRITE),
1107+ ANA_TABLES_MACACCESS);
1108+
1109+ ocelot_write_rix(ocelot, pgid_val, ANA_PGID_PGID, dst_idx);
1110+
1111+ return 0;
1112+}
1113+
1114+int ocelot_qci_sfi_get(struct ocelot *ocelot, int port, u32 index,
1115+ struct tsn_qci_psfp_sfi_conf *sfi)
1116+{
1117+ u32 val, reg, fmeter_id, max_sdu;
1118+ u32 sfid = index;
1119+
1120+ if (sfid >= capa.num_psfp_sfid) {
1121+ dev_err(ocelot->dev, "Invalid index %u, maximum:%u\n",
1122+ sfid, capa.num_psfp_sfid);
1123+ return -EINVAL;
1124+ }
1125+
1126+ ocelot_rmw(ocelot,
1127+ ANA_TABLES_SFIDTIDX_SFID_INDEX(sfid),
1128+ ANA_TABLES_SFIDTIDX_SFID_INDEX_M,
1129+ ANA_TABLES_SFIDTIDX);
1130+
1131+ ocelot_write(ocelot,
1132+ ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(SFIDACCESS_CMD_READ),
1133+ ANA_TABLES_SFIDACCESS);
1134+
1135+ val = ocelot_read(ocelot, ANA_TABLES_SFIDTIDX);
1136+ if (!(val & ANA_TABLES_SFIDTIDX_SGID_VALID))
1137+ return -EINVAL;
1138+
1139+ sfi->stream_gate_instance_id = ANA_TABLES_SFIDTIDX_SGID_X(val);
1140+ fmeter_id = ANA_TABLES_SFIDTIDX_POL_IDX_X(val);
1141+ sfi->stream_filter.flow_meter_instance_id = fmeter_id;
1142+
1143+ reg = ocelot_read(ocelot, ANA_TABLES_SFIDACCESS);
1144+ max_sdu = ANA_TABLES_SFIDACCESS_MAX_SDU_LEN_X(reg);
1145+ sfi->stream_filter.maximum_sdu_size = max_sdu;
1146+
1147+ if (reg & ANA_TABLES_SFIDACCESS_IGR_PRIO_MATCH_ENA)
1148+ sfi->priority_spec = ANA_TABLES_SFIDACCESS_IGR_PRIO_X(reg);
1149+ else
1150+ dev_err(ocelot->dev, "priority not enable\n");
1151+
1152+ return 0;
1153+}
1154+
1155+int ocelot_qci_sfi_set(struct ocelot *ocelot, int port,
1156+ u32 index, bool enable,
1157+ struct tsn_qci_psfp_sfi_conf *sfi)
1158+{
1159+ int igr_prio = sfi->priority_spec;
1160+ u16 sgid = sfi->stream_gate_instance_id;
1161+ u16 pol_idx;
1162+ int fmid = sfi->stream_filter.flow_meter_instance_id;
1163+ u16 max_sdu_len = sfi->stream_filter.maximum_sdu_size;
1164+ int sfid = index;
1165+ u32 val;
1166+
1167+ if (fmid == -1)
1168+ pol_idx = capa.psfp_fmi_max;
1169+ else
1170+ pol_idx = (u16)fmid;
1171+
1172+ if (sfid >= capa.num_psfp_sfid) {
1173+ dev_err(ocelot->dev, "Invalid index %u, maximum:%u\n",
1174+ sfid, capa.num_psfp_sfid);
1175+ return -EINVAL;
1176+ }
1177+
1178+ if (!enable) {
1179+ val = ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(SFIDACCESS_CMD_WRITE);
1180+ ocelot_write(ocelot,
1181+ ANA_TABLES_SFIDTIDX_SFID_INDEX(sfid),
1182+ ANA_TABLES_SFIDTIDX);
1183+ ocelot_write(ocelot, val, ANA_TABLES_SFIDACCESS);
1184+ return 0;
1185+ }
1186+
1187+ if (sgid >= capa.num_psfp_sgid) {
1188+ dev_err(ocelot->dev, "Invalid sgid %u, maximum:%u\n",
1189+ sgid, capa.num_psfp_sgid);
1190+ return -EINVAL;
1191+ }
1192+ if (pol_idx > capa.psfp_fmi_max || pol_idx < capa.psfp_fmi_min) {
1193+ dev_err(ocelot->dev, "Invalid pol_idx %u, range:%d~%d\n",
1194+ pol_idx, capa.psfp_fmi_min, capa.psfp_fmi_max);
1195+ return -EINVAL;
1196+ }
1197+
1198+ ocelot_write(ocelot, ANA_TABLES_SFIDTIDX_SGID_VALID |
1199+ ANA_TABLES_SFIDTIDX_SGID(sgid) |
1200+ ((fmid != -1) ? ANA_TABLES_SFIDTIDX_POL_ENA : 0) |
1201+ ANA_TABLES_SFIDTIDX_POL_IDX(pol_idx) |
1202+ ANA_TABLES_SFIDTIDX_SFID_INDEX(sfid),
1203+ ANA_TABLES_SFIDTIDX);
1204+
1205+ ocelot_write(ocelot,
1206+ ((igr_prio >= 0) ?
1207+ ANA_TABLES_SFIDACCESS_IGR_PRIO_MATCH_ENA : 0) |
1208+ ANA_TABLES_SFIDACCESS_IGR_PRIO(igr_prio) |
1209+ ANA_TABLES_SFIDACCESS_MAX_SDU_LEN(max_sdu_len) |
1210+ ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(SFIDACCESS_CMD_WRITE),
1211+ ANA_TABLES_SFIDACCESS);
1212+
1213+ return 0;
1214+}
1215+
1216+int ocelot_qci_sfi_counters_get(struct ocelot *ocelot, int port,
1217+ u32 index,
1218+ struct tsn_qci_psfp_sfi_counters *sfi_cnt)
1219+{
1220+ u32 sfid = index;
1221+ u32 match, not_pass, not_pass_sdu, red;
1222+
1223+ if (sfid >= capa.num_psfp_sfid) {
1224+ dev_err(ocelot->dev, "Invalid index %u, maximum:%u\n",
1225+ sfid, capa.num_psfp_sfid);
1226+ return -EINVAL;
1227+ }
1228+
1229+ ocelot_rmw(ocelot,
1230+ SYS_STAT_CFG_STAT_VIEW(sfid),
1231+ SYS_STAT_CFG_STAT_VIEW_M,
1232+ SYS_STAT_CFG);
1233+
1234+ match = ocelot_read_gix(ocelot, SYS_CNT, 0x200);
1235+ not_pass = ocelot_read_gix(ocelot, SYS_CNT, 0x201);
1236+ not_pass_sdu = ocelot_read_gix(ocelot, SYS_CNT, 0x202);
1237+ red = ocelot_read_gix(ocelot, SYS_CNT, 0x203);
1238+
1239+ sfi_cnt->matching_frames_count = match;
1240+ sfi_cnt->not_passing_frames_count = not_pass;
1241+ sfi_cnt->not_passing_sdu_count = not_pass_sdu;
1242+ sfi_cnt->red_frames_count = red;
1243+
1244+ sfi_cnt->passing_frames_count = match - not_pass;
1245+ sfi_cnt->passing_sdu_count = match - not_pass - not_pass_sdu;
1246+
1247+ return 0;
1248+}
1249+
1250+int ocelot_qci_max_cap_get(struct ocelot *ocelot,
1251+ struct tsn_qci_psfp_stream_param *stream_para)
1252+{
1253+ /* MaxStreamFilterInstances */
1254+ stream_para->max_sf_instance = capa.num_psfp_sfid;
1255+ /* MaxStreamGateInstances */
1256+ stream_para->max_sg_instance = capa.num_psfp_sgid;
1257+ /* MaxFlowMeterInstances */
1258+ stream_para->max_fm_instance = capa.psfp_fmi_max -
1259+ capa.psfp_fmi_min + 1;
1260+ /* SupportedListMax */
1261+ stream_para->supported_list_max = capa.num_sgi_gcl;
1262+
1263+ return 0;
1264+}
1265+
1266+static int sgi_set_glist(struct ocelot *ocelot,
1267+ struct tsn_qci_psfp_gcl *gcl, uint32_t num)
1268+{
1269+ u32 time_sum = 0;
1270+ int i;
1271+
1272+ if (num > capa.num_sgi_gcl)
1273+ return -EINVAL;
1274+
1275+ for (i = 0; i < num; i++) {
1276+ u32 val = ANA_SG_GCL_GS_CONFIG_IPS((gcl->ipv < 0) ?
1277+ 0 : gcl->ipv + 8);
1278+ val |= (gcl->gate_state ? ANA_SG_GCL_GS_CONFIG_GATE_STATE : 0);
1279+ ocelot_write_rix(ocelot, val, ANA_SG_GCL_GS_CONFIG, i);
1280+
1281+ time_sum += gcl->time_interval;
1282+ ocelot_write_rix(ocelot, time_sum, ANA_SG_GCL_TI_CONFIG, i);
1283+
1284+ gcl++;
1285+ }
1286+
1287+ return 0;
1288+}
1289+
1290+static u32 sgi_read_status(struct ocelot *ocelot)
1291+{
1292+ u32 val;
1293+
1294+ val = ocelot_read(ocelot, ANA_SG_ACCESS_CTRL);
1295+
1296+ return val;
1297+}
1298+
1299+int ocelot_qci_sgi_set(struct ocelot *ocelot, int port, u32 index,
1300+ struct tsn_qci_psfp_sgi_conf *sgi_conf)
1301+{
1302+ struct tsn_qci_sg_control *admin_list = &sgi_conf->admin;
1303+ u32 sgid = index;
1304+ u32 list_length = sgi_conf->admin.control_list_length;
1305+ u32 cycle_time = sgi_conf->admin.cycle_time;
1306+ u32 cycle_time_ex = sgi_conf->admin.cycle_time_extension;
1307+ u32 l_basetime = sgi_conf->admin.base_time % 1000000000;
1308+ u64 h_basetime = sgi_conf->admin.base_time / 1000000000;
1309+ u64 cur_time;
1310+ u32 val;
1311+ int ret;
1312+
1313+ if (sgid >= capa.num_psfp_sgid) {
1314+ dev_err(ocelot->dev, "Invalid sgid %u, maximum:%u\n",
1315+ sgid, capa.num_psfp_sgid);
1316+ return -EINVAL;
1317+ }
1318+ if ((cycle_time < capa.sgi_ct_min ||
1319+ cycle_time > capa.sgi_ct_max) &&
1320+ sgi_conf->gate_enabled) {
1321+ dev_err(ocelot->dev, "Invalid cycle_time %u ns\n",
1322+ cycle_time);
1323+ return -EINVAL;
1324+ }
1325+ if (cycle_time_ex > capa.sgi_cte_max) {
1326+ dev_err(ocelot->dev,
1327+ "Invalid cycle_time_extension %u\n",
1328+ cycle_time_ex);
1329+ return -EINVAL;
1330+ }
1331+ if (list_length > capa.num_sgi_gcl) {
1332+ dev_err(ocelot->dev,
1333+ "Invalid sgi_gcl len %u, maximum:%u\n",
1334+ list_length, capa.num_sgi_gcl);
1335+ return -EINVAL;
1336+ }
1337+
1338+ /*configure SGID*/
1339+ ocelot_rmw(ocelot,
1340+ ANA_SG_ACCESS_CTRL_SGID(sgid),
1341+ ANA_SG_ACCESS_CTRL_SGID_M,
1342+ ANA_SG_ACCESS_CTRL);
1343+
1344+ /*Disable SG*/
1345+ if (!sgi_conf->gate_enabled) {
1346+ ocelot_rmw(ocelot,
1347+ ANA_SG_CONFIG_REG_3_INIT_GATE_STATE,
1348+ ANA_SG_CONFIG_REG_3_INIT_GATE_STATE |
1349+ ANA_SG_CONFIG_REG_3_GATE_ENABLE,
1350+ ANA_SG_CONFIG_REG_3);
1351+ return 0;
1352+ }
1353+
1354+ /*admin parameters*/
1355+ cur_time = ocelot_read(ocelot, PTP_CUR_SEC_MSB);
1356+ cur_time = cur_time << 32;
1357+ cur_time += ocelot_read(ocelot, PTP_CUR_SEC_LSB);
1358+ if (h_basetime < cur_time) {
1359+ h_basetime = cur_time;
1360+ l_basetime = ocelot_read(ocelot, PTP_CUR_NSEC);
1361+ }
1362+
1363+ ocelot_write(ocelot, l_basetime, ANA_SG_CONFIG_REG_1);
1364+ ocelot_write(ocelot, h_basetime, ANA_SG_CONFIG_REG_2);
1365+
1366+ ocelot_write(ocelot,
1367+ (sgi_conf->admin.init_ipv < 0 ?
1368+ 0 : ANA_SG_CONFIG_REG_3_IPV_VALID) |
1369+ ANA_SG_CONFIG_REG_3_INIT_IPV(sgi_conf->admin.init_ipv) |
1370+ ANA_SG_CONFIG_REG_3_GATE_ENABLE |
1371+ ANA_SG_CONFIG_REG_3_LIST_LENGTH(list_length) |
1372+ (sgi_conf->admin.gate_states > 0 ?
1373+ ANA_SG_CONFIG_REG_3_INIT_GATE_STATE : 0) |
1374+ ANA_SG_CONFIG_REG_3_BASE_TIME_SEC_MSB(h_basetime >> 32),
1375+ ANA_SG_CONFIG_REG_3);
1376+
1377+ ocelot_write(ocelot, cycle_time, ANA_SG_CONFIG_REG_4);
1378+ ocelot_write(ocelot, cycle_time_ex, ANA_SG_CONFIG_REG_5);
1379+
1380+ ret = sgi_set_glist(ocelot, admin_list->gcl, list_length);
1381+ if (ret < 0)
1382+ return ret;
1383+
1384+ /* Start configuration change */
1385+ ocelot_rmw(ocelot,
1386+ ANA_SG_ACCESS_CTRL_CONFIG_CHANGE,
1387+ ANA_SG_ACCESS_CTRL_CONFIG_CHANGE,
1388+ ANA_SG_ACCESS_CTRL);
1389+
1390+ ret = readx_poll_timeout(sgi_read_status, ocelot, val,
1391+ (!(ANA_SG_ACCESS_CTRL_CONFIG_CHANGE & val)),
1392+ 10, 100000);
1393+
1394+ return ret;
1395+}
1396+
1397+static int sgi_get_glist(struct ocelot *ocelot,
1398+ struct tsn_qci_psfp_gcl *gcl,
1399+ uint32_t num)
1400+{
1401+ int i;
1402+ u16 val;
1403+ u32 time = 0;
1404+ u32 reg;
1405+
1406+ if (num > capa.num_sgi_gcl)
1407+ return -EINVAL;
1408+
1409+ for (i = 0; i < num; i++) {
1410+ val = ocelot_read_rix(ocelot, ANA_SG_GCL_GS_CONFIG, i);
1411+ gcl->gate_state = (val & ANA_SG_GCL_GS_CONFIG_GATE_STATE);
1412+
1413+ if (val & ANA_SG_GCL_GS_CONFIG_IPV_VALID)
1414+ gcl->ipv = ANA_SG_GCL_GS_CONFIG_IPV(val);
1415+ else
1416+ gcl->ipv = -1;
1417+
1418+ reg = ocelot_read_rix(ocelot, ANA_SG_GCL_TI_CONFIG, i);
1419+ gcl->time_interval = (reg - time);
1420+ time = reg;
1421+
1422+ gcl++;
1423+ }
1424+
1425+ return 0;
1426+}
1427+
1428+int ocelot_qci_sgi_get(struct ocelot *ocelot, int port, u32 index,
1429+ struct tsn_qci_psfp_sgi_conf *sgi_conf)
1430+{
1431+ struct tsn_qci_sg_control *admin = &sgi_conf->admin;
1432+ struct tsn_qci_psfp_gcl *glist;
1433+ u32 val, reg;
1434+ u32 list_num;
1435+ int ret;
1436+
1437+ if (index >= capa.num_psfp_sgid) {
1438+ dev_err(ocelot->dev, "Invalid sgid %u, maximum:%u\n",
1439+ index, capa.num_psfp_sgid);
1440+ return -EINVAL;
1441+ }
1442+
1443+ ocelot_rmw(ocelot,
1444+ ANA_SG_ACCESS_CTRL_SGID(index),
1445+ ANA_SG_ACCESS_CTRL_SGID_M,
1446+ ANA_SG_ACCESS_CTRL);
1447+
1448+ admin->cycle_time = ocelot_read(ocelot, ANA_SG_CONFIG_REG_4);
1449+ admin->cycle_time_extension =
1450+ ocelot_read(ocelot, ANA_SG_CONFIG_REG_5);
1451+
1452+ val = ocelot_read(ocelot, ANA_SG_CONFIG_REG_2);
1453+ admin->base_time = val;
1454+
1455+ reg = ocelot_read(ocelot, ANA_SG_CONFIG_REG_1);
1456+ val = ocelot_read(ocelot, ANA_SG_CONFIG_REG_3);
1457+
1458+ admin->base_time +=
1459+ ANA_SG_CONFIG_REG_3_BASE_TIME_SEC_MSB(val) << 32;
1460+
1461+ admin->base_time = admin->base_time * 1000000000 + reg;
1462+
1463+ if (val & ANA_SG_CONFIG_REG_3_IPV_VALID)
1464+ admin->init_ipv = ANA_SG_CONFIG_REG_3_INIT_IPV_X(val);
1465+ else
1466+ admin->init_ipv = -1;
1467+
1468+ if (val & ANA_SG_CONFIG_REG_3_GATE_ENABLE)
1469+ sgi_conf->gate_enabled = TRUE;
1470+
1471+ admin->control_list_length = ANA_SG_CONFIG_REG_3_LIST_LENGTH_X(val);
1472+
1473+ list_num = admin->control_list_length;
1474+
1475+ glist = kmalloc_array(list_num, sizeof(struct tsn_qci_psfp_gcl),
1476+ GFP_KERNEL);
1477+ admin->gcl = glist;
1478+
1479+ ret = sgi_get_glist(ocelot, glist, list_num);
1480+
1481+ return ret;
1482+}
1483+
1484+int ocelot_qci_sgi_status_get(struct ocelot *ocelot, int port, u32 index,
1485+ struct tsn_psfp_sgi_status *sgi_status)
1486+{
1487+ u32 val, reg;
1488+
1489+ if (index >= capa.num_psfp_sgid) {
1490+ dev_err(ocelot->dev, "Invalid sgid %u, maximum:%u\n",
1491+ index, capa.num_psfp_sgid);
1492+ return -EINVAL;
1493+ }
1494+
1495+ ocelot_rmw(ocelot,
1496+ ANA_SG_ACCESS_CTRL_SGID(index),
1497+ ANA_SG_ACCESS_CTRL_SGID_M,
1498+ ANA_SG_ACCESS_CTRL);
1499+
1500+ val = ocelot_read(ocelot, ANA_SG_STATUS_REG_2);
1501+ sgi_status->config_change_time = val;
1502+
1503+ reg = ocelot_read(ocelot, ANA_SG_STATUS_REG_1);
1504+ val = ocelot_read(ocelot, ANA_SG_STATUS_REG_3);
1505+ sgi_status->config_change_time +=
1506+ ANA_SG_STATUS_REG_3_CFG_CHG_TIME_SEC_MSB(val) << 32;
1507+ sgi_status->config_change_time =
1508+ sgi_status->config_change_time * 1000000000 + reg;
1509+
1510+ if (val & ANA_SG_STATUS_REG_3_CONFIG_PENDING)
1511+ sgi_status->config_pending = TRUE;
1512+ else
1513+ sgi_status->config_pending = FALSE;
1514+
1515+ if (val & ANA_SG_STATUS_REG_3_GATE_STATE)
1516+ sgi_status->oper.gate_states = TRUE;
1517+ else
1518+ sgi_status->oper.gate_states = FALSE;
1519+ /*bit 3 encoding 0:IPV [0:2]is invalid . 1:IPV[0:2] is valid*/
1520+ if (val & ANA_SG_STATUS_REG_3_IPV_VALID)
1521+ sgi_status->oper.init_ipv = ANA_SG_STATUS_REG_3_IPV_X(val);
1522+ else
1523+ sgi_status->oper.init_ipv = -1;
1524+
1525+ return 0;
1526+}
1527+
1528+int ocelot_qci_fmi_set(struct ocelot *ocelot, int port, u32 index,
1529+ bool enable, struct tsn_qci_psfp_fmi *fmi)
1530+{
1531+ u32 cir = 0, cbs = 0, pir = 0, pbs = 0;
1532+ u32 cir_ena = 0;
1533+ u32 pbs_max = 0, cbs_max = 0;
1534+ bool cir_discard = 0, pir_discard = 0;
1535+
1536+ if (index > capa.qos_pol_max) {
1537+ dev_err(ocelot->dev, "Invalid pol_idx %u, maximum: %u\n",
1538+ index, capa.qos_pol_max);
1539+ return -EINVAL;
1540+ }
1541+
1542+ if (fmi->mark_red_enable && fmi->mark_red) {
1543+ fmi->eir = 0;
1544+ fmi->ebs = 0;
1545+ fmi->cir = 0;
1546+ fmi->cbs = 0;
1547+ }
1548+
1549+ pir = fmi->eir;
1550+ pbs = fmi->ebs;
1551+
1552+ if (!fmi->drop_on_yellow)
1553+ cir_ena = 1;
1554+
1555+ if (cir_ena) {
1556+ cir = fmi->cir;
1557+ cbs = fmi->cbs;
1558+ if (cir == 0 && cbs == 0) {
1559+ cir_discard = 1;
1560+ } else {
1561+ cir = DIV_ROUND_UP(cir, 100);
1562+ cir *= 3; /* Rate unit is 33 1/3 kbps */
1563+ cbs = DIV_ROUND_UP(cbs, 4096);
1564+ cbs = (cbs ? cbs : 1);
1565+ cbs_max = capa.pol_cbs_max;
1566+ if (fmi->cf)
1567+ pir += fmi->cir;
1568+ }
1569+ }
1570+
1571+ if (pir == 0 && pbs == 0) {
1572+ pir_discard = 1;
1573+ } else {
1574+ pir = DIV_ROUND_UP(pir, 100);
1575+ pir *= 3; /* Rate unit is 33 1/3 kbps */
1576+ pbs = DIV_ROUND_UP(pbs, 4096);
1577+ pbs = (pbs ? pbs : 1);
1578+ pbs_max = capa.pol_pbs_max;
1579+ }
1580+ pir = min_t(u32, GENMASK(15, 0), pir);
1581+ cir = min_t(u32, GENMASK(15, 0), cir);
1582+ pbs = min(pbs_max, pbs);
1583+ cbs = min(cbs_max, cbs);
1584+
1585+ ocelot_write_gix(ocelot, (ANA_POL_MODE_CFG_IPG_SIZE(20) |
1586+ ANA_POL_MODE_CFG_FRM_MODE(1) |
1587+ (fmi->cf ? ANA_POL_MODE_CFG_DLB_COUPLED : 0) |
1588+ (cir_ena ? ANA_POL_MODE_CFG_CIR_ENA : 0) |
1589+ ANA_POL_MODE_CFG_OVERSHOOT_ENA),
1590+ ANA_POL_MODE_CFG, index);
1591+
1592+ ocelot_write_gix(ocelot, ANA_POL_PIR_CFG_PIR_RATE(pir) |
1593+ ANA_POL_PIR_CFG_PIR_BURST(pbs),
1594+ ANA_POL_PIR_CFG, index);
1595+
1596+ ocelot_write_gix(ocelot,
1597+ (pir_discard ? GENMASK(22, 0) : 0),
1598+ ANA_POL_PIR_STATE, index);
1599+
1600+ ocelot_write_gix(ocelot, ANA_POL_CIR_CFG_CIR_RATE(cir) |
1601+ ANA_POL_CIR_CFG_CIR_BURST(cbs),
1602+ ANA_POL_CIR_CFG, index);
1603+
1604+ ocelot_write_gix(ocelot,
1605+ (cir_discard ? GENMASK(22, 0) : 0),
1606+ ANA_POL_CIR_STATE, index);
1607+
1608+ return 0;
1609+}
1610+
1611+int ocelot_qci_fmi_get(struct ocelot *ocelot, int port, u32 index,
1612+ struct tsn_qci_psfp_fmi *fmi,
1613+ struct tsn_qci_psfp_fmi_counters *counters)
1614+{
1615+ u32 val, reg;
1616+
1617+ if (index > capa.qos_pol_max) {
1618+ dev_err(ocelot->dev, "Invalid pol_idx %u, maximum: %u\n",
1619+ index, capa.qos_pol_max);
1620+ return -EINVAL;
1621+ }
1622+
1623+ val = ocelot_read_gix(ocelot, ANA_POL_PIR_CFG, index);
1624+ reg = ocelot_read_gix(ocelot, ANA_POL_CIR_CFG, index);
1625+
1626+ fmi->eir = ANA_POL_PIR_CFG_PIR_RATE_X(val);
1627+ fmi->eir = fmi->eir * 100 / 3;
1628+ fmi->ebs = ANA_POL_PIR_CFG_PIR_BURST(val);
1629+ fmi->ebs *= 4096;
1630+ fmi->cir = ANA_POL_CIR_CFG_CIR_RATE_X(reg);
1631+ fmi->cir = fmi->cir * 100 / 3;
1632+ fmi->cbs = ANA_POL_CIR_CFG_CIR_BURST(reg);
1633+ fmi->cbs *= 4096;
1634+ if (!(fmi->eir | fmi->ebs | fmi->cir | fmi->cbs))
1635+ fmi->mark_red = TRUE;
1636+ else
1637+ fmi->mark_red = FALSE;
1638+
1639+ val = ocelot_read_gix(ocelot, ANA_POL_MODE_CFG, index);
1640+ if (val & ANA_POL_MODE_CFG_DLB_COUPLED)
1641+ fmi->cf = TRUE;
1642+ else
1643+ fmi->cf = FALSE;
1644+ if (val & ANA_POL_MODE_CFG_CIR_ENA)
1645+ fmi->drop_on_yellow = FALSE;
1646+ else
1647+ fmi->drop_on_yellow = TRUE;
1648+
1649+ return 0;
1650+}
1651+
1652+int ocelot_seq_gen_set(struct ocelot *ocelot, int port, u32 index,
1653+ struct tsn_seq_gen_conf *sg_conf)
1654+{
1655+ u8 iport_mask = sg_conf->iport_mask;
1656+ u8 split_mask = sg_conf->split_mask;
1657+ u8 seq_len = sg_conf->seq_len;
1658+ u32 seq_num = sg_conf->seq_num;
1659+
1660+ if (index >= capa.num_frer_ssid) {
1661+ dev_err(ocelot->dev, "Invalid SSID %u, maximum:%u\n",
1662+ index, capa.num_frer_ssid - 1);
1663+ return -EINVAL;
1664+ }
1665+ if (seq_len < capa.frer_seq_len_min ||
1666+ seq_len > capa.frer_seq_len_max) {
1667+ dev_err(ocelot->dev,
1668+ "Invalid seq_space_bits num %u,range:%d~%d\n",
1669+ seq_len,
1670+ capa.frer_seq_len_min,
1671+ capa.frer_seq_len_max);
1672+ return -EINVAL;
1673+ }
1674+
1675+ streamid_multi_forward_set(ocelot,
1676+ streamhandle_map[index],
1677+ split_mask);
1678+
1679+ ocelot_write(ocelot,
1680+ ANA_TABLES_SEQ_MASK_SPLIT_MASK(split_mask) |
1681+ ANA_TABLES_SEQ_MASK_INPUT_PORT_MASK(iport_mask),
1682+ ANA_TABLES_SEQ_MASK);
1683+
1684+ ocelot_write(ocelot,
1685+ ANA_TABLES_STREAMTIDX_S_INDEX(index) |
1686+ ANA_TABLES_STREAMTIDX_STREAM_SPLIT |
1687+ ANA_TABLES_STREAMTIDX_SEQ_SPACE_LOG2(seq_len),
1688+ ANA_TABLES_STREAMTIDX);
1689+
1690+ ocelot_write(ocelot,
1691+ ANA_TABLES_STREAMACCESS_GEN_REC_SEQ_NUM(seq_num) |
1692+ ANA_TABLES_STREAMACCESS_SEQ_GEN_REC_ENA |
1693+ ANA_TABLES_STREAMACCESS_STREAM_TBL_CMD(SFIDACCESS_CMD_WRITE),
1694+ ANA_TABLES_STREAMACCESS);
1695+
1696+ return 0;
1697+}
1698+
1699+int ocelot_seq_rec_set(struct ocelot *ocelot, int port, u32 index,
1700+ struct tsn_seq_rec_conf *sr_conf)
1701+{
1702+ u8 seq_len = sr_conf->seq_len;
1703+ u8 hislen = sr_conf->his_len;
1704+
1705+ if (index >= capa.num_frer_ssid) {
1706+ dev_err(ocelot->dev, "Invalid SSID %u, maximum:%u\n",
1707+ index, capa.num_frer_ssid - 1);
1708+ return -EINVAL;
1709+ }
1710+ if (seq_len < capa.frer_seq_len_min ||
1711+ seq_len > capa.frer_seq_len_max) {
1712+ dev_err(ocelot->dev,
1713+ "Invalid seq_space_bits num %u,range:%d~%d\n",
1714+ seq_len,
1715+ capa.frer_seq_len_min,
1716+ capa.frer_seq_len_max);
1717+ return -EINVAL;
1718+ }
1719+ if (hislen < capa.frer_his_len_min ||
1720+ hislen > capa.frer_his_len_max) {
1721+ dev_err(ocelot->dev,
1722+ "Invalid history_bits num %u,range:%d~%d\n",
1723+ hislen,
1724+ capa.frer_his_len_min,
1725+ capa.frer_his_len_max);
1726+ return -EINVAL;
1727+ }
1728+
1729+ ocelot_write(ocelot,
1730+ ANA_TABLES_STREAMTIDX_S_INDEX(index) |
1731+ ANA_TABLES_STREAMTIDX_FORCE_SF_BEHAVIOUR |
1732+ ANA_TABLES_STREAMTIDX_SEQ_HISTORY_LEN(hislen) |
1733+ ANA_TABLES_STREAMTIDX_RESET_ON_ROGUE |
1734+ (sr_conf->rtag_pop_en ?
1735+ ANA_TABLES_STREAMTIDX_REDTAG_POP : 0) |
1736+ ANA_TABLES_STREAMTIDX_SEQ_SPACE_LOG2(seq_len),
1737+ ANA_TABLES_STREAMTIDX);
1738+
1739+ ocelot_write(ocelot,
1740+ ANA_TABLES_STREAMACCESS_SEQ_GEN_REC_ENA |
1741+ ANA_TABLES_STREAMACCESS_GEN_REC_TYPE |
1742+ ANA_TABLES_STREAMACCESS_STREAM_TBL_CMD(SFIDACCESS_CMD_WRITE),
1743+ ANA_TABLES_STREAMACCESS);
1744+
1745+ return 0;
1746+}
1747+
1748+int ocelot_cb_get(struct ocelot *ocelot, int port, u32 index,
1749+ struct tsn_cb_status *c)
1750+{
1751+ u32 val;
1752+
1753+ if (index >= capa.num_frer_ssid) {
1754+ dev_err(ocelot->dev, "Invalid SSID %u, maximum:%u\n",
1755+ index, capa.num_frer_ssid - 1);
1756+ return -EINVAL;
1757+ }
1758+
1759+ ocelot_write(ocelot,
1760+ ANA_TABLES_STREAMTIDX_S_INDEX(index),
1761+ ANA_TABLES_STREAMTIDX);
1762+
1763+ ocelot_write(ocelot,
1764+ ANA_TABLES_STREAMACCESS_STREAM_TBL_CMD(SFIDACCESS_CMD_READ),
1765+ ANA_TABLES_STREAMACCESS);
1766+
1767+ val = ocelot_read(ocelot, ANA_TABLES_STREAMACCESS);
1768+ c->gen_rec = (ANA_TABLES_STREAMACCESS_GEN_REC_TYPE & val) >> 2;
1769+ c->seq_num = ANA_TABLES_STREAMACCESS_GEN_REC_SEQ_NUM_X(val);
1770+
1771+ val = ocelot_read(ocelot, ANA_TABLES_STREAMTIDX);
1772+ c->err = ANA_TABLES_STREAMTIDX_SEQ_GEN_ERR_STATUS_X(val);
1773+ c->his_len = ANA_TABLES_STREAMTIDX_SEQ_HISTORY_LEN_X(val);
1774+ c->seq_len = ANA_TABLES_STREAMTIDX_SEQ_SPACE_LOG2(val);
1775+
1776+ val = ocelot_read(ocelot, ANA_TABLES_SEQ_MASK);
1777+ c->split_mask = ANA_TABLES_SEQ_MASK_SPLIT_MASK_X(val);
1778+ c->iport_mask = ANA_TABLES_SEQ_MASK_INPUT_PORT_MASK(val);
1779+
1780+ c->seq_his = ocelot_read(ocelot, ANA_TABLES_SEQ_HISTORY);
1781+
1782+ return 0;
1783+}
1784+
1785+int ocelot_pcp_map_enable(struct ocelot *ocelot, u8 port)
1786+{
1787+ int i;
1788+
1789+ ocelot_rmw_gix(ocelot,
1790+ ANA_PORT_QOS_CFG_QOS_PCP_ENA,
1791+ ANA_PORT_QOS_CFG_QOS_PCP_ENA,
1792+ ANA_PORT_QOS_CFG,
1793+ port);
1794+
1795+ for (i = 0; i < NUM_MSCC_QOS_PRIO * 2; i++) {
1796+ ocelot_rmw_ix(ocelot,
1797+ (ANA_PORT_PCP_DEI_MAP_DP_PCP_DEI_VAL & i) |
1798+ ANA_PORT_PCP_DEI_MAP_QOS_PCP_DEI_VAL(i),
1799+ ANA_PORT_PCP_DEI_MAP_DP_PCP_DEI_VAL |
1800+ ANA_PORT_PCP_DEI_MAP_QOS_PCP_DEI_VAL_M,
1801+ ANA_PORT_PCP_DEI_MAP,
1802+ port, i);
1803+ }
1804+
1805+ return 0;
1806+}
1807+
1808+int ocelot_rtag_parse_enable(struct ocelot *ocelot, u8 port)
1809+{
1810+ ocelot_rmw_rix(ocelot,
1811+ ANA_PORT_MODE_REDTAG_PARSE_CFG,
1812+ ANA_PORT_MODE_REDTAG_PARSE_CFG,
1813+ ANA_PORT_MODE,
1814+ port);
1815+
1816+ return 0;
1817+}
1818+
1819+int ocelot_dscp_set(struct ocelot *ocelot, int port,
1820+ bool enable, const u8 dscp_ix,
1821+ struct tsn_qos_switch_dscp_conf *c)
1822+{
1823+ u32 val, ri = dscp_ix;
1824+
1825+ c->dscp = 0;
1826+ c->trust = 1;
1827+ c->remark = 0;
1828+
1829+ if (dscp_ix > capa.qos_dscp_max) {
1830+ dev_err(ocelot->dev, "Invalid dscp_ix %u\n", dscp_ix);
1831+ return -EINVAL;
1832+ }
1833+ if (c->cos > capa.qos_cos_max) {
1834+ dev_err(ocelot->dev, "Invalid cos %d\n", c->cos);
1835+ return -EINVAL;
1836+ }
1837+ if (c->dpl > capa.qos_dp_max) {
1838+ dev_err(ocelot->dev, "Invalid dpl %d\n", c->dpl);
1839+ return -EINVAL;
1840+ }
1841+
1842+ ocelot_rmw_gix(ocelot,
1843+ (enable ? ANA_PORT_QOS_CFG_QOS_DSCP_ENA : 0) |
1844+ (c->dscp ? ANA_PORT_QOS_CFG_DSCP_TRANSLATE_ENA : 0),
1845+ ANA_PORT_QOS_CFG_QOS_DSCP_ENA |
1846+ ANA_PORT_QOS_CFG_DSCP_TRANSLATE_ENA,
1847+ ANA_PORT_QOS_CFG,
1848+ port);
1849+
1850+ val = (c->dpl ? ANA_DSCP_CFG_DP_DSCP_VAL : 0) |
1851+ ANA_DSCP_CFG_QOS_DSCP_VAL(c->cos) |
1852+ ANA_DSCP_CFG_DSCP_TRANSLATE_VAL(c->dscp) |
1853+ (c->trust ? ANA_DSCP_CFG_DSCP_TRUST_ENA : 0) |
1854+ (c->remark ? ANA_DSCP_CFG_DSCP_REWR_ENA : 0);
1855+
1856+ ocelot_write_rix(ocelot, val, ANA_DSCP_CFG, ri);
1857+
1858+ return 0;
1859+}
1860--- /dev/null
1861+++ b/drivers/net/ethernet/mscc/ocelot_tsn.h
1862@@ -0,0 +1,51 @@
1863+/* SPDX-License-Identifier: (GPL-2.0 OR MIT)
1864+ *
1865+ * TSN_SWITCH driver
1866+ *
1867+ * Copyright 2018-2019 NXP
1868+ */
1869+
1870+#ifndef _MSCC_OCELOT_SWITCH_TSN_H_
1871+#define _MSCC_OCELOT_SWITCH_TSN_H_
1872+
1873+#define TRUE 1
1874+#define FALSE 0
1875+
1876+struct mscc_switch_capa {
1877+ u8 num_tas_gcl; /* Number of TAS Gate Control Lists */
1878+ u32 tas_ct_min; /* Minimum supported TAS CycleTime in nS */
1879+ u32 tas_ct_max; /* Maximum supported TAS CycleTime in nS */
1880+ u32 tas_cte_max; /* Maximum supported TAS CycleTimeExtension in nS
1881+ */
1882+ u32 tas_it_max;
1883+ u32 tas_it_min;
1884+ u8 num_hsch;
1885+ u8 num_psfp_sfid;
1886+ u8 num_frer_ssid;
1887+ u8 num_psfp_sgid;
1888+ u16 psfp_fmi_max;
1889+ u16 psfp_fmi_min;
1890+ u8 num_sgi_gcl;
1891+ u32 sgi_ct_min;
1892+ u32 sgi_ct_max;
1893+ u32 sgi_cte_max;
1894+ u16 qos_pol_max;
1895+ u8 pol_cbs_max;
1896+ u8 pol_pbs_max;
1897+ u8 frer_seq_len_min;
1898+ u8 frer_seq_len_max;
1899+ u8 frer_his_len_min;
1900+ u8 frer_his_len_max;
1901+ u8 qos_dscp_max;
1902+ u8 qos_cos_max;
1903+ u8 qos_dp_max;
1904+};
1905+
1906+static inline void ocelot_port_rmwl(struct ocelot_port *port, u32 val,
1907+ u32 mask, u32 reg)
1908+{
1909+ u32 cur = ocelot_port_readl(port, reg);
1910+
1911+ ocelot_port_writel(port, (cur & (~mask)) | val, reg);
1912+}
1913+#endif
1914--- a/include/soc/mscc/ocelot.h
1915+++ b/include/soc/mscc/ocelot.h
1916@@ -10,6 +10,7 @@
1917 #include <linux/if_vlan.h>
1918 #include <linux/regmap.h>
1919 #include <net/dsa.h>
1920+#include <net/tsn.h>
1921
1922 #define IFH_INJ_BYPASS BIT(31)
1923 #define IFH_INJ_POP_CNT_DISABLE (3 << 28)
1924@@ -328,6 +329,10 @@ enum ocelot_reg {
1925 PTP_CFG_MISC,
1926 PTP_CLK_CFG_ADJ_CFG,
1927 PTP_CLK_CFG_ADJ_FREQ,
1928+ PTP_CUR_NSF,
1929+ PTP_CUR_NSEC,
1930+ PTP_CUR_SEC_LSB,
1931+ PTP_CUR_SEC_MSB,
1932 GCB_SOFT_RST = GCB << TARGET_OFFSET,
1933 };
1934
1935@@ -539,5 +544,50 @@ int ocelot_ptp_gettime64(struct ptp_cloc
1936 int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port,
1937 struct sk_buff *skb);
1938 void ocelot_get_txtstamp(struct ocelot *ocelot);
1939-
1940+int ocelot_qbv_set(struct ocelot *ocelot, int port_id,
1941+ struct tsn_qbv_conf *shaper_config);
1942+int ocelot_qbv_get(struct ocelot *ocelot, int port_id,
1943+ struct tsn_qbv_conf *shaper_config);
1944+int ocelot_qbv_get_status(struct ocelot *ocelot, int port_id,
1945+ struct tsn_qbv_status *qbvstatus);
1946+int ocelot_cut_thru_set(struct ocelot *ocelot, int port_id, u8 cut_thru);
1947+int ocelot_cbs_set(struct ocelot *ocelot, int port, u8 tc, u8 bw);
1948+int ocelot_cbs_get(struct ocelot *ocelot, int port, u8 tc);
1949+int ocelot_qbu_set(struct ocelot *ocelot, int port, u8 preemptible);
1950+int ocelot_qbu_get(struct ocelot *ocelot, int port,
1951+ struct tsn_preempt_status *c);
1952+int ocelot_cb_streamid_get(struct ocelot *ocelot, int port, u32 index,
1953+ struct tsn_cb_streamid *streamid);
1954+int ocelot_cb_streamid_set(struct ocelot *ocelot, int port, u32 index,
1955+ bool enable, struct tsn_cb_streamid *streamid);
1956+int ocelot_qci_sfi_get(struct ocelot *ocelot, int port, u32 index,
1957+ struct tsn_qci_psfp_sfi_conf *sfi);
1958+int ocelot_qci_sfi_set(struct ocelot *ocelot, int port, u32 index,
1959+ bool enable, struct tsn_qci_psfp_sfi_conf *sfi);
1960+int ocelot_qci_sfi_counters_get(struct ocelot *ocelot, int port, u32 index,
1961+ struct tsn_qci_psfp_sfi_counters *sfi_counters);
1962+int ocelot_qci_max_cap_get(struct ocelot *ocelot,
1963+ struct tsn_qci_psfp_stream_param *stream_para);
1964+int ocelot_qci_sgi_set(struct ocelot *ocelot, int port, u32 index,
1965+ struct tsn_qci_psfp_sgi_conf *sgi_conf);
1966+int ocelot_qci_sgi_get(struct ocelot *ocelot, int port, u32 index,
1967+ struct tsn_qci_psfp_sgi_conf *sgi_conf);
1968+int ocelot_qci_sgi_status_get(struct ocelot *ocelot, int port, u32 index,
1969+ struct tsn_psfp_sgi_status *sgi_status);
1970+int ocelot_qci_fmi_set(struct ocelot *ocelot, int port, u32 index,
1971+ bool enable, struct tsn_qci_psfp_fmi *fmi);
1972+int ocelot_qci_fmi_get(struct ocelot *ocelot, int port, u32 index,
1973+ struct tsn_qci_psfp_fmi *fmi,
1974+ struct tsn_qci_psfp_fmi_counters *counters);
1975+int ocelot_seq_gen_set(struct ocelot *ocelot, int port, u32 index,
1976+ struct tsn_seq_gen_conf *sg_conf);
1977+int ocelot_seq_rec_set(struct ocelot *ocelot, int port, u32 index,
1978+ struct tsn_seq_rec_conf *sr_conf);
1979+int ocelot_cb_get(struct ocelot *ocelot, int port, u32 index,
1980+ struct tsn_cb_status *c);
1981+int ocelot_pcp_map_enable(struct ocelot *ocelot, u8 port);
1982+int ocelot_rtag_parse_enable(struct ocelot *ocelot, u8 port);
1983+int ocelot_dscp_set(struct ocelot *ocelot, int port,
1984+ bool enable, const u8 dscp_ix,
1985+ struct tsn_qos_switch_dscp_conf *c);
1986 #endif