This source file includes following definitions.
- cpsw_ale_get_field
- cpsw_ale_set_field
- DEFINE_ALE_FIELD
- cpsw_ale_set_addr
- cpsw_ale_read
- cpsw_ale_write
- cpsw_ale_match_addr
- cpsw_ale_match_vlan
- cpsw_ale_match_free
- cpsw_ale_find_ageable
- cpsw_ale_flush_mcast
- cpsw_ale_flush_multicast
- cpsw_ale_set_vlan_entry_type
- cpsw_ale_add_ucast
- cpsw_ale_del_ucast
- cpsw_ale_add_mcast
- cpsw_ale_del_mcast
- cpsw_ale_set_vlan_mcast
- cpsw_ale_add_vlan
- cpsw_ale_del_vlan
- cpsw_ale_set_allmulti
- cpsw_ale_control_set
- cpsw_ale_control_get
- cpsw_ale_timer
- cpsw_ale_start
- cpsw_ale_stop
- cpsw_ale_create
- cpsw_ale_dump
1
2
3
4
5
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
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
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
61 static 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;
68 return (ale_entry[idx] >> start) & BITMASK(bits);
69 }
70
71 static 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;
80 ale_entry[idx] &= ~(BITMASK(bits) << start);
81 ale_entry[idx] |= (value << start);
82 }
83
84 #define DEFINE_ALE_FIELD(name, start, bits) \
85 static inline int cpsw_ale_get_##name(u32 *ale_entry) \
86 { \
87 return cpsw_ale_get_field(ale_entry, start, bits); \
88 } \
89 static 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) \
95 static inline int cpsw_ale_get_##name(u32 *ale_entry, u32 bits) \
96 { \
97 return cpsw_ale_get_field(ale_entry, start, bits); \
98 } \
99 static 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
105 DEFINE_ALE_FIELD(entry_type, 60, 2)
106 DEFINE_ALE_FIELD(vlan_id, 48, 12)
107 DEFINE_ALE_FIELD(mcast_state, 62, 2)
108 DEFINE_ALE_FIELD1(port_mask, 66)
109 DEFINE_ALE_FIELD(super, 65, 1)
110 DEFINE_ALE_FIELD(ucast_type, 62, 2)
111 DEFINE_ALE_FIELD1(port_num, 66)
112 DEFINE_ALE_FIELD(blocked, 65, 1)
113 DEFINE_ALE_FIELD(secure, 64, 1)
114 DEFINE_ALE_FIELD1(vlan_untag_force, 24)
115 DEFINE_ALE_FIELD1(vlan_reg_mcast, 16)
116 DEFINE_ALE_FIELD1(vlan_unreg_mcast, 8)
117 DEFINE_ALE_FIELD1(vlan_member_list, 0)
118 DEFINE_ALE_FIELD(mcast, 40, 1)
119
120 DEFINE_ALE_FIELD(vlan_unreg_mcast_idx, 20, 3)
121 DEFINE_ALE_FIELD(vlan_reg_mcast_idx, 44, 3)
122
123
124 static 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
132 static 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
140 static 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
155 static 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
171 static 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
192 static 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
208 static 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
222 static 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
242 static 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;
251 mask &= ~port_mask;
252
253
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
261 int 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
273
274
275
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
296 static 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
307 int 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
333 int 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
348 int 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
381 int 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
404 static 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
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
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
418 int 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
453 int 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
474 void 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
507 struct ale_control_info {
508 const char *name;
509 int offset, port_offset;
510 int shift, port_shift;
511 int bits;
512 };
513
514 static 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
701 int 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;
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
732 int 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;
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
755 static 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
767 void 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
779 void cpsw_ale_stop(struct cpsw_ale *ale)
780 {
781 del_timer_sync(&ale->timer);
782 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
783 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0);
784 }
785
786 struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params)
787 {
788 struct cpsw_ale *ale;
789 u32 rev, ale_entries;
790
791 ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL);
792 if (!ale)
793 return NULL;
794
795 ale->params = *params;
796 ale->ageout = ale->params.ale_ageout * HZ;
797
798 rev = readl_relaxed(ale->params.ale_regs + ALE_IDVER);
799 if (!ale->params.major_ver_mask)
800 ale->params.major_ver_mask = 0xff;
801 ale->version =
802 (ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask) << 8) |
803 ALE_VERSION_MINOR(rev);
804 dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n",
805 ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask),
806 ALE_VERSION_MINOR(rev));
807
808 if (!ale->params.ale_entries) {
809 ale_entries =
810 readl_relaxed(ale->params.ale_regs + ALE_STATUS) &
811 ALE_STATUS_SIZE_MASK;
812
813
814
815
816
817
818
819
820
821
822
823 if (!ale_entries)
824 ale_entries = ALE_TABLE_SIZE_DEFAULT;
825 else
826 ale_entries *= ALE_TABLE_SIZE_MULTIPLIER;
827 ale->params.ale_entries = ale_entries;
828 }
829 dev_info(ale->params.dev,
830 "ALE Table size %ld\n", ale->params.ale_entries);
831
832
833 ale->port_mask_bits = ale->params.ale_ports;
834 ale->port_num_bits = order_base_2(ale->params.ale_ports);
835 ale->vlan_field_bits = ale->params.ale_ports;
836
837
838
839
840 if (ale->params.nu_switch_ale) {
841
842
843
844
845 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].bits =
846 ale->params.ale_ports;
847 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].offset =
848 ALE_UNKNOWNVLAN_MEMBER;
849 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].bits =
850 ale->params.ale_ports;
851 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].shift = 0;
852 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].offset =
853 ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD;
854 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].bits =
855 ale->params.ale_ports;
856 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].shift = 0;
857 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].offset =
858 ALE_UNKNOWNVLAN_REG_MCAST_FLOOD;
859 ale_controls[ALE_PORT_UNTAGGED_EGRESS].bits =
860 ale->params.ale_ports;
861 ale_controls[ALE_PORT_UNTAGGED_EGRESS].shift = 0;
862 ale_controls[ALE_PORT_UNTAGGED_EGRESS].offset =
863 ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS;
864 }
865
866 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
867 return ale;
868 }
869
870 void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data)
871 {
872 int i;
873
874 for (i = 0; i < ale->params.ale_entries; i++) {
875 cpsw_ale_read(ale, i, data);
876 data += ALE_ENTRY_WORDS;
877 }
878 }