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