1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Texas Instruments N-Port Ethernet Switch Address Lookup Engine
4 *
5 * Copyright (C) 2012 Texas Instruments
6 *
7 */
8 #include <linux/bitmap.h>
9 #include <linux/if_vlan.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/seq_file.h>
14 #include <linux/slab.h>
15 #include <linux/err.h>
16 #include <linux/io.h>
17 #include <linux/stat.h>
18 #include <linux/sysfs.h>
19 #include <linux/etherdevice.h>
20
21 #include "cpsw_ale.h"
22
23 #define BITMASK(bits) (BIT(bits) - 1)
24
25 #define ALE_VERSION_MAJOR(rev, mask) (((rev) >> 8) & (mask))
26 #define ALE_VERSION_MINOR(rev) (rev & 0xff)
27 #define ALE_VERSION_1R3 0x0103
28 #define ALE_VERSION_1R4 0x0104
29
30 /* ALE Registers */
31 #define ALE_IDVER 0x00
32 #define ALE_STATUS 0x04
33 #define ALE_CONTROL 0x08
34 #define ALE_PRESCALE 0x10
35 #define ALE_AGING_TIMER 0x14
36 #define ALE_UNKNOWNVLAN 0x18
37 #define ALE_TABLE_CONTROL 0x20
38 #define ALE_TABLE 0x34
39 #define ALE_PORTCTL 0x40
40
41 /* ALE NetCP NU switch specific Registers */
42 #define ALE_UNKNOWNVLAN_MEMBER 0x90
43 #define ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD 0x94
44 #define ALE_UNKNOWNVLAN_REG_MCAST_FLOOD 0x98
45 #define ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS 0x9C
46 #define ALE_VLAN_MASK_MUX(reg) (0xc0 + (0x4 * (reg)))
47
48 #define AM65_CPSW_ALE_THREAD_DEF_REG 0x134
49
50 /* ALE_AGING_TIMER */
51 #define ALE_AGING_TIMER_MASK GENMASK(23, 0)
52
53 /**
54 * struct ale_entry_fld - The ALE tbl entry field description
55 * @start_bit: field start bit
56 * @num_bits: field bit length
57 * @flags: field flags
58 */
59 struct ale_entry_fld {
60 u8 start_bit;
61 u8 num_bits;
62 u8 flags;
63 };
64
65 enum {
66 CPSW_ALE_F_STATUS_REG = BIT(0), /* Status register present */
67 CPSW_ALE_F_HW_AUTOAGING = BIT(1), /* HW auto aging */
68
69 CPSW_ALE_F_COUNT
70 };
71
72 /**
73 * struct ale_dev_id - The ALE version/SoC specific configuration
74 * @dev_id: ALE version/SoC id
75 * @features: features supported by ALE
76 * @tbl_entries: number of ALE entries
77 * @major_ver_mask: mask of ALE Major Version Value in ALE_IDVER reg.
78 * @nu_switch_ale: NU Switch ALE
79 * @vlan_entry_tbl: ALE vlan entry fields description tbl
80 */
81 struct cpsw_ale_dev_id {
82 const char *dev_id;
83 u32 features;
84 u32 tbl_entries;
85 u32 major_ver_mask;
86 bool nu_switch_ale;
87 const struct ale_entry_fld *vlan_entry_tbl;
88 };
89
90 #define ALE_TABLE_WRITE BIT(31)
91
92 #define ALE_TYPE_FREE 0
93 #define ALE_TYPE_ADDR 1
94 #define ALE_TYPE_VLAN 2
95 #define ALE_TYPE_VLAN_ADDR 3
96
97 #define ALE_UCAST_PERSISTANT 0
98 #define ALE_UCAST_UNTOUCHED 1
99 #define ALE_UCAST_OUI 2
100 #define ALE_UCAST_TOUCHED 3
101
102 #define ALE_TABLE_SIZE_MULTIPLIER 1024
103 #define ALE_STATUS_SIZE_MASK 0x1f
104
cpsw_ale_get_field(u32 * ale_entry,u32 start,u32 bits)105 static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
106 {
107 int idx, idx2;
108 u32 hi_val = 0;
109
110 idx = start / 32;
111 idx2 = (start + bits - 1) / 32;
112 /* Check if bits to be fetched exceed a word */
113 if (idx != idx2) {
114 idx2 = 2 - idx2; /* flip */
115 hi_val = ale_entry[idx2] << ((idx2 * 32) - start);
116 }
117 start -= idx * 32;
118 idx = 2 - idx; /* flip */
119 return (hi_val + (ale_entry[idx] >> start)) & BITMASK(bits);
120 }
121
cpsw_ale_set_field(u32 * ale_entry,u32 start,u32 bits,u32 value)122 static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
123 u32 value)
124 {
125 int idx, idx2;
126
127 value &= BITMASK(bits);
128 idx = start / 32;
129 idx2 = (start + bits - 1) / 32;
130 /* Check if bits to be set exceed a word */
131 if (idx != idx2) {
132 idx2 = 2 - idx2; /* flip */
133 ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32)));
134 ale_entry[idx2] |= (value >> ((idx2 * 32) - start));
135 }
136 start -= idx * 32;
137 idx = 2 - idx; /* flip */
138 ale_entry[idx] &= ~(BITMASK(bits) << start);
139 ale_entry[idx] |= (value << start);
140 }
141
142 #define DEFINE_ALE_FIELD(name, start, bits) \
143 static inline int cpsw_ale_get_##name(u32 *ale_entry) \
144 { \
145 return cpsw_ale_get_field(ale_entry, start, bits); \
146 } \
147 static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value) \
148 { \
149 cpsw_ale_set_field(ale_entry, start, bits, value); \
150 }
151
152 #define DEFINE_ALE_FIELD1(name, start) \
153 static inline int cpsw_ale_get_##name(u32 *ale_entry, u32 bits) \
154 { \
155 return cpsw_ale_get_field(ale_entry, start, bits); \
156 } \
157 static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value, \
158 u32 bits) \
159 { \
160 cpsw_ale_set_field(ale_entry, start, bits, value); \
161 }
162
163 enum {
164 ALE_ENT_VID_MEMBER_LIST = 0,
165 ALE_ENT_VID_UNREG_MCAST_MSK,
166 ALE_ENT_VID_REG_MCAST_MSK,
167 ALE_ENT_VID_FORCE_UNTAGGED_MSK,
168 ALE_ENT_VID_UNREG_MCAST_IDX,
169 ALE_ENT_VID_REG_MCAST_IDX,
170 ALE_ENT_VID_LAST,
171 };
172
173 #define ALE_FLD_ALLOWED BIT(0)
174 #define ALE_FLD_SIZE_PORT_MASK_BITS BIT(1)
175 #define ALE_FLD_SIZE_PORT_NUM_BITS BIT(2)
176
177 #define ALE_ENTRY_FLD(id, start, bits) \
178 [id] = { \
179 .start_bit = start, \
180 .num_bits = bits, \
181 .flags = ALE_FLD_ALLOWED, \
182 }
183
184 #define ALE_ENTRY_FLD_DYN_MSK_SIZE(id, start) \
185 [id] = { \
186 .start_bit = start, \
187 .num_bits = 0, \
188 .flags = ALE_FLD_ALLOWED | \
189 ALE_FLD_SIZE_PORT_MASK_BITS, \
190 }
191
192 /* dm814x, am3/am4/am5, k2hk */
193 static const struct ale_entry_fld vlan_entry_cpsw[ALE_ENT_VID_LAST] = {
194 ALE_ENTRY_FLD(ALE_ENT_VID_MEMBER_LIST, 0, 3),
195 ALE_ENTRY_FLD(ALE_ENT_VID_UNREG_MCAST_MSK, 8, 3),
196 ALE_ENTRY_FLD(ALE_ENT_VID_REG_MCAST_MSK, 16, 3),
197 ALE_ENTRY_FLD(ALE_ENT_VID_FORCE_UNTAGGED_MSK, 24, 3),
198 };
199
200 /* k2e/k2l, k3 am65/j721e cpsw2g */
201 static const struct ale_entry_fld vlan_entry_nu[ALE_ENT_VID_LAST] = {
202 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_MEMBER_LIST, 0),
203 ALE_ENTRY_FLD(ALE_ENT_VID_UNREG_MCAST_IDX, 20, 3),
204 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_FORCE_UNTAGGED_MSK, 24),
205 ALE_ENTRY_FLD(ALE_ENT_VID_REG_MCAST_IDX, 44, 3),
206 };
207
208 /* K3 j721e/j7200 cpsw9g/5g, am64x cpsw3g */
209 static const struct ale_entry_fld vlan_entry_k3_cpswxg[] = {
210 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_MEMBER_LIST, 0),
211 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_UNREG_MCAST_MSK, 12),
212 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_FORCE_UNTAGGED_MSK, 24),
213 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_REG_MCAST_MSK, 36),
214 };
215
216 DEFINE_ALE_FIELD(entry_type, 60, 2)
217 DEFINE_ALE_FIELD(vlan_id, 48, 12)
218 DEFINE_ALE_FIELD(mcast_state, 62, 2)
219 DEFINE_ALE_FIELD1(port_mask, 66)
220 DEFINE_ALE_FIELD(super, 65, 1)
221 DEFINE_ALE_FIELD(ucast_type, 62, 2)
222 DEFINE_ALE_FIELD1(port_num, 66)
223 DEFINE_ALE_FIELD(blocked, 65, 1)
224 DEFINE_ALE_FIELD(secure, 64, 1)
225 DEFINE_ALE_FIELD(mcast, 40, 1)
226
227 #define NU_VLAN_UNREG_MCAST_IDX 1
228
cpsw_ale_entry_get_fld(struct cpsw_ale * ale,u32 * ale_entry,const struct ale_entry_fld * entry_tbl,int fld_id)229 static int cpsw_ale_entry_get_fld(struct cpsw_ale *ale,
230 u32 *ale_entry,
231 const struct ale_entry_fld *entry_tbl,
232 int fld_id)
233 {
234 const struct ale_entry_fld *entry_fld;
235 u32 bits;
236
237 if (!ale || !ale_entry)
238 return -EINVAL;
239
240 entry_fld = &entry_tbl[fld_id];
241 if (!(entry_fld->flags & ALE_FLD_ALLOWED)) {
242 dev_err(ale->params.dev, "get: wrong ale fld id %d\n", fld_id);
243 return -ENOENT;
244 }
245
246 bits = entry_fld->num_bits;
247 if (entry_fld->flags & ALE_FLD_SIZE_PORT_MASK_BITS)
248 bits = ale->port_mask_bits;
249
250 return cpsw_ale_get_field(ale_entry, entry_fld->start_bit, bits);
251 }
252
cpsw_ale_entry_set_fld(struct cpsw_ale * ale,u32 * ale_entry,const struct ale_entry_fld * entry_tbl,int fld_id,u32 value)253 static void cpsw_ale_entry_set_fld(struct cpsw_ale *ale,
254 u32 *ale_entry,
255 const struct ale_entry_fld *entry_tbl,
256 int fld_id,
257 u32 value)
258 {
259 const struct ale_entry_fld *entry_fld;
260 u32 bits;
261
262 if (!ale || !ale_entry)
263 return;
264
265 entry_fld = &entry_tbl[fld_id];
266 if (!(entry_fld->flags & ALE_FLD_ALLOWED)) {
267 dev_err(ale->params.dev, "set: wrong ale fld id %d\n", fld_id);
268 return;
269 }
270
271 bits = entry_fld->num_bits;
272 if (entry_fld->flags & ALE_FLD_SIZE_PORT_MASK_BITS)
273 bits = ale->port_mask_bits;
274
275 cpsw_ale_set_field(ale_entry, entry_fld->start_bit, bits, value);
276 }
277
cpsw_ale_vlan_get_fld(struct cpsw_ale * ale,u32 * ale_entry,int fld_id)278 static int cpsw_ale_vlan_get_fld(struct cpsw_ale *ale,
279 u32 *ale_entry,
280 int fld_id)
281 {
282 return cpsw_ale_entry_get_fld(ale, ale_entry,
283 ale->vlan_entry_tbl, fld_id);
284 }
285
cpsw_ale_vlan_set_fld(struct cpsw_ale * ale,u32 * ale_entry,int fld_id,u32 value)286 static void cpsw_ale_vlan_set_fld(struct cpsw_ale *ale,
287 u32 *ale_entry,
288 int fld_id,
289 u32 value)
290 {
291 cpsw_ale_entry_set_fld(ale, ale_entry,
292 ale->vlan_entry_tbl, fld_id, value);
293 }
294
295 /* The MAC address field in the ALE entry cannot be macroized as above */
cpsw_ale_get_addr(u32 * ale_entry,u8 * addr)296 static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr)
297 {
298 int i;
299
300 for (i = 0; i < 6; i++)
301 addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8);
302 }
303
cpsw_ale_set_addr(u32 * ale_entry,const u8 * addr)304 static inline void cpsw_ale_set_addr(u32 *ale_entry, const u8 *addr)
305 {
306 int i;
307
308 for (i = 0; i < 6; i++)
309 cpsw_ale_set_field(ale_entry, 40 - 8*i, 8, addr[i]);
310 }
311
cpsw_ale_read(struct cpsw_ale * ale,int idx,u32 * ale_entry)312 static int cpsw_ale_read(struct cpsw_ale *ale, int idx, u32 *ale_entry)
313 {
314 int i;
315
316 WARN_ON(idx > ale->params.ale_entries);
317
318 writel_relaxed(idx, ale->params.ale_regs + ALE_TABLE_CONTROL);
319
320 for (i = 0; i < ALE_ENTRY_WORDS; i++)
321 ale_entry[i] = readl_relaxed(ale->params.ale_regs +
322 ALE_TABLE + 4 * i);
323
324 return idx;
325 }
326
cpsw_ale_write(struct cpsw_ale * ale,int idx,u32 * ale_entry)327 static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry)
328 {
329 int i;
330
331 WARN_ON(idx > ale->params.ale_entries);
332
333 for (i = 0; i < ALE_ENTRY_WORDS; i++)
334 writel_relaxed(ale_entry[i], ale->params.ale_regs +
335 ALE_TABLE + 4 * i);
336
337 writel_relaxed(idx | ALE_TABLE_WRITE, ale->params.ale_regs +
338 ALE_TABLE_CONTROL);
339
340 return idx;
341 }
342
cpsw_ale_match_addr(struct cpsw_ale * ale,const u8 * addr,u16 vid)343 static int cpsw_ale_match_addr(struct cpsw_ale *ale, const u8 *addr, u16 vid)
344 {
345 u32 ale_entry[ALE_ENTRY_WORDS];
346 int type, idx;
347
348 for (idx = 0; idx < ale->params.ale_entries; idx++) {
349 u8 entry_addr[6];
350
351 cpsw_ale_read(ale, idx, ale_entry);
352 type = cpsw_ale_get_entry_type(ale_entry);
353 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
354 continue;
355 if (cpsw_ale_get_vlan_id(ale_entry) != vid)
356 continue;
357 cpsw_ale_get_addr(ale_entry, entry_addr);
358 if (ether_addr_equal(entry_addr, addr))
359 return idx;
360 }
361 return -ENOENT;
362 }
363
cpsw_ale_match_vlan(struct cpsw_ale * ale,u16 vid)364 static int cpsw_ale_match_vlan(struct cpsw_ale *ale, u16 vid)
365 {
366 u32 ale_entry[ALE_ENTRY_WORDS];
367 int type, idx;
368
369 for (idx = 0; idx < ale->params.ale_entries; idx++) {
370 cpsw_ale_read(ale, idx, ale_entry);
371 type = cpsw_ale_get_entry_type(ale_entry);
372 if (type != ALE_TYPE_VLAN)
373 continue;
374 if (cpsw_ale_get_vlan_id(ale_entry) == vid)
375 return idx;
376 }
377 return -ENOENT;
378 }
379
cpsw_ale_match_free(struct cpsw_ale * ale)380 static int cpsw_ale_match_free(struct cpsw_ale *ale)
381 {
382 u32 ale_entry[ALE_ENTRY_WORDS];
383 int type, idx;
384
385 for (idx = 0; idx < ale->params.ale_entries; idx++) {
386 cpsw_ale_read(ale, idx, ale_entry);
387 type = cpsw_ale_get_entry_type(ale_entry);
388 if (type == ALE_TYPE_FREE)
389 return idx;
390 }
391 return -ENOENT;
392 }
393
cpsw_ale_find_ageable(struct cpsw_ale * ale)394 static int cpsw_ale_find_ageable(struct cpsw_ale *ale)
395 {
396 u32 ale_entry[ALE_ENTRY_WORDS];
397 int type, idx;
398
399 for (idx = 0; idx < ale->params.ale_entries; idx++) {
400 cpsw_ale_read(ale, idx, ale_entry);
401 type = cpsw_ale_get_entry_type(ale_entry);
402 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
403 continue;
404 if (cpsw_ale_get_mcast(ale_entry))
405 continue;
406 type = cpsw_ale_get_ucast_type(ale_entry);
407 if (type != ALE_UCAST_PERSISTANT &&
408 type != ALE_UCAST_OUI)
409 return idx;
410 }
411 return -ENOENT;
412 }
413
cpsw_ale_flush_mcast(struct cpsw_ale * ale,u32 * ale_entry,int port_mask)414 static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry,
415 int port_mask)
416 {
417 int mask;
418
419 mask = cpsw_ale_get_port_mask(ale_entry,
420 ale->port_mask_bits);
421 if ((mask & port_mask) == 0)
422 return; /* ports dont intersect, not interested */
423 mask &= ~port_mask;
424
425 /* free if only remaining port is host port */
426 if (mask)
427 cpsw_ale_set_port_mask(ale_entry, mask,
428 ale->port_mask_bits);
429 else
430 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
431 }
432
cpsw_ale_flush_multicast(struct cpsw_ale * ale,int port_mask,int vid)433 int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid)
434 {
435 u32 ale_entry[ALE_ENTRY_WORDS];
436 int ret, idx;
437
438 for (idx = 0; idx < ale->params.ale_entries; idx++) {
439 cpsw_ale_read(ale, idx, ale_entry);
440 ret = cpsw_ale_get_entry_type(ale_entry);
441 if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR)
442 continue;
443
444 /* if vid passed is -1 then remove all multicast entry from
445 * the table irrespective of vlan id, if a valid vlan id is
446 * passed then remove only multicast added to that vlan id.
447 * if vlan id doesn't match then move on to next entry.
448 */
449 if (vid != -1 && cpsw_ale_get_vlan_id(ale_entry) != vid)
450 continue;
451
452 if (cpsw_ale_get_mcast(ale_entry)) {
453 u8 addr[6];
454
455 if (cpsw_ale_get_super(ale_entry))
456 continue;
457
458 cpsw_ale_get_addr(ale_entry, addr);
459 if (!is_broadcast_ether_addr(addr))
460 cpsw_ale_flush_mcast(ale, ale_entry, port_mask);
461 }
462
463 cpsw_ale_write(ale, idx, ale_entry);
464 }
465 return 0;
466 }
467
cpsw_ale_set_vlan_entry_type(u32 * ale_entry,int flags,u16 vid)468 static inline void cpsw_ale_set_vlan_entry_type(u32 *ale_entry,
469 int flags, u16 vid)
470 {
471 if (flags & ALE_VLAN) {
472 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN_ADDR);
473 cpsw_ale_set_vlan_id(ale_entry, vid);
474 } else {
475 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
476 }
477 }
478
cpsw_ale_add_ucast(struct cpsw_ale * ale,const u8 * addr,int port,int flags,u16 vid)479 int cpsw_ale_add_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
480 int flags, u16 vid)
481 {
482 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
483 int idx;
484
485 cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);
486
487 cpsw_ale_set_addr(ale_entry, addr);
488 cpsw_ale_set_ucast_type(ale_entry, ALE_UCAST_PERSISTANT);
489 cpsw_ale_set_secure(ale_entry, (flags & ALE_SECURE) ? 1 : 0);
490 cpsw_ale_set_blocked(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0);
491 cpsw_ale_set_port_num(ale_entry, port, ale->port_num_bits);
492
493 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
494 if (idx < 0)
495 idx = cpsw_ale_match_free(ale);
496 if (idx < 0)
497 idx = cpsw_ale_find_ageable(ale);
498 if (idx < 0)
499 return -ENOMEM;
500
501 cpsw_ale_write(ale, idx, ale_entry);
502 return 0;
503 }
504
cpsw_ale_del_ucast(struct cpsw_ale * ale,const u8 * addr,int port,int flags,u16 vid)505 int cpsw_ale_del_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
506 int flags, u16 vid)
507 {
508 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
509 int idx;
510
511 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
512 if (idx < 0)
513 return -ENOENT;
514
515 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
516 cpsw_ale_write(ale, idx, ale_entry);
517 return 0;
518 }
519
cpsw_ale_add_mcast(struct cpsw_ale * ale,const u8 * addr,int port_mask,int flags,u16 vid,int mcast_state)520 int cpsw_ale_add_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
521 int flags, u16 vid, int mcast_state)
522 {
523 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
524 int idx, mask;
525
526 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
527 if (idx >= 0)
528 cpsw_ale_read(ale, idx, ale_entry);
529
530 cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);
531
532 cpsw_ale_set_addr(ale_entry, addr);
533 cpsw_ale_set_super(ale_entry, (flags & ALE_SUPER) ? 1 : 0);
534 cpsw_ale_set_mcast_state(ale_entry, mcast_state);
535
536 mask = cpsw_ale_get_port_mask(ale_entry,
537 ale->port_mask_bits);
538 port_mask |= mask;
539 cpsw_ale_set_port_mask(ale_entry, port_mask,
540 ale->port_mask_bits);
541
542 if (idx < 0)
543 idx = cpsw_ale_match_free(ale);
544 if (idx < 0)
545 idx = cpsw_ale_find_ageable(ale);
546 if (idx < 0)
547 return -ENOMEM;
548
549 cpsw_ale_write(ale, idx, ale_entry);
550 return 0;
551 }
552
cpsw_ale_del_mcast(struct cpsw_ale * ale,const u8 * addr,int port_mask,int flags,u16 vid)553 int cpsw_ale_del_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
554 int flags, u16 vid)
555 {
556 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
557 int mcast_members = 0;
558 int idx;
559
560 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
561 if (idx < 0)
562 return -ENOENT;
563
564 cpsw_ale_read(ale, idx, ale_entry);
565
566 if (port_mask) {
567 mcast_members = cpsw_ale_get_port_mask(ale_entry,
568 ale->port_mask_bits);
569 mcast_members &= ~port_mask;
570 }
571
572 if (mcast_members)
573 cpsw_ale_set_port_mask(ale_entry, mcast_members,
574 ale->port_mask_bits);
575 else
576 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
577
578 cpsw_ale_write(ale, idx, ale_entry);
579 return 0;
580 }
581
582 /* ALE NetCP NU switch specific vlan functions */
cpsw_ale_set_vlan_mcast(struct cpsw_ale * ale,u32 * ale_entry,int reg_mcast,int unreg_mcast)583 static void cpsw_ale_set_vlan_mcast(struct cpsw_ale *ale, u32 *ale_entry,
584 int reg_mcast, int unreg_mcast)
585 {
586 int idx;
587
588 /* Set VLAN registered multicast flood mask */
589 idx = cpsw_ale_vlan_get_fld(ale, ale_entry,
590 ALE_ENT_VID_REG_MCAST_IDX);
591 writel(reg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
592
593 /* Set VLAN unregistered multicast flood mask */
594 idx = cpsw_ale_vlan_get_fld(ale, ale_entry,
595 ALE_ENT_VID_UNREG_MCAST_IDX);
596 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
597 }
598
cpsw_ale_set_vlan_untag(struct cpsw_ale * ale,u32 * ale_entry,u16 vid,int untag_mask)599 static void cpsw_ale_set_vlan_untag(struct cpsw_ale *ale, u32 *ale_entry,
600 u16 vid, int untag_mask)
601 {
602 cpsw_ale_vlan_set_fld(ale, ale_entry,
603 ALE_ENT_VID_FORCE_UNTAGGED_MSK,
604 untag_mask);
605 if (untag_mask & ALE_PORT_HOST)
606 bitmap_set(ale->p0_untag_vid_mask, vid, 1);
607 else
608 bitmap_clear(ale->p0_untag_vid_mask, vid, 1);
609 }
610
cpsw_ale_add_vlan(struct cpsw_ale * ale,u16 vid,int port_mask,int untag,int reg_mcast,int unreg_mcast)611 int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port_mask, int untag,
612 int reg_mcast, int unreg_mcast)
613 {
614 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
615 int idx;
616
617 idx = cpsw_ale_match_vlan(ale, vid);
618 if (idx >= 0)
619 cpsw_ale_read(ale, idx, ale_entry);
620
621 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN);
622 cpsw_ale_set_vlan_id(ale_entry, vid);
623 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, untag);
624
625 if (!ale->params.nu_switch_ale) {
626 cpsw_ale_vlan_set_fld(ale, ale_entry,
627 ALE_ENT_VID_REG_MCAST_MSK, reg_mcast);
628 cpsw_ale_vlan_set_fld(ale, ale_entry,
629 ALE_ENT_VID_UNREG_MCAST_MSK, unreg_mcast);
630 } else {
631 cpsw_ale_vlan_set_fld(ale, ale_entry,
632 ALE_ENT_VID_UNREG_MCAST_IDX,
633 NU_VLAN_UNREG_MCAST_IDX);
634 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast, unreg_mcast);
635 }
636
637 cpsw_ale_vlan_set_fld(ale, ale_entry,
638 ALE_ENT_VID_MEMBER_LIST, port_mask);
639
640 if (idx < 0)
641 idx = cpsw_ale_match_free(ale);
642 if (idx < 0)
643 idx = cpsw_ale_find_ageable(ale);
644 if (idx < 0)
645 return -ENOMEM;
646
647 cpsw_ale_write(ale, idx, ale_entry);
648 return 0;
649 }
650
cpsw_ale_del_vlan_modify(struct cpsw_ale * ale,u32 * ale_entry,u16 vid,int port_mask)651 static void cpsw_ale_del_vlan_modify(struct cpsw_ale *ale, u32 *ale_entry,
652 u16 vid, int port_mask)
653 {
654 int reg_mcast, unreg_mcast;
655 int members, untag;
656
657 members = cpsw_ale_vlan_get_fld(ale, ale_entry,
658 ALE_ENT_VID_MEMBER_LIST);
659 members &= ~port_mask;
660 if (!members) {
661 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
662 return;
663 }
664
665 untag = cpsw_ale_vlan_get_fld(ale, ale_entry,
666 ALE_ENT_VID_FORCE_UNTAGGED_MSK);
667 reg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry,
668 ALE_ENT_VID_REG_MCAST_MSK);
669 unreg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry,
670 ALE_ENT_VID_UNREG_MCAST_MSK);
671 untag &= members;
672 reg_mcast &= members;
673 unreg_mcast &= members;
674
675 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, untag);
676
677 if (!ale->params.nu_switch_ale) {
678 cpsw_ale_vlan_set_fld(ale, ale_entry,
679 ALE_ENT_VID_REG_MCAST_MSK, reg_mcast);
680 cpsw_ale_vlan_set_fld(ale, ale_entry,
681 ALE_ENT_VID_UNREG_MCAST_MSK, unreg_mcast);
682 } else {
683 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast,
684 unreg_mcast);
685 }
686 cpsw_ale_vlan_set_fld(ale, ale_entry,
687 ALE_ENT_VID_MEMBER_LIST, members);
688 }
689
cpsw_ale_del_vlan(struct cpsw_ale * ale,u16 vid,int port_mask)690 int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask)
691 {
692 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
693 int idx;
694
695 idx = cpsw_ale_match_vlan(ale, vid);
696 if (idx < 0)
697 return -ENOENT;
698
699 cpsw_ale_read(ale, idx, ale_entry);
700
701 if (port_mask) {
702 cpsw_ale_del_vlan_modify(ale, ale_entry, vid, port_mask);
703 } else {
704 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, 0);
705 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
706 }
707
708 cpsw_ale_write(ale, idx, ale_entry);
709
710 return 0;
711 }
712
cpsw_ale_vlan_add_modify(struct cpsw_ale * ale,u16 vid,int port_mask,int untag_mask,int reg_mask,int unreg_mask)713 int cpsw_ale_vlan_add_modify(struct cpsw_ale *ale, u16 vid, int port_mask,
714 int untag_mask, int reg_mask, int unreg_mask)
715 {
716 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
717 int reg_mcast_members, unreg_mcast_members;
718 int vlan_members, untag_members;
719 int idx, ret = 0;
720
721 idx = cpsw_ale_match_vlan(ale, vid);
722 if (idx >= 0)
723 cpsw_ale_read(ale, idx, ale_entry);
724
725 vlan_members = cpsw_ale_vlan_get_fld(ale, ale_entry,
726 ALE_ENT_VID_MEMBER_LIST);
727 reg_mcast_members = cpsw_ale_vlan_get_fld(ale, ale_entry,
728 ALE_ENT_VID_REG_MCAST_MSK);
729 unreg_mcast_members =
730 cpsw_ale_vlan_get_fld(ale, ale_entry,
731 ALE_ENT_VID_UNREG_MCAST_MSK);
732 untag_members = cpsw_ale_vlan_get_fld(ale, ale_entry,
733 ALE_ENT_VID_FORCE_UNTAGGED_MSK);
734
735 vlan_members |= port_mask;
736 untag_members = (untag_members & ~port_mask) | untag_mask;
737 reg_mcast_members = (reg_mcast_members & ~port_mask) | reg_mask;
738 unreg_mcast_members = (unreg_mcast_members & ~port_mask) | unreg_mask;
739
740 ret = cpsw_ale_add_vlan(ale, vid, vlan_members, untag_members,
741 reg_mcast_members, unreg_mcast_members);
742 if (ret) {
743 dev_err(ale->params.dev, "Unable to add vlan\n");
744 return ret;
745 }
746 dev_dbg(ale->params.dev, "port mask 0x%x untag 0x%x\n", vlan_members,
747 untag_mask);
748
749 return ret;
750 }
751
cpsw_ale_set_unreg_mcast(struct cpsw_ale * ale,int unreg_mcast_mask,bool add)752 void cpsw_ale_set_unreg_mcast(struct cpsw_ale *ale, int unreg_mcast_mask,
753 bool add)
754 {
755 u32 ale_entry[ALE_ENTRY_WORDS];
756 int unreg_members = 0;
757 int type, idx;
758
759 for (idx = 0; idx < ale->params.ale_entries; idx++) {
760 cpsw_ale_read(ale, idx, ale_entry);
761 type = cpsw_ale_get_entry_type(ale_entry);
762 if (type != ALE_TYPE_VLAN)
763 continue;
764
765 unreg_members =
766 cpsw_ale_vlan_get_fld(ale, ale_entry,
767 ALE_ENT_VID_UNREG_MCAST_MSK);
768 if (add)
769 unreg_members |= unreg_mcast_mask;
770 else
771 unreg_members &= ~unreg_mcast_mask;
772 cpsw_ale_vlan_set_fld(ale, ale_entry,
773 ALE_ENT_VID_UNREG_MCAST_MSK,
774 unreg_members);
775 cpsw_ale_write(ale, idx, ale_entry);
776 }
777 }
778
cpsw_ale_vlan_set_unreg_mcast(struct cpsw_ale * ale,u32 * ale_entry,int allmulti)779 static void cpsw_ale_vlan_set_unreg_mcast(struct cpsw_ale *ale, u32 *ale_entry,
780 int allmulti)
781 {
782 int unreg_mcast;
783
784 unreg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry,
785 ALE_ENT_VID_UNREG_MCAST_MSK);
786 if (allmulti)
787 unreg_mcast |= ALE_PORT_HOST;
788 else
789 unreg_mcast &= ~ALE_PORT_HOST;
790
791 cpsw_ale_vlan_set_fld(ale, ale_entry,
792 ALE_ENT_VID_UNREG_MCAST_MSK, unreg_mcast);
793 }
794
795 static void
cpsw_ale_vlan_set_unreg_mcast_idx(struct cpsw_ale * ale,u32 * ale_entry,int allmulti)796 cpsw_ale_vlan_set_unreg_mcast_idx(struct cpsw_ale *ale, u32 *ale_entry,
797 int allmulti)
798 {
799 int unreg_mcast;
800 int idx;
801
802 idx = cpsw_ale_vlan_get_fld(ale, ale_entry,
803 ALE_ENT_VID_UNREG_MCAST_IDX);
804
805 unreg_mcast = readl(ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
806
807 if (allmulti)
808 unreg_mcast |= ALE_PORT_HOST;
809 else
810 unreg_mcast &= ~ALE_PORT_HOST;
811
812 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
813 }
814
cpsw_ale_set_allmulti(struct cpsw_ale * ale,int allmulti,int port)815 void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti, int port)
816 {
817 u32 ale_entry[ALE_ENTRY_WORDS];
818 int type, idx;
819
820 for (idx = 0; idx < ale->params.ale_entries; idx++) {
821 int vlan_members;
822
823 cpsw_ale_read(ale, idx, ale_entry);
824 type = cpsw_ale_get_entry_type(ale_entry);
825 if (type != ALE_TYPE_VLAN)
826 continue;
827
828 vlan_members = cpsw_ale_vlan_get_fld(ale, ale_entry,
829 ALE_ENT_VID_MEMBER_LIST);
830
831 if (port != -1 && !(vlan_members & BIT(port)))
832 continue;
833
834 if (!ale->params.nu_switch_ale)
835 cpsw_ale_vlan_set_unreg_mcast(ale, ale_entry, allmulti);
836 else
837 cpsw_ale_vlan_set_unreg_mcast_idx(ale, ale_entry,
838 allmulti);
839
840 cpsw_ale_write(ale, idx, ale_entry);
841 }
842 }
843
844 struct ale_control_info {
845 const char *name;
846 int offset, port_offset;
847 int shift, port_shift;
848 int bits;
849 };
850
851 static struct ale_control_info ale_controls[ALE_NUM_CONTROLS] = {
852 [ALE_ENABLE] = {
853 .name = "enable",
854 .offset = ALE_CONTROL,
855 .port_offset = 0,
856 .shift = 31,
857 .port_shift = 0,
858 .bits = 1,
859 },
860 [ALE_CLEAR] = {
861 .name = "clear",
862 .offset = ALE_CONTROL,
863 .port_offset = 0,
864 .shift = 30,
865 .port_shift = 0,
866 .bits = 1,
867 },
868 [ALE_AGEOUT] = {
869 .name = "ageout",
870 .offset = ALE_CONTROL,
871 .port_offset = 0,
872 .shift = 29,
873 .port_shift = 0,
874 .bits = 1,
875 },
876 [ALE_P0_UNI_FLOOD] = {
877 .name = "port0_unicast_flood",
878 .offset = ALE_CONTROL,
879 .port_offset = 0,
880 .shift = 8,
881 .port_shift = 0,
882 .bits = 1,
883 },
884 [ALE_VLAN_NOLEARN] = {
885 .name = "vlan_nolearn",
886 .offset = ALE_CONTROL,
887 .port_offset = 0,
888 .shift = 7,
889 .port_shift = 0,
890 .bits = 1,
891 },
892 [ALE_NO_PORT_VLAN] = {
893 .name = "no_port_vlan",
894 .offset = ALE_CONTROL,
895 .port_offset = 0,
896 .shift = 6,
897 .port_shift = 0,
898 .bits = 1,
899 },
900 [ALE_OUI_DENY] = {
901 .name = "oui_deny",
902 .offset = ALE_CONTROL,
903 .port_offset = 0,
904 .shift = 5,
905 .port_shift = 0,
906 .bits = 1,
907 },
908 [ALE_BYPASS] = {
909 .name = "bypass",
910 .offset = ALE_CONTROL,
911 .port_offset = 0,
912 .shift = 4,
913 .port_shift = 0,
914 .bits = 1,
915 },
916 [ALE_RATE_LIMIT_TX] = {
917 .name = "rate_limit_tx",
918 .offset = ALE_CONTROL,
919 .port_offset = 0,
920 .shift = 3,
921 .port_shift = 0,
922 .bits = 1,
923 },
924 [ALE_VLAN_AWARE] = {
925 .name = "vlan_aware",
926 .offset = ALE_CONTROL,
927 .port_offset = 0,
928 .shift = 2,
929 .port_shift = 0,
930 .bits = 1,
931 },
932 [ALE_AUTH_ENABLE] = {
933 .name = "auth_enable",
934 .offset = ALE_CONTROL,
935 .port_offset = 0,
936 .shift = 1,
937 .port_shift = 0,
938 .bits = 1,
939 },
940 [ALE_RATE_LIMIT] = {
941 .name = "rate_limit",
942 .offset = ALE_CONTROL,
943 .port_offset = 0,
944 .shift = 0,
945 .port_shift = 0,
946 .bits = 1,
947 },
948 [ALE_PORT_STATE] = {
949 .name = "port_state",
950 .offset = ALE_PORTCTL,
951 .port_offset = 4,
952 .shift = 0,
953 .port_shift = 0,
954 .bits = 2,
955 },
956 [ALE_PORT_DROP_UNTAGGED] = {
957 .name = "drop_untagged",
958 .offset = ALE_PORTCTL,
959 .port_offset = 4,
960 .shift = 2,
961 .port_shift = 0,
962 .bits = 1,
963 },
964 [ALE_PORT_DROP_UNKNOWN_VLAN] = {
965 .name = "drop_unknown",
966 .offset = ALE_PORTCTL,
967 .port_offset = 4,
968 .shift = 3,
969 .port_shift = 0,
970 .bits = 1,
971 },
972 [ALE_PORT_NOLEARN] = {
973 .name = "nolearn",
974 .offset = ALE_PORTCTL,
975 .port_offset = 4,
976 .shift = 4,
977 .port_shift = 0,
978 .bits = 1,
979 },
980 [ALE_PORT_NO_SA_UPDATE] = {
981 .name = "no_source_update",
982 .offset = ALE_PORTCTL,
983 .port_offset = 4,
984 .shift = 5,
985 .port_shift = 0,
986 .bits = 1,
987 },
988 [ALE_PORT_MACONLY] = {
989 .name = "mac_only_port_mode",
990 .offset = ALE_PORTCTL,
991 .port_offset = 4,
992 .shift = 11,
993 .port_shift = 0,
994 .bits = 1,
995 },
996 [ALE_PORT_MACONLY_CAF] = {
997 .name = "mac_only_port_caf",
998 .offset = ALE_PORTCTL,
999 .port_offset = 4,
1000 .shift = 13,
1001 .port_shift = 0,
1002 .bits = 1,
1003 },
1004 [ALE_PORT_MCAST_LIMIT] = {
1005 .name = "mcast_limit",
1006 .offset = ALE_PORTCTL,
1007 .port_offset = 4,
1008 .shift = 16,
1009 .port_shift = 0,
1010 .bits = 8,
1011 },
1012 [ALE_PORT_BCAST_LIMIT] = {
1013 .name = "bcast_limit",
1014 .offset = ALE_PORTCTL,
1015 .port_offset = 4,
1016 .shift = 24,
1017 .port_shift = 0,
1018 .bits = 8,
1019 },
1020 [ALE_PORT_UNKNOWN_VLAN_MEMBER] = {
1021 .name = "unknown_vlan_member",
1022 .offset = ALE_UNKNOWNVLAN,
1023 .port_offset = 0,
1024 .shift = 0,
1025 .port_shift = 0,
1026 .bits = 6,
1027 },
1028 [ALE_PORT_UNKNOWN_MCAST_FLOOD] = {
1029 .name = "unknown_mcast_flood",
1030 .offset = ALE_UNKNOWNVLAN,
1031 .port_offset = 0,
1032 .shift = 8,
1033 .port_shift = 0,
1034 .bits = 6,
1035 },
1036 [ALE_PORT_UNKNOWN_REG_MCAST_FLOOD] = {
1037 .name = "unknown_reg_flood",
1038 .offset = ALE_UNKNOWNVLAN,
1039 .port_offset = 0,
1040 .shift = 16,
1041 .port_shift = 0,
1042 .bits = 6,
1043 },
1044 [ALE_PORT_UNTAGGED_EGRESS] = {
1045 .name = "untagged_egress",
1046 .offset = ALE_UNKNOWNVLAN,
1047 .port_offset = 0,
1048 .shift = 24,
1049 .port_shift = 0,
1050 .bits = 6,
1051 },
1052 [ALE_DEFAULT_THREAD_ID] = {
1053 .name = "default_thread_id",
1054 .offset = AM65_CPSW_ALE_THREAD_DEF_REG,
1055 .port_offset = 0,
1056 .shift = 0,
1057 .port_shift = 0,
1058 .bits = 6,
1059 },
1060 [ALE_DEFAULT_THREAD_ENABLE] = {
1061 .name = "default_thread_id_enable",
1062 .offset = AM65_CPSW_ALE_THREAD_DEF_REG,
1063 .port_offset = 0,
1064 .shift = 15,
1065 .port_shift = 0,
1066 .bits = 1,
1067 },
1068 };
1069
cpsw_ale_control_set(struct cpsw_ale * ale,int port,int control,int value)1070 int cpsw_ale_control_set(struct cpsw_ale *ale, int port, int control,
1071 int value)
1072 {
1073 const struct ale_control_info *info;
1074 int offset, shift;
1075 u32 tmp, mask;
1076
1077 if (control < 0 || control >= ARRAY_SIZE(ale_controls))
1078 return -EINVAL;
1079
1080 info = &ale_controls[control];
1081 if (info->port_offset == 0 && info->port_shift == 0)
1082 port = 0; /* global, port is a dont care */
1083
1084 if (port < 0 || port >= ale->params.ale_ports)
1085 return -EINVAL;
1086
1087 mask = BITMASK(info->bits);
1088 if (value & ~mask)
1089 return -EINVAL;
1090
1091 offset = info->offset + (port * info->port_offset);
1092 shift = info->shift + (port * info->port_shift);
1093
1094 tmp = readl_relaxed(ale->params.ale_regs + offset);
1095 tmp = (tmp & ~(mask << shift)) | (value << shift);
1096 writel_relaxed(tmp, ale->params.ale_regs + offset);
1097
1098 return 0;
1099 }
1100
cpsw_ale_control_get(struct cpsw_ale * ale,int port,int control)1101 int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control)
1102 {
1103 const struct ale_control_info *info;
1104 int offset, shift;
1105 u32 tmp;
1106
1107 if (control < 0 || control >= ARRAY_SIZE(ale_controls))
1108 return -EINVAL;
1109
1110 info = &ale_controls[control];
1111 if (info->port_offset == 0 && info->port_shift == 0)
1112 port = 0; /* global, port is a dont care */
1113
1114 if (port < 0 || port >= ale->params.ale_ports)
1115 return -EINVAL;
1116
1117 offset = info->offset + (port * info->port_offset);
1118 shift = info->shift + (port * info->port_shift);
1119
1120 tmp = readl_relaxed(ale->params.ale_regs + offset) >> shift;
1121 return tmp & BITMASK(info->bits);
1122 }
1123
cpsw_ale_timer(struct timer_list * t)1124 static void cpsw_ale_timer(struct timer_list *t)
1125 {
1126 struct cpsw_ale *ale = from_timer(ale, t, timer);
1127
1128 cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
1129
1130 if (ale->ageout) {
1131 ale->timer.expires = jiffies + ale->ageout;
1132 add_timer(&ale->timer);
1133 }
1134 }
1135
cpsw_ale_hw_aging_timer_start(struct cpsw_ale * ale)1136 static void cpsw_ale_hw_aging_timer_start(struct cpsw_ale *ale)
1137 {
1138 u32 aging_timer;
1139
1140 aging_timer = ale->params.bus_freq / 1000000;
1141 aging_timer *= ale->params.ale_ageout;
1142
1143 if (aging_timer & ~ALE_AGING_TIMER_MASK) {
1144 aging_timer = ALE_AGING_TIMER_MASK;
1145 dev_warn(ale->params.dev,
1146 "ALE aging timer overflow, set to max\n");
1147 }
1148
1149 writel(aging_timer, ale->params.ale_regs + ALE_AGING_TIMER);
1150 }
1151
cpsw_ale_hw_aging_timer_stop(struct cpsw_ale * ale)1152 static void cpsw_ale_hw_aging_timer_stop(struct cpsw_ale *ale)
1153 {
1154 writel(0, ale->params.ale_regs + ALE_AGING_TIMER);
1155 }
1156
cpsw_ale_aging_start(struct cpsw_ale * ale)1157 static void cpsw_ale_aging_start(struct cpsw_ale *ale)
1158 {
1159 if (!ale->params.ale_ageout)
1160 return;
1161
1162 if (ale->features & CPSW_ALE_F_HW_AUTOAGING) {
1163 cpsw_ale_hw_aging_timer_start(ale);
1164 return;
1165 }
1166
1167 timer_setup(&ale->timer, cpsw_ale_timer, 0);
1168 ale->timer.expires = jiffies + ale->ageout;
1169 add_timer(&ale->timer);
1170 }
1171
cpsw_ale_aging_stop(struct cpsw_ale * ale)1172 static void cpsw_ale_aging_stop(struct cpsw_ale *ale)
1173 {
1174 if (!ale->params.ale_ageout)
1175 return;
1176
1177 if (ale->features & CPSW_ALE_F_HW_AUTOAGING) {
1178 cpsw_ale_hw_aging_timer_stop(ale);
1179 return;
1180 }
1181
1182 del_timer_sync(&ale->timer);
1183 }
1184
cpsw_ale_start(struct cpsw_ale * ale)1185 void cpsw_ale_start(struct cpsw_ale *ale)
1186 {
1187 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 1);
1188 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
1189
1190 cpsw_ale_aging_start(ale);
1191 }
1192
cpsw_ale_stop(struct cpsw_ale * ale)1193 void cpsw_ale_stop(struct cpsw_ale *ale)
1194 {
1195 cpsw_ale_aging_stop(ale);
1196 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
1197 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0);
1198 }
1199
1200 static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = {
1201 {
1202 /* am3/4/5, dra7. dm814x, 66ak2hk-gbe */
1203 .dev_id = "cpsw",
1204 .tbl_entries = 1024,
1205 .major_ver_mask = 0xff,
1206 .vlan_entry_tbl = vlan_entry_cpsw,
1207 },
1208 {
1209 /* 66ak2h_xgbe */
1210 .dev_id = "66ak2h-xgbe",
1211 .tbl_entries = 2048,
1212 .major_ver_mask = 0xff,
1213 .vlan_entry_tbl = vlan_entry_cpsw,
1214 },
1215 {
1216 .dev_id = "66ak2el",
1217 .features = CPSW_ALE_F_STATUS_REG,
1218 .major_ver_mask = 0x7,
1219 .nu_switch_ale = true,
1220 .vlan_entry_tbl = vlan_entry_nu,
1221 },
1222 {
1223 .dev_id = "66ak2g",
1224 .features = CPSW_ALE_F_STATUS_REG,
1225 .tbl_entries = 64,
1226 .major_ver_mask = 0x7,
1227 .nu_switch_ale = true,
1228 .vlan_entry_tbl = vlan_entry_nu,
1229 },
1230 {
1231 .dev_id = "am65x-cpsw2g",
1232 .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
1233 .tbl_entries = 64,
1234 .major_ver_mask = 0x7,
1235 .nu_switch_ale = true,
1236 .vlan_entry_tbl = vlan_entry_nu,
1237 },
1238 {
1239 .dev_id = "j721e-cpswxg",
1240 .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
1241 .major_ver_mask = 0x7,
1242 .vlan_entry_tbl = vlan_entry_k3_cpswxg,
1243 },
1244 { },
1245 };
1246
1247 static const struct
cpsw_ale_match_id(const struct cpsw_ale_dev_id * id,const char * dev_id)1248 cpsw_ale_dev_id *cpsw_ale_match_id(const struct cpsw_ale_dev_id *id,
1249 const char *dev_id)
1250 {
1251 if (!dev_id)
1252 return NULL;
1253
1254 while (id->dev_id) {
1255 if (strcmp(dev_id, id->dev_id) == 0)
1256 return id;
1257 id++;
1258 }
1259 return NULL;
1260 }
1261
cpsw_ale_create(struct cpsw_ale_params * params)1262 struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params)
1263 {
1264 const struct cpsw_ale_dev_id *ale_dev_id;
1265 struct cpsw_ale *ale;
1266 u32 rev, ale_entries;
1267
1268 ale_dev_id = cpsw_ale_match_id(cpsw_ale_id_match, params->dev_id);
1269 if (!ale_dev_id)
1270 return ERR_PTR(-EINVAL);
1271
1272 params->ale_entries = ale_dev_id->tbl_entries;
1273 params->major_ver_mask = ale_dev_id->major_ver_mask;
1274 params->nu_switch_ale = ale_dev_id->nu_switch_ale;
1275
1276 ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL);
1277 if (!ale)
1278 return ERR_PTR(-ENOMEM);
1279
1280 ale->p0_untag_vid_mask =
1281 devm_kmalloc_array(params->dev, BITS_TO_LONGS(VLAN_N_VID),
1282 sizeof(unsigned long),
1283 GFP_KERNEL);
1284 if (!ale->p0_untag_vid_mask)
1285 return ERR_PTR(-ENOMEM);
1286
1287 ale->params = *params;
1288 ale->ageout = ale->params.ale_ageout * HZ;
1289 ale->features = ale_dev_id->features;
1290 ale->vlan_entry_tbl = ale_dev_id->vlan_entry_tbl;
1291
1292 rev = readl_relaxed(ale->params.ale_regs + ALE_IDVER);
1293 ale->version =
1294 (ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask) << 8) |
1295 ALE_VERSION_MINOR(rev);
1296 dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n",
1297 ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask),
1298 ALE_VERSION_MINOR(rev));
1299
1300 if (ale->features & CPSW_ALE_F_STATUS_REG &&
1301 !ale->params.ale_entries) {
1302 ale_entries =
1303 readl_relaxed(ale->params.ale_regs + ALE_STATUS) &
1304 ALE_STATUS_SIZE_MASK;
1305 /* ALE available on newer NetCP switches has introduced
1306 * a register, ALE_STATUS, to indicate the size of ALE
1307 * table which shows the size as a multiple of 1024 entries.
1308 * For these, params.ale_entries will be set to zero. So
1309 * read the register and update the value of ale_entries.
1310 * return error if ale_entries is zero in ALE_STATUS.
1311 */
1312 if (!ale_entries)
1313 return ERR_PTR(-EINVAL);
1314
1315 ale_entries *= ALE_TABLE_SIZE_MULTIPLIER;
1316 ale->params.ale_entries = ale_entries;
1317 }
1318 dev_info(ale->params.dev,
1319 "ALE Table size %ld\n", ale->params.ale_entries);
1320
1321 /* set default bits for existing h/w */
1322 ale->port_mask_bits = ale->params.ale_ports;
1323 ale->port_num_bits = order_base_2(ale->params.ale_ports);
1324 ale->vlan_field_bits = ale->params.ale_ports;
1325
1326 /* Set defaults override for ALE on NetCP NU switch and for version
1327 * 1R3
1328 */
1329 if (ale->params.nu_switch_ale) {
1330 /* Separate registers for unknown vlan configuration.
1331 * Also there are N bits, where N is number of ale
1332 * ports and shift value should be 0
1333 */
1334 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].bits =
1335 ale->params.ale_ports;
1336 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].offset =
1337 ALE_UNKNOWNVLAN_MEMBER;
1338 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].bits =
1339 ale->params.ale_ports;
1340 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].shift = 0;
1341 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].offset =
1342 ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD;
1343 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].bits =
1344 ale->params.ale_ports;
1345 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].shift = 0;
1346 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].offset =
1347 ALE_UNKNOWNVLAN_REG_MCAST_FLOOD;
1348 ale_controls[ALE_PORT_UNTAGGED_EGRESS].bits =
1349 ale->params.ale_ports;
1350 ale_controls[ALE_PORT_UNTAGGED_EGRESS].shift = 0;
1351 ale_controls[ALE_PORT_UNTAGGED_EGRESS].offset =
1352 ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS;
1353 }
1354
1355 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
1356 return ale;
1357 }
1358
cpsw_ale_dump(struct cpsw_ale * ale,u32 * data)1359 void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data)
1360 {
1361 int i;
1362
1363 for (i = 0; i < ale->params.ale_entries; i++) {
1364 cpsw_ale_read(ale, i, data);
1365 data += ALE_ENTRY_WORDS;
1366 }
1367 }
1368
cpsw_ale_get_num_entries(struct cpsw_ale * ale)1369 u32 cpsw_ale_get_num_entries(struct cpsw_ale *ale)
1370 {
1371 return ale ? ale->params.ale_entries : 0;
1372 }
1373