Loading...
Note: File does not exist in v3.1.
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/kernel.h>
9#include <linux/module.h>
10#include <linux/platform_device.h>
11#include <linux/seq_file.h>
12#include <linux/slab.h>
13#include <linux/err.h>
14#include <linux/io.h>
15#include <linux/stat.h>
16#include <linux/sysfs.h>
17#include <linux/etherdevice.h>
18
19#include "cpsw_ale.h"
20
21#define BITMASK(bits) (BIT(bits) - 1)
22
23#define ALE_VERSION_MAJOR(rev, mask) (((rev) >> 8) & (mask))
24#define ALE_VERSION_MINOR(rev) (rev & 0xff)
25#define ALE_VERSION_1R3 0x0103
26#define ALE_VERSION_1R4 0x0104
27
28/* ALE Registers */
29#define ALE_IDVER 0x00
30#define ALE_STATUS 0x04
31#define ALE_CONTROL 0x08
32#define ALE_PRESCALE 0x10
33#define ALE_UNKNOWNVLAN 0x18
34#define ALE_TABLE_CONTROL 0x20
35#define ALE_TABLE 0x34
36#define ALE_PORTCTL 0x40
37
38/* ALE NetCP NU switch specific Registers */
39#define ALE_UNKNOWNVLAN_MEMBER 0x90
40#define ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD 0x94
41#define ALE_UNKNOWNVLAN_REG_MCAST_FLOOD 0x98
42#define ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS 0x9C
43#define ALE_VLAN_MASK_MUX(reg) (0xc0 + (0x4 * (reg)))
44
45#define ALE_TABLE_WRITE BIT(31)
46
47#define ALE_TYPE_FREE 0
48#define ALE_TYPE_ADDR 1
49#define ALE_TYPE_VLAN 2
50#define ALE_TYPE_VLAN_ADDR 3
51
52#define ALE_UCAST_PERSISTANT 0
53#define ALE_UCAST_UNTOUCHED 1
54#define ALE_UCAST_OUI 2
55#define ALE_UCAST_TOUCHED 3
56
57#define ALE_TABLE_SIZE_MULTIPLIER 1024
58#define ALE_STATUS_SIZE_MASK 0x1f
59#define ALE_TABLE_SIZE_DEFAULT 64
60
61static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
62{
63 int idx;
64
65 idx = start / 32;
66 start -= idx * 32;
67 idx = 2 - idx; /* flip */
68 return (ale_entry[idx] >> start) & BITMASK(bits);
69}
70
71static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
72 u32 value)
73{
74 int idx;
75
76 value &= BITMASK(bits);
77 idx = start / 32;
78 start -= idx * 32;
79 idx = 2 - idx; /* flip */
80 ale_entry[idx] &= ~(BITMASK(bits) << start);
81 ale_entry[idx] |= (value << start);
82}
83
84#define DEFINE_ALE_FIELD(name, start, bits) \
85static inline int cpsw_ale_get_##name(u32 *ale_entry) \
86{ \
87 return cpsw_ale_get_field(ale_entry, start, bits); \
88} \
89static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value) \
90{ \
91 cpsw_ale_set_field(ale_entry, start, bits, value); \
92}
93
94#define DEFINE_ALE_FIELD1(name, start) \
95static inline int cpsw_ale_get_##name(u32 *ale_entry, u32 bits) \
96{ \
97 return cpsw_ale_get_field(ale_entry, start, bits); \
98} \
99static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value, \
100 u32 bits) \
101{ \
102 cpsw_ale_set_field(ale_entry, start, bits, value); \
103}
104
105DEFINE_ALE_FIELD(entry_type, 60, 2)
106DEFINE_ALE_FIELD(vlan_id, 48, 12)
107DEFINE_ALE_FIELD(mcast_state, 62, 2)
108DEFINE_ALE_FIELD1(port_mask, 66)
109DEFINE_ALE_FIELD(super, 65, 1)
110DEFINE_ALE_FIELD(ucast_type, 62, 2)
111DEFINE_ALE_FIELD1(port_num, 66)
112DEFINE_ALE_FIELD(blocked, 65, 1)
113DEFINE_ALE_FIELD(secure, 64, 1)
114DEFINE_ALE_FIELD1(vlan_untag_force, 24)
115DEFINE_ALE_FIELD1(vlan_reg_mcast, 16)
116DEFINE_ALE_FIELD1(vlan_unreg_mcast, 8)
117DEFINE_ALE_FIELD1(vlan_member_list, 0)
118DEFINE_ALE_FIELD(mcast, 40, 1)
119/* ALE NetCP nu switch specific */
120DEFINE_ALE_FIELD(vlan_unreg_mcast_idx, 20, 3)
121DEFINE_ALE_FIELD(vlan_reg_mcast_idx, 44, 3)
122
123/* The MAC address field in the ALE entry cannot be macroized as above */
124static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr)
125{
126 int i;
127
128 for (i = 0; i < 6; i++)
129 addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8);
130}
131
132static inline void cpsw_ale_set_addr(u32 *ale_entry, const u8 *addr)
133{
134 int i;
135
136 for (i = 0; i < 6; i++)
137 cpsw_ale_set_field(ale_entry, 40 - 8*i, 8, addr[i]);
138}
139
140static int cpsw_ale_read(struct cpsw_ale *ale, int idx, u32 *ale_entry)
141{
142 int i;
143
144 WARN_ON(idx > ale->params.ale_entries);
145
146 writel_relaxed(idx, ale->params.ale_regs + ALE_TABLE_CONTROL);
147
148 for (i = 0; i < ALE_ENTRY_WORDS; i++)
149 ale_entry[i] = readl_relaxed(ale->params.ale_regs +
150 ALE_TABLE + 4 * i);
151
152 return idx;
153}
154
155static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry)
156{
157 int i;
158
159 WARN_ON(idx > ale->params.ale_entries);
160
161 for (i = 0; i < ALE_ENTRY_WORDS; i++)
162 writel_relaxed(ale_entry[i], ale->params.ale_regs +
163 ALE_TABLE + 4 * i);
164
165 writel_relaxed(idx | ALE_TABLE_WRITE, ale->params.ale_regs +
166 ALE_TABLE_CONTROL);
167
168 return idx;
169}
170
171static int cpsw_ale_match_addr(struct cpsw_ale *ale, const u8 *addr, u16 vid)
172{
173 u32 ale_entry[ALE_ENTRY_WORDS];
174 int type, idx;
175
176 for (idx = 0; idx < ale->params.ale_entries; idx++) {
177 u8 entry_addr[6];
178
179 cpsw_ale_read(ale, idx, ale_entry);
180 type = cpsw_ale_get_entry_type(ale_entry);
181 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
182 continue;
183 if (cpsw_ale_get_vlan_id(ale_entry) != vid)
184 continue;
185 cpsw_ale_get_addr(ale_entry, entry_addr);
186 if (ether_addr_equal(entry_addr, addr))
187 return idx;
188 }
189 return -ENOENT;
190}
191
192static int cpsw_ale_match_vlan(struct cpsw_ale *ale, u16 vid)
193{
194 u32 ale_entry[ALE_ENTRY_WORDS];
195 int type, idx;
196
197 for (idx = 0; idx < ale->params.ale_entries; idx++) {
198 cpsw_ale_read(ale, idx, ale_entry);
199 type = cpsw_ale_get_entry_type(ale_entry);
200 if (type != ALE_TYPE_VLAN)
201 continue;
202 if (cpsw_ale_get_vlan_id(ale_entry) == vid)
203 return idx;
204 }
205 return -ENOENT;
206}
207
208static int cpsw_ale_match_free(struct cpsw_ale *ale)
209{
210 u32 ale_entry[ALE_ENTRY_WORDS];
211 int type, idx;
212
213 for (idx = 0; idx < ale->params.ale_entries; idx++) {
214 cpsw_ale_read(ale, idx, ale_entry);
215 type = cpsw_ale_get_entry_type(ale_entry);
216 if (type == ALE_TYPE_FREE)
217 return idx;
218 }
219 return -ENOENT;
220}
221
222static int cpsw_ale_find_ageable(struct cpsw_ale *ale)
223{
224 u32 ale_entry[ALE_ENTRY_WORDS];
225 int type, idx;
226
227 for (idx = 0; idx < ale->params.ale_entries; idx++) {
228 cpsw_ale_read(ale, idx, ale_entry);
229 type = cpsw_ale_get_entry_type(ale_entry);
230 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
231 continue;
232 if (cpsw_ale_get_mcast(ale_entry))
233 continue;
234 type = cpsw_ale_get_ucast_type(ale_entry);
235 if (type != ALE_UCAST_PERSISTANT &&
236 type != ALE_UCAST_OUI)
237 return idx;
238 }
239 return -ENOENT;
240}
241
242static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry,
243 int port_mask)
244{
245 int mask;
246
247 mask = cpsw_ale_get_port_mask(ale_entry,
248 ale->port_mask_bits);
249 if ((mask & port_mask) == 0)
250 return; /* ports dont intersect, not interested */
251 mask &= ~port_mask;
252
253 /* free if only remaining port is host port */
254 if (mask)
255 cpsw_ale_set_port_mask(ale_entry, mask,
256 ale->port_mask_bits);
257 else
258 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
259}
260
261int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid)
262{
263 u32 ale_entry[ALE_ENTRY_WORDS];
264 int ret, idx;
265
266 for (idx = 0; idx < ale->params.ale_entries; idx++) {
267 cpsw_ale_read(ale, idx, ale_entry);
268 ret = cpsw_ale_get_entry_type(ale_entry);
269 if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR)
270 continue;
271
272 /* if vid passed is -1 then remove all multicast entry from
273 * the table irrespective of vlan id, if a valid vlan id is
274 * passed then remove only multicast added to that vlan id.
275 * if vlan id doesn't match then move on to next entry.
276 */
277 if (vid != -1 && cpsw_ale_get_vlan_id(ale_entry) != vid)
278 continue;
279
280 if (cpsw_ale_get_mcast(ale_entry)) {
281 u8 addr[6];
282
283 if (cpsw_ale_get_super(ale_entry))
284 continue;
285
286 cpsw_ale_get_addr(ale_entry, addr);
287 if (!is_broadcast_ether_addr(addr))
288 cpsw_ale_flush_mcast(ale, ale_entry, port_mask);
289 }
290
291 cpsw_ale_write(ale, idx, ale_entry);
292 }
293 return 0;
294}
295
296static inline void cpsw_ale_set_vlan_entry_type(u32 *ale_entry,
297 int flags, u16 vid)
298{
299 if (flags & ALE_VLAN) {
300 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN_ADDR);
301 cpsw_ale_set_vlan_id(ale_entry, vid);
302 } else {
303 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
304 }
305}
306
307int cpsw_ale_add_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
308 int flags, u16 vid)
309{
310 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
311 int idx;
312
313 cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);
314
315 cpsw_ale_set_addr(ale_entry, addr);
316 cpsw_ale_set_ucast_type(ale_entry, ALE_UCAST_PERSISTANT);
317 cpsw_ale_set_secure(ale_entry, (flags & ALE_SECURE) ? 1 : 0);
318 cpsw_ale_set_blocked(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0);
319 cpsw_ale_set_port_num(ale_entry, port, ale->port_num_bits);
320
321 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
322 if (idx < 0)
323 idx = cpsw_ale_match_free(ale);
324 if (idx < 0)
325 idx = cpsw_ale_find_ageable(ale);
326 if (idx < 0)
327 return -ENOMEM;
328
329 cpsw_ale_write(ale, idx, ale_entry);
330 return 0;
331}
332
333int cpsw_ale_del_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
334 int flags, u16 vid)
335{
336 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
337 int idx;
338
339 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
340 if (idx < 0)
341 return -ENOENT;
342
343 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
344 cpsw_ale_write(ale, idx, ale_entry);
345 return 0;
346}
347
348int cpsw_ale_add_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
349 int flags, u16 vid, int mcast_state)
350{
351 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
352 int idx, mask;
353
354 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
355 if (idx >= 0)
356 cpsw_ale_read(ale, idx, ale_entry);
357
358 cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);
359
360 cpsw_ale_set_addr(ale_entry, addr);
361 cpsw_ale_set_super(ale_entry, (flags & ALE_SUPER) ? 1 : 0);
362 cpsw_ale_set_mcast_state(ale_entry, mcast_state);
363
364 mask = cpsw_ale_get_port_mask(ale_entry,
365 ale->port_mask_bits);
366 port_mask |= mask;
367 cpsw_ale_set_port_mask(ale_entry, port_mask,
368 ale->port_mask_bits);
369
370 if (idx < 0)
371 idx = cpsw_ale_match_free(ale);
372 if (idx < 0)
373 idx = cpsw_ale_find_ageable(ale);
374 if (idx < 0)
375 return -ENOMEM;
376
377 cpsw_ale_write(ale, idx, ale_entry);
378 return 0;
379}
380
381int cpsw_ale_del_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
382 int flags, u16 vid)
383{
384 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
385 int idx;
386
387 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
388 if (idx < 0)
389 return -ENOENT;
390
391 cpsw_ale_read(ale, idx, ale_entry);
392
393 if (port_mask)
394 cpsw_ale_set_port_mask(ale_entry, port_mask,
395 ale->port_mask_bits);
396 else
397 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
398
399 cpsw_ale_write(ale, idx, ale_entry);
400 return 0;
401}
402
403/* ALE NetCP NU switch specific vlan functions */
404static void cpsw_ale_set_vlan_mcast(struct cpsw_ale *ale, u32 *ale_entry,
405 int reg_mcast, int unreg_mcast)
406{
407 int idx;
408
409 /* Set VLAN registered multicast flood mask */
410 idx = cpsw_ale_get_vlan_reg_mcast_idx(ale_entry);
411 writel(reg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
412
413 /* Set VLAN unregistered multicast flood mask */
414 idx = cpsw_ale_get_vlan_unreg_mcast_idx(ale_entry);
415 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
416}
417
418int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag,
419 int reg_mcast, int unreg_mcast)
420{
421 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
422 int idx;
423
424 idx = cpsw_ale_match_vlan(ale, vid);
425 if (idx >= 0)
426 cpsw_ale_read(ale, idx, ale_entry);
427
428 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN);
429 cpsw_ale_set_vlan_id(ale_entry, vid);
430
431 cpsw_ale_set_vlan_untag_force(ale_entry, untag, ale->vlan_field_bits);
432 if (!ale->params.nu_switch_ale) {
433 cpsw_ale_set_vlan_reg_mcast(ale_entry, reg_mcast,
434 ale->vlan_field_bits);
435 cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast,
436 ale->vlan_field_bits);
437 } else {
438 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast, unreg_mcast);
439 }
440 cpsw_ale_set_vlan_member_list(ale_entry, port, ale->vlan_field_bits);
441
442 if (idx < 0)
443 idx = cpsw_ale_match_free(ale);
444 if (idx < 0)
445 idx = cpsw_ale_find_ageable(ale);
446 if (idx < 0)
447 return -ENOMEM;
448
449 cpsw_ale_write(ale, idx, ale_entry);
450 return 0;
451}
452
453int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask)
454{
455 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
456 int idx;
457
458 idx = cpsw_ale_match_vlan(ale, vid);
459 if (idx < 0)
460 return -ENOENT;
461
462 cpsw_ale_read(ale, idx, ale_entry);
463
464 if (port_mask)
465 cpsw_ale_set_vlan_member_list(ale_entry, port_mask,
466 ale->vlan_field_bits);
467 else
468 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
469
470 cpsw_ale_write(ale, idx, ale_entry);
471 return 0;
472}
473
474void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti, int port)
475{
476 u32 ale_entry[ALE_ENTRY_WORDS];
477 int unreg_mcast = 0;
478 int type, idx;
479
480 for (idx = 0; idx < ale->params.ale_entries; idx++) {
481 int vlan_members;
482
483 cpsw_ale_read(ale, idx, ale_entry);
484 type = cpsw_ale_get_entry_type(ale_entry);
485 if (type != ALE_TYPE_VLAN)
486 continue;
487 vlan_members =
488 cpsw_ale_get_vlan_member_list(ale_entry,
489 ale->vlan_field_bits);
490
491 if (port != -1 && !(vlan_members & BIT(port)))
492 continue;
493
494 unreg_mcast =
495 cpsw_ale_get_vlan_unreg_mcast(ale_entry,
496 ale->vlan_field_bits);
497 if (allmulti)
498 unreg_mcast |= ALE_PORT_HOST;
499 else
500 unreg_mcast &= ~ALE_PORT_HOST;
501 cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast,
502 ale->vlan_field_bits);
503 cpsw_ale_write(ale, idx, ale_entry);
504 }
505}
506
507struct ale_control_info {
508 const char *name;
509 int offset, port_offset;
510 int shift, port_shift;
511 int bits;
512};
513
514static struct ale_control_info ale_controls[ALE_NUM_CONTROLS] = {
515 [ALE_ENABLE] = {
516 .name = "enable",
517 .offset = ALE_CONTROL,
518 .port_offset = 0,
519 .shift = 31,
520 .port_shift = 0,
521 .bits = 1,
522 },
523 [ALE_CLEAR] = {
524 .name = "clear",
525 .offset = ALE_CONTROL,
526 .port_offset = 0,
527 .shift = 30,
528 .port_shift = 0,
529 .bits = 1,
530 },
531 [ALE_AGEOUT] = {
532 .name = "ageout",
533 .offset = ALE_CONTROL,
534 .port_offset = 0,
535 .shift = 29,
536 .port_shift = 0,
537 .bits = 1,
538 },
539 [ALE_P0_UNI_FLOOD] = {
540 .name = "port0_unicast_flood",
541 .offset = ALE_CONTROL,
542 .port_offset = 0,
543 .shift = 8,
544 .port_shift = 0,
545 .bits = 1,
546 },
547 [ALE_VLAN_NOLEARN] = {
548 .name = "vlan_nolearn",
549 .offset = ALE_CONTROL,
550 .port_offset = 0,
551 .shift = 7,
552 .port_shift = 0,
553 .bits = 1,
554 },
555 [ALE_NO_PORT_VLAN] = {
556 .name = "no_port_vlan",
557 .offset = ALE_CONTROL,
558 .port_offset = 0,
559 .shift = 6,
560 .port_shift = 0,
561 .bits = 1,
562 },
563 [ALE_OUI_DENY] = {
564 .name = "oui_deny",
565 .offset = ALE_CONTROL,
566 .port_offset = 0,
567 .shift = 5,
568 .port_shift = 0,
569 .bits = 1,
570 },
571 [ALE_BYPASS] = {
572 .name = "bypass",
573 .offset = ALE_CONTROL,
574 .port_offset = 0,
575 .shift = 4,
576 .port_shift = 0,
577 .bits = 1,
578 },
579 [ALE_RATE_LIMIT_TX] = {
580 .name = "rate_limit_tx",
581 .offset = ALE_CONTROL,
582 .port_offset = 0,
583 .shift = 3,
584 .port_shift = 0,
585 .bits = 1,
586 },
587 [ALE_VLAN_AWARE] = {
588 .name = "vlan_aware",
589 .offset = ALE_CONTROL,
590 .port_offset = 0,
591 .shift = 2,
592 .port_shift = 0,
593 .bits = 1,
594 },
595 [ALE_AUTH_ENABLE] = {
596 .name = "auth_enable",
597 .offset = ALE_CONTROL,
598 .port_offset = 0,
599 .shift = 1,
600 .port_shift = 0,
601 .bits = 1,
602 },
603 [ALE_RATE_LIMIT] = {
604 .name = "rate_limit",
605 .offset = ALE_CONTROL,
606 .port_offset = 0,
607 .shift = 0,
608 .port_shift = 0,
609 .bits = 1,
610 },
611 [ALE_PORT_STATE] = {
612 .name = "port_state",
613 .offset = ALE_PORTCTL,
614 .port_offset = 4,
615 .shift = 0,
616 .port_shift = 0,
617 .bits = 2,
618 },
619 [ALE_PORT_DROP_UNTAGGED] = {
620 .name = "drop_untagged",
621 .offset = ALE_PORTCTL,
622 .port_offset = 4,
623 .shift = 2,
624 .port_shift = 0,
625 .bits = 1,
626 },
627 [ALE_PORT_DROP_UNKNOWN_VLAN] = {
628 .name = "drop_unknown",
629 .offset = ALE_PORTCTL,
630 .port_offset = 4,
631 .shift = 3,
632 .port_shift = 0,
633 .bits = 1,
634 },
635 [ALE_PORT_NOLEARN] = {
636 .name = "nolearn",
637 .offset = ALE_PORTCTL,
638 .port_offset = 4,
639 .shift = 4,
640 .port_shift = 0,
641 .bits = 1,
642 },
643 [ALE_PORT_NO_SA_UPDATE] = {
644 .name = "no_source_update",
645 .offset = ALE_PORTCTL,
646 .port_offset = 4,
647 .shift = 5,
648 .port_shift = 0,
649 .bits = 1,
650 },
651 [ALE_PORT_MCAST_LIMIT] = {
652 .name = "mcast_limit",
653 .offset = ALE_PORTCTL,
654 .port_offset = 4,
655 .shift = 16,
656 .port_shift = 0,
657 .bits = 8,
658 },
659 [ALE_PORT_BCAST_LIMIT] = {
660 .name = "bcast_limit",
661 .offset = ALE_PORTCTL,
662 .port_offset = 4,
663 .shift = 24,
664 .port_shift = 0,
665 .bits = 8,
666 },
667 [ALE_PORT_UNKNOWN_VLAN_MEMBER] = {
668 .name = "unknown_vlan_member",
669 .offset = ALE_UNKNOWNVLAN,
670 .port_offset = 0,
671 .shift = 0,
672 .port_shift = 0,
673 .bits = 6,
674 },
675 [ALE_PORT_UNKNOWN_MCAST_FLOOD] = {
676 .name = "unknown_mcast_flood",
677 .offset = ALE_UNKNOWNVLAN,
678 .port_offset = 0,
679 .shift = 8,
680 .port_shift = 0,
681 .bits = 6,
682 },
683 [ALE_PORT_UNKNOWN_REG_MCAST_FLOOD] = {
684 .name = "unknown_reg_flood",
685 .offset = ALE_UNKNOWNVLAN,
686 .port_offset = 0,
687 .shift = 16,
688 .port_shift = 0,
689 .bits = 6,
690 },
691 [ALE_PORT_UNTAGGED_EGRESS] = {
692 .name = "untagged_egress",
693 .offset = ALE_UNKNOWNVLAN,
694 .port_offset = 0,
695 .shift = 24,
696 .port_shift = 0,
697 .bits = 6,
698 },
699};
700
701int cpsw_ale_control_set(struct cpsw_ale *ale, int port, int control,
702 int value)
703{
704 const struct ale_control_info *info;
705 int offset, shift;
706 u32 tmp, mask;
707
708 if (control < 0 || control >= ARRAY_SIZE(ale_controls))
709 return -EINVAL;
710
711 info = &ale_controls[control];
712 if (info->port_offset == 0 && info->port_shift == 0)
713 port = 0; /* global, port is a dont care */
714
715 if (port < 0 || port >= ale->params.ale_ports)
716 return -EINVAL;
717
718 mask = BITMASK(info->bits);
719 if (value & ~mask)
720 return -EINVAL;
721
722 offset = info->offset + (port * info->port_offset);
723 shift = info->shift + (port * info->port_shift);
724
725 tmp = readl_relaxed(ale->params.ale_regs + offset);
726 tmp = (tmp & ~(mask << shift)) | (value << shift);
727 writel_relaxed(tmp, ale->params.ale_regs + offset);
728
729 return 0;
730}
731
732int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control)
733{
734 const struct ale_control_info *info;
735 int offset, shift;
736 u32 tmp;
737
738 if (control < 0 || control >= ARRAY_SIZE(ale_controls))
739 return -EINVAL;
740
741 info = &ale_controls[control];
742 if (info->port_offset == 0 && info->port_shift == 0)
743 port = 0; /* global, port is a dont care */
744
745 if (port < 0 || port >= ale->params.ale_ports)
746 return -EINVAL;
747
748 offset = info->offset + (port * info->port_offset);
749 shift = info->shift + (port * info->port_shift);
750
751 tmp = readl_relaxed(ale->params.ale_regs + offset) >> shift;
752 return tmp & BITMASK(info->bits);
753}
754
755static void cpsw_ale_timer(struct timer_list *t)
756{
757 struct cpsw_ale *ale = from_timer(ale, t, timer);
758
759 cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
760
761 if (ale->ageout) {
762 ale->timer.expires = jiffies + ale->ageout;
763 add_timer(&ale->timer);
764 }
765}
766
767void cpsw_ale_start(struct cpsw_ale *ale)
768{
769 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 1);
770 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
771
772 timer_setup(&ale->timer, cpsw_ale_timer, 0);
773 if (ale->ageout) {
774 ale->timer.expires = jiffies + ale->ageout;
775 add_timer(&ale->timer);
776 }
777}
778
779void cpsw_ale_stop(struct cpsw_ale *ale)
780{
781 del_timer_sync(&ale->timer);
782 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0);
783}
784
785struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params)
786{
787 struct cpsw_ale *ale;
788 u32 rev, ale_entries;
789
790 ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL);
791 if (!ale)
792 return NULL;
793
794 ale->params = *params;
795 ale->ageout = ale->params.ale_ageout * HZ;
796
797 rev = readl_relaxed(ale->params.ale_regs + ALE_IDVER);
798 if (!ale->params.major_ver_mask)
799 ale->params.major_ver_mask = 0xff;
800 ale->version =
801 (ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask) << 8) |
802 ALE_VERSION_MINOR(rev);
803 dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n",
804 ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask),
805 ALE_VERSION_MINOR(rev));
806
807 if (!ale->params.ale_entries) {
808 ale_entries =
809 readl_relaxed(ale->params.ale_regs + ALE_STATUS) &
810 ALE_STATUS_SIZE_MASK;
811 /* ALE available on newer NetCP switches has introduced
812 * a register, ALE_STATUS, to indicate the size of ALE
813 * table which shows the size as a multiple of 1024 entries.
814 * For these, params.ale_entries will be set to zero. So
815 * read the register and update the value of ale_entries.
816 * ALE table on NetCP lite, is much smaller and is indicated
817 * by a value of zero in ALE_STATUS. So use a default value
818 * of ALE_TABLE_SIZE_DEFAULT for this. Caller is expected
819 * to set the value of ale_entries for all other versions
820 * of ALE.
821 */
822 if (!ale_entries)
823 ale_entries = ALE_TABLE_SIZE_DEFAULT;
824 else
825 ale_entries *= ALE_TABLE_SIZE_MULTIPLIER;
826 ale->params.ale_entries = ale_entries;
827 }
828 dev_info(ale->params.dev,
829 "ALE Table size %ld\n", ale->params.ale_entries);
830
831 /* set default bits for existing h/w */
832 ale->port_mask_bits = ale->params.ale_ports;
833 ale->port_num_bits = order_base_2(ale->params.ale_ports);
834 ale->vlan_field_bits = ale->params.ale_ports;
835
836 /* Set defaults override for ALE on NetCP NU switch and for version
837 * 1R3
838 */
839 if (ale->params.nu_switch_ale) {
840 /* Separate registers for unknown vlan configuration.
841 * Also there are N bits, where N is number of ale
842 * ports and shift value should be 0
843 */
844 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].bits =
845 ale->params.ale_ports;
846 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].offset =
847 ALE_UNKNOWNVLAN_MEMBER;
848 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].bits =
849 ale->params.ale_ports;
850 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].shift = 0;
851 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].offset =
852 ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD;
853 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].bits =
854 ale->params.ale_ports;
855 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].shift = 0;
856 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].offset =
857 ALE_UNKNOWNVLAN_REG_MCAST_FLOOD;
858 ale_controls[ALE_PORT_UNTAGGED_EGRESS].bits =
859 ale->params.ale_ports;
860 ale_controls[ALE_PORT_UNTAGGED_EGRESS].shift = 0;
861 ale_controls[ALE_PORT_UNTAGGED_EGRESS].offset =
862 ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS;
863 }
864
865 return ale;
866}
867
868void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data)
869{
870 int i;
871
872 for (i = 0; i < ale->params.ale_entries; i++) {
873 cpsw_ale_read(ale, i, data);
874 data += ALE_ENTRY_WORDS;
875 }
876}