1 // SPDX-License-Identifier: GPL-2.0
2 /* Texas Instruments ICSSG Ethernet Driver
3  *
4  * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
5  *
6  */
7 
8 #include <dm/ofnode.h>
9 #include <regmap.h>
10 
11 #define ICSSG_NUM_CLASSIFIERS	16
12 #define ICSSG_NUM_FT1_SLOTS	8
13 #define ICSSG_NUM_FT3_SLOTS	16
14 
15 #define ICSSG_NUM_CLASSIFIERS_IN_USE	1
16 
17 /* Filter 1 - FT1 */
18 #define FT1_NUM_SLOTS	8
19 #define FT1_SLOT_SIZE	0x10	/* bytes */
20 
21 /* offsets from FT1 slot base i.e. slot 1 start */
22 #define FT1_DA0		0x0
23 #define FT1_DA1		0x4
24 #define FT1_DA0_MASK	0x8
25 #define FT1_DA1_MASK	0xc
26 
27 #define FT1_N_REG(slize, n, reg)	(offs[slice].ft1_slot_base + FT1_SLOT_SIZE * (n) + (reg))
28 
29 #define FT1_LEN_MASK	GENMASK(19, 16)
30 #define FT1_LEN_SHIFT	16
31 #define FT1_LEN(len)	(((len) << FT1_LEN_SHIFT) & FT1_LEN_MASK)
32 
33 #define FT1_START_MASK	GENMASK(14, 0)
34 #define FT1_START(start)	((start) & FT1_START_MASK)
35 
36 #define FT1_MATCH_SLOT(n)	(GENMASK(23, 16) & (BIT(n) << 16))
37 
38 enum ft1_cfg_type {
39 	FT1_CFG_TYPE_DISABLED = 0,
40 	FT1_CFG_TYPE_EQ,
41 	FT1_CFG_TYPE_GT,
42 	FT1_CFG_TYPE_LT,
43 };
44 
45 #define FT1_CFG_SHIFT(n)	(2 * (n))
46 #define FT1_CFG_MASK(n)	(0x3 << FT1_CFG_SHIFT((n)))
47 
48 /* Filter 3 -  FT3 */
49 #define FT3_NUM_SLOTS	16
50 #define FT3_SLOT_SIZE	0x20	/* bytes */
51 
52 /* offsets from FT3 slot n's base */
53 #define FT3_START	0
54 #define FT3_START_AUTO	0x4
55 #define FT3_START_OFFSET	0x8
56 #define FT3_JUMP_OFFSET	0xc
57 #define FT3_LEN		0x10
58 #define FT3_CFG		0x14
59 #define FT3_T		0x18
60 #define FT3_T_MASK	0x1c
61 
62 #define FT3_N_REG(slize, n, reg)	\
63 	(offs[slice].ft3_slot_base + FT3_SLOT_SIZE * (n) + (reg))
64 
65 /* offsets from rx_class n's base */
66 #define RX_CLASS_AND_EN	0
67 #define RX_CLASS_OR_EN	0x4
68 
69 #define RX_CLASS_NUM_SLOTS	16
70 #define RX_CLASS_EN_SIZE	0x8	/* bytes */
71 
72 #define RX_CLASS_N_REG(slice, n, reg)	\
73 	(offs[slice].rx_class_base + RX_CLASS_EN_SIZE * (n) + (reg))
74 
75 /* RX Class Gates */
76 #define RX_CLASS_GATES_SIZE	0x4	/* bytes */
77 
78 #define RX_CLASS_GATES_N_REG(slice, n)	\
79 	(offs[slice].rx_class_gates_base + RX_CLASS_GATES_SIZE * (n))
80 
81 #define RX_CLASS_GATES_ALLOW_MASK	BIT(6)
82 #define RX_CLASS_GATES_RAW_MASK		BIT(5)
83 #define RX_CLASS_GATES_PHASE_MASK	BIT(4)
84 
85 /* RX Class traffic data matching bits */
86 #define RX_CLASS_FT_UC		BIT(31)
87 #define RX_CLASS_FT_MC		BIT(30)
88 #define RX_CLASS_FT_BC		BIT(29)
89 #define RX_CLASS_FT_FW		BIT(28)
90 #define RX_CLASS_FT_RCV		BIT(27)
91 #define RX_CLASS_FT_VLAN	BIT(26)
92 #define RX_CLASS_FT_DA_P	BIT(25)
93 #define RX_CLASS_FT_DA_I	BIT(24)
94 #define RX_CLASS_FT_FT1_MATCH_MASK	GENMASK(23, 16)
95 #define RX_CLASS_FT_FT1_MATCH_SHIFT	16
96 #define RX_CLASS_FT_FT3_MATCH_MASK	GENMASK(15, 0)
97 #define RX_CLASS_FT_FT3_MATCH_SHIFT	0
98 
99 #define RX_CLASS_FT_FT1_MATCH(slot)	\
100 	((BIT(slot) << RX_CLASS_FT_FT1_MATCH_SHIFT) & \
101 	RX_CLASS_FT_FT1_MATCH_MASK)
102 
103 enum rx_class_sel_type {
104 	RX_CLASS_SEL_TYPE_OR = 0,
105 	RX_CLASS_SEL_TYPE_AND = 1,
106 	RX_CLASS_SEL_TYPE_OR_AND_AND = 2,
107 	RX_CLASS_SEL_TYPE_OR_OR_AND = 3,
108 };
109 
110 #define FT1_CFG_SHIFT(n)	(2 * (n))
111 #define FT1_CFG_MASK(n)		(0x3 << FT1_CFG_SHIFT((n)))
112 
113 #define RX_CLASS_SEL_SHIFT(n)	(2 * (n))
114 #define RX_CLASS_SEL_MASK(n)	(0x3 << RX_CLASS_SEL_SHIFT((n)))
115 
116 #define ICSSG_CFG_OFFSET	0
117 #define MAC_INTERFACE_0		0x18
118 #define MAC_INTERFACE_1		0x1c
119 
120 #define ICSSG_CFG_RX_L2_G_EN	BIT(2)
121 
122 /* these are register offsets per PRU */
123 struct miig_rt_offsets {
124 	u32 mac0;
125 	u32 mac1;
126 	u32 ft1_start_len;
127 	u32 ft1_cfg;
128 	u32 ft1_slot_base;
129 	u32 ft3_slot_base;
130 	u32 ft3_p_base;
131 	u32 ft_rx_ptr;
132 	u32 rx_class_base;
133 	u32 rx_class_cfg1;
134 	u32 rx_class_cfg2;
135 	u32 rx_class_gates_base;
136 	u32 rx_green;
137 	u32 rx_rate_cfg_base;
138 	u32 rx_rate_src_sel0;
139 	u32 rx_rate_src_sel1;
140 	u32 tx_rate_cfg_base;
141 	u32 stat_base;
142 	u32 tx_hsr_tag;
143 	u32 tx_hsr_seq;
144 	u32 tx_vlan_type;
145 	u32 tx_vlan_ins;
146 };
147 
148 static struct miig_rt_offsets offs[] = {
149 	/* PRU0 */
150 	{
151 		0x8,
152 		0xc,
153 		0x80,
154 		0x84,
155 		0x88,
156 		0x108,
157 		0x308,
158 		0x408,
159 		0x40c,
160 		0x48c,
161 		0x490,
162 		0x494,
163 		0x4d4,
164 		0x4e4,
165 		0x504,
166 		0x508,
167 		0x50c,
168 		0x54c,
169 		0x63c,
170 		0x640,
171 		0x644,
172 		0x648,
173 	},
174 	/* PRU1 */
175 	{
176 		0x10,
177 		0x14,
178 		0x64c,
179 		0x650,
180 		0x654,
181 		0x6d4,
182 		0x8d4,
183 		0x9d4,
184 		0x9d8,
185 		0xa58,
186 		0xa5c,
187 		0xa60,
188 		0xaa0,
189 		0xab0,
190 		0xad0,
191 		0xad4,
192 		0xad8,
193 		0xb18,
194 		0xc08,
195 		0xc0c,
196 		0xc10,
197 		0xc14,
198 	},
199 };
200 
addr_to_da0(const u8 * addr)201 static inline u32 addr_to_da0(const u8 *addr)
202 {
203 	return (u32)(addr[0] | addr[1] << 8 |
204 		addr[2] << 16 | addr[3] << 24);
205 };
206 
addr_to_da1(const u8 * addr)207 static inline u32 addr_to_da1(const u8 *addr)
208 {
209 	return (u32)(addr[4] | addr[5] << 8);
210 };
211 
rx_class_ft1_set_start_len(struct regmap * miig_rt,int slice,u16 start,u8 len)212 static void rx_class_ft1_set_start_len(struct regmap *miig_rt, int slice,
213 				       u16 start, u8 len)
214 {
215 	u32 offset, val;
216 
217 	offset = offs[slice].ft1_start_len;
218 	val = FT1_LEN(len) | FT1_START(start);
219 	regmap_write(miig_rt, offset, val);
220 }
221 
rx_class_ft1_set_da(struct regmap * miig_rt,int slice,int n,const u8 * addr)222 static void rx_class_ft1_set_da(struct regmap *miig_rt, int slice,
223 				int n, const u8 *addr)
224 {
225 	u32 offset;
226 
227 	offset = FT1_N_REG(slice, n, FT1_DA0);
228 	regmap_write(miig_rt, offset, addr_to_da0(addr));
229 	offset = FT1_N_REG(slice, n, FT1_DA1);
230 	regmap_write(miig_rt, offset, addr_to_da1(addr));
231 }
232 
rx_class_ft1_set_da_mask(struct regmap * miig_rt,int slice,int n,const u8 * addr)233 static void rx_class_ft1_set_da_mask(struct regmap *miig_rt, int slice,
234 				     int n, const u8 *addr)
235 {
236 	u32 offset;
237 
238 	offset = FT1_N_REG(slice, n, FT1_DA0_MASK);
239 	regmap_write(miig_rt, offset, addr_to_da0(addr));
240 	offset = FT1_N_REG(slice, n, FT1_DA1_MASK);
241 	regmap_write(miig_rt, offset, addr_to_da1(addr));
242 }
243 
rx_class_ft1_cfg_set_type(struct regmap * miig_rt,int slice,int n,enum ft1_cfg_type type)244 static void rx_class_ft1_cfg_set_type(struct regmap *miig_rt, int slice, int n,
245 				      enum ft1_cfg_type type)
246 {
247 	u32 offset;
248 
249 	offset = offs[slice].ft1_cfg;
250 	regmap_update_bits(miig_rt, offset, FT1_CFG_MASK(n),
251 			   type << FT1_CFG_SHIFT(n));
252 }
253 
rx_class_sel_set_type(struct regmap * miig_rt,int slice,int n,enum rx_class_sel_type type)254 static void rx_class_sel_set_type(struct regmap *miig_rt, int slice, int n,
255 				  enum rx_class_sel_type type)
256 {
257 	u32 offset;
258 
259 	offset = offs[slice].rx_class_cfg1;
260 	regmap_update_bits(miig_rt, offset, RX_CLASS_SEL_MASK(n),
261 			   type << RX_CLASS_SEL_SHIFT(n));
262 }
263 
rx_class_set_and(struct regmap * miig_rt,int slice,int n,u32 data)264 static void rx_class_set_and(struct regmap *miig_rt, int slice, int n,
265 			     u32 data)
266 {
267 	u32 offset;
268 
269 	offset = RX_CLASS_N_REG(slice, n, RX_CLASS_AND_EN);
270 	regmap_write(miig_rt, offset, data);
271 }
272 
rx_class_set_or(struct regmap * miig_rt,int slice,int n,u32 data)273 static void rx_class_set_or(struct regmap *miig_rt, int slice, int n,
274 			    u32 data)
275 {
276 	u32 offset;
277 
278 	offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN);
279 	regmap_write(miig_rt, offset, data);
280 }
281 
icssg_class_set_host_mac_addr(struct regmap * miig_rt,u8 * mac)282 void icssg_class_set_host_mac_addr(struct regmap *miig_rt, u8 *mac)
283 {
284 	regmap_write(miig_rt, MAC_INTERFACE_0, addr_to_da0(mac));
285 	regmap_write(miig_rt, MAC_INTERFACE_1, addr_to_da1(mac));
286 }
287 
icssg_class_set_mac_addr(struct regmap * miig_rt,int slice,u8 * mac)288 void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac)
289 {
290 	regmap_write(miig_rt, offs[slice].mac0, addr_to_da0(mac));
291 	regmap_write(miig_rt, offs[slice].mac1, addr_to_da1(mac));
292 }
293 
icssg_class_disable_n(struct regmap * miig_rt,int slice,int n)294 void icssg_class_disable_n(struct regmap *miig_rt, int slice, int n)
295 {
296 	u32 data, offset;
297 
298 	/* AND_EN = 0 */
299 	rx_class_set_and(miig_rt, slice, n, 0);
300 	/* OR_EN = 0 */
301 	rx_class_set_or(miig_rt, slice, n, 0);
302 
303 	/* set CFG1 to OR */
304 	rx_class_sel_set_type(miig_rt, slice, n, RX_CLASS_SEL_TYPE_OR);
305 
306 	/* configure gate */
307 	offset = RX_CLASS_GATES_N_REG(slice, n);
308 	regmap_read(miig_rt, offset, &data);
309 	/* clear class_raw so we go through filters */
310 	data &= ~RX_CLASS_GATES_RAW_MASK;
311 	/* set allow and phase mask */
312 	data |= RX_CLASS_GATES_ALLOW_MASK | RX_CLASS_GATES_PHASE_MASK;
313 	regmap_write(miig_rt, offset, data);
314 }
315 
316 /* disable all RX traffic */
icssg_class_disable(struct regmap * miig_rt,int slice)317 void icssg_class_disable(struct regmap *miig_rt, int slice)
318 {
319 	int n;
320 
321 	/* Enable RX_L2_G */
322 	regmap_update_bits(miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_RX_L2_G_EN,
323 			   ICSSG_CFG_RX_L2_G_EN);
324 
325 	for (n = 0; n < ICSSG_NUM_CLASSIFIERS; n++)
326 		icssg_class_disable_n(miig_rt, slice, n);
327 
328 	/* FT1 Disabled */
329 	for (n = 0; n < ICSSG_NUM_FT1_SLOTS; n++) {
330 		u8 addr[] = { 0, 0, 0, 0, 0, 0, };
331 
332 		rx_class_ft1_cfg_set_type(miig_rt, slice, n,
333 					  FT1_CFG_TYPE_DISABLED);
334 		rx_class_ft1_set_da(miig_rt, slice, n, addr);
335 		rx_class_ft1_set_da_mask(miig_rt, slice, n, addr);
336 	}
337 
338 	/* clear CFG2 */
339 	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
340 }
341 
icssg_class_default(struct regmap * miig_rt,int slice,bool allmulti)342 void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti)
343 {
344 	u32 data;
345 
346 	/* defaults */
347 	icssg_class_disable(miig_rt, slice);
348 
349 	/* Setup Classifier */
350 	/* match on Broadcast or MAC_PRU address */
351 	data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P;
352 
353 	/* multicast? */
354 	if (allmulti)
355 		data |= RX_CLASS_FT_MC;
356 
357 	rx_class_set_or(miig_rt, slice, 0, data);
358 
359 	/* set CFG1 for OR_OR_AND for classifier */
360 	rx_class_sel_set_type(miig_rt, slice, 0,
361 			      RX_CLASS_SEL_TYPE_OR_OR_AND);
362 
363 	/* clear CFG2 */
364 	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
365 }
366 
367 /* required for SR2 for SAV check */
icssg_ft1_set_mac_addr(struct regmap * miig_rt,int slice,u8 * mac_addr)368 void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr)
369 {
370 	u8 mask_addr[] = { 0, 0, 0, 0, 0, 0, };
371 
372 	rx_class_ft1_set_start_len(miig_rt, slice, 6, 6);
373 	rx_class_ft1_set_da(miig_rt, slice, 0, mac_addr);
374 	rx_class_ft1_set_da_mask(miig_rt, slice, 0, mask_addr);
375 	rx_class_ft1_cfg_set_type(miig_rt, slice, 0, FT1_CFG_TYPE_EQ);
376 }
377