]> Git Repo - J-linux.git/blob - drivers/net/ethernet/ti/cpsw_ale.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / net / ethernet / ti / cpsw_ale.c
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/regmap.h>
14 #include <linux/seq_file.h>
15 #include <linux/slab.h>
16 #include <linux/err.h>
17 #include <linux/io.h>
18 #include <linux/stat.h>
19 #include <linux/sysfs.h>
20 #include <linux/etherdevice.h>
21
22 #include "cpsw_ale.h"
23
24 #define BITMASK(bits)           (BIT(bits) - 1)
25
26 #define ALE_VERSION_MAJOR(rev, mask) (((rev) >> 8) & (mask))
27 #define ALE_VERSION_MINOR(rev)  (rev & 0xff)
28 #define ALE_VERSION_1R3         0x0103
29 #define ALE_VERSION_1R4         0x0104
30
31 /* ALE Registers */
32 #define ALE_IDVER               0x00
33 #define ALE_STATUS              0x04
34 #define ALE_CONTROL             0x08
35 #define ALE_PRESCALE            0x10
36 #define ALE_AGING_TIMER         0x14
37 #define ALE_UNKNOWNVLAN         0x18
38 #define ALE_TABLE_CONTROL       0x20
39 #define ALE_TABLE               0x34
40 #define ALE_PORTCTL             0x40
41
42 /* ALE NetCP NU switch specific Registers */
43 #define ALE_UNKNOWNVLAN_MEMBER                  0x90
44 #define ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD       0x94
45 #define ALE_UNKNOWNVLAN_REG_MCAST_FLOOD         0x98
46 #define ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS      0x9C
47 #define ALE_VLAN_MASK_MUX(reg)                  (0xc0 + (0x4 * (reg)))
48
49 #define ALE_POLICER_PORT_OUI            0x100
50 #define ALE_POLICER_DA_SA               0x104
51 #define ALE_POLICER_VLAN                0x108
52 #define ALE_POLICER_ETHERTYPE_IPSA      0x10c
53 #define ALE_POLICER_IPDA                0x110
54 #define ALE_POLICER_PIR                 0x118
55 #define ALE_POLICER_CIR                 0x11c
56 #define ALE_POLICER_TBL_CTL             0x120
57 #define ALE_POLICER_CTL                 0x124
58 #define ALE_POLICER_TEST_CTL            0x128
59 #define ALE_POLICER_HIT_STATUS          0x12c
60 #define ALE_THREAD_DEF                  0x134
61 #define ALE_THREAD_CTL                  0x138
62 #define ALE_THREAD_VAL                  0x13c
63
64 #define ALE_POLICER_TBL_WRITE_ENABLE    BIT(31)
65 #define ALE_POLICER_TBL_INDEX_MASK      GENMASK(4, 0)
66
67 #define AM65_CPSW_ALE_THREAD_DEF_REG 0x134
68
69 /* ALE_AGING_TIMER */
70 #define ALE_AGING_TIMER_MASK    GENMASK(23, 0)
71
72 #define ALE_RATE_LIMIT_MIN_PPS 1000
73
74 /**
75  * struct ale_entry_fld - The ALE tbl entry field description
76  * @start_bit: field start bit
77  * @num_bits: field bit length
78  * @flags: field flags
79  */
80 struct ale_entry_fld {
81         u8 start_bit;
82         u8 num_bits;
83         u8 flags;
84 };
85
86 enum {
87         CPSW_ALE_F_STATUS_REG = BIT(0), /* Status register present */
88         CPSW_ALE_F_HW_AUTOAGING = BIT(1), /* HW auto aging */
89
90         CPSW_ALE_F_COUNT
91 };
92
93 /**
94  * struct cpsw_ale_dev_id - The ALE version/SoC specific configuration
95  * @dev_id: ALE version/SoC id
96  * @features: features supported by ALE
97  * @tbl_entries: number of ALE entries
98  * @reg_fields: pointer to array of register field configuration
99  * @num_fields: number of fields in the reg_fields array
100  * @nu_switch_ale: NU Switch ALE
101  * @vlan_entry_tbl: ALE vlan entry fields description tbl
102  */
103 struct cpsw_ale_dev_id {
104         const char *dev_id;
105         u32 features;
106         u32 tbl_entries;
107         const struct reg_field *reg_fields;
108         int num_fields;
109         bool nu_switch_ale;
110         const struct ale_entry_fld *vlan_entry_tbl;
111 };
112
113 #define ALE_TABLE_WRITE         BIT(31)
114
115 #define ALE_TYPE_FREE                   0
116 #define ALE_TYPE_ADDR                   1
117 #define ALE_TYPE_VLAN                   2
118 #define ALE_TYPE_VLAN_ADDR              3
119
120 #define ALE_UCAST_PERSISTANT            0
121 #define ALE_UCAST_UNTOUCHED             1
122 #define ALE_UCAST_OUI                   2
123 #define ALE_UCAST_TOUCHED               3
124
125 #define ALE_TABLE_SIZE_MULTIPLIER       1024
126 #define ALE_POLICER_SIZE_MULTIPLIER     8
127
128 static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
129 {
130         int idx, idx2;
131         u32 hi_val = 0;
132
133         idx    = start / 32;
134         idx2 = (start + bits - 1) / 32;
135         /* Check if bits to be fetched exceed a word */
136         if (idx != idx2) {
137                 idx2 = 2 - idx2; /* flip */
138                 hi_val = ale_entry[idx2] << ((idx2 * 32) - start);
139         }
140         start -= idx * 32;
141         idx    = 2 - idx; /* flip */
142         return (hi_val + (ale_entry[idx] >> start)) & BITMASK(bits);
143 }
144
145 static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
146                                       u32 value)
147 {
148         int idx, idx2;
149
150         value &= BITMASK(bits);
151         idx = start / 32;
152         idx2 = (start + bits - 1) / 32;
153         /* Check if bits to be set exceed a word */
154         if (idx != idx2) {
155                 idx2 = 2 - idx2; /* flip */
156                 ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32)));
157                 ale_entry[idx2] |= (value >> ((idx2 * 32) - start));
158         }
159         start -= idx * 32;
160         idx = 2 - idx; /* flip */
161         ale_entry[idx] &= ~(BITMASK(bits) << start);
162         ale_entry[idx] |=  (value << start);
163 }
164
165 #define DEFINE_ALE_FIELD_GET(name, start, bits)                         \
166 static inline int cpsw_ale_get_##name(u32 *ale_entry)                   \
167 {                                                                       \
168         return cpsw_ale_get_field(ale_entry, start, bits);              \
169 }
170
171 #define DEFINE_ALE_FIELD_SET(name, start, bits)                         \
172 static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value)       \
173 {                                                                       \
174         cpsw_ale_set_field(ale_entry, start, bits, value);              \
175 }
176
177 #define DEFINE_ALE_FIELD(name, start, bits)                             \
178 DEFINE_ALE_FIELD_GET(name, start, bits)                                 \
179 DEFINE_ALE_FIELD_SET(name, start, bits)
180
181 #define DEFINE_ALE_FIELD1_GET(name, start)                              \
182 static inline int cpsw_ale_get_##name(u32 *ale_entry, u32 bits)         \
183 {                                                                       \
184         return cpsw_ale_get_field(ale_entry, start, bits);              \
185 }
186
187 #define DEFINE_ALE_FIELD1_SET(name, start)                              \
188 static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value,       \
189                 u32 bits)                                               \
190 {                                                                       \
191         cpsw_ale_set_field(ale_entry, start, bits, value);              \
192 }
193
194 #define DEFINE_ALE_FIELD1(name, start)                                  \
195 DEFINE_ALE_FIELD1_GET(name, start)                                      \
196 DEFINE_ALE_FIELD1_SET(name, start)
197
198 enum {
199         ALE_ENT_VID_MEMBER_LIST = 0,
200         ALE_ENT_VID_UNREG_MCAST_MSK,
201         ALE_ENT_VID_REG_MCAST_MSK,
202         ALE_ENT_VID_FORCE_UNTAGGED_MSK,
203         ALE_ENT_VID_UNREG_MCAST_IDX,
204         ALE_ENT_VID_REG_MCAST_IDX,
205         ALE_ENT_VID_LAST,
206 };
207
208 #define ALE_FLD_ALLOWED                 BIT(0)
209 #define ALE_FLD_SIZE_PORT_MASK_BITS     BIT(1)
210 #define ALE_FLD_SIZE_PORT_NUM_BITS      BIT(2)
211
212 #define ALE_ENTRY_FLD(id, start, bits)  \
213 [id] = {                                \
214         .start_bit = start,             \
215         .num_bits = bits,               \
216         .flags = ALE_FLD_ALLOWED,       \
217 }
218
219 #define ALE_ENTRY_FLD_DYN_MSK_SIZE(id, start)   \
220 [id] = {                                        \
221         .start_bit = start,                     \
222         .num_bits = 0,                          \
223         .flags = ALE_FLD_ALLOWED |              \
224                  ALE_FLD_SIZE_PORT_MASK_BITS,   \
225 }
226
227 /* dm814x, am3/am4/am5, k2hk */
228 static const struct ale_entry_fld vlan_entry_cpsw[ALE_ENT_VID_LAST] = {
229         ALE_ENTRY_FLD(ALE_ENT_VID_MEMBER_LIST, 0, 3),
230         ALE_ENTRY_FLD(ALE_ENT_VID_UNREG_MCAST_MSK, 8, 3),
231         ALE_ENTRY_FLD(ALE_ENT_VID_REG_MCAST_MSK, 16, 3),
232         ALE_ENTRY_FLD(ALE_ENT_VID_FORCE_UNTAGGED_MSK, 24, 3),
233 };
234
235 /* k2e/k2l, k3 am65/j721e cpsw2g  */
236 static const struct ale_entry_fld vlan_entry_nu[ALE_ENT_VID_LAST] = {
237         ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_MEMBER_LIST, 0),
238         ALE_ENTRY_FLD(ALE_ENT_VID_UNREG_MCAST_IDX, 20, 3),
239         ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_FORCE_UNTAGGED_MSK, 24),
240         ALE_ENTRY_FLD(ALE_ENT_VID_REG_MCAST_IDX, 44, 3),
241 };
242
243 /* K3 j721e/j7200 cpsw9g/5g, am64x cpsw3g  */
244 static const struct ale_entry_fld vlan_entry_k3_cpswxg[] = {
245         ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_MEMBER_LIST, 0),
246         ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_UNREG_MCAST_MSK, 12),
247         ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_FORCE_UNTAGGED_MSK, 24),
248         ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_REG_MCAST_MSK, 36),
249 };
250
251 DEFINE_ALE_FIELD(entry_type,            60,     2)
252 DEFINE_ALE_FIELD(vlan_id,               48,     12)
253 DEFINE_ALE_FIELD_SET(mcast_state,       62,     2)
254 DEFINE_ALE_FIELD1(port_mask,            66)
255 DEFINE_ALE_FIELD(super,                 65,     1)
256 DEFINE_ALE_FIELD(ucast_type,            62,     2)
257 DEFINE_ALE_FIELD1_SET(port_num,         66)
258 DEFINE_ALE_FIELD_SET(blocked,           65,     1)
259 DEFINE_ALE_FIELD_SET(secure,            64,     1)
260 DEFINE_ALE_FIELD_GET(mcast,             40,     1)
261
262 #define NU_VLAN_UNREG_MCAST_IDX 1
263
264 static int cpsw_ale_entry_get_fld(struct cpsw_ale *ale,
265                                   u32 *ale_entry,
266                                   const struct ale_entry_fld *entry_tbl,
267                                   int fld_id)
268 {
269         const struct ale_entry_fld *entry_fld;
270         u32 bits;
271
272         if (!ale || !ale_entry)
273                 return -EINVAL;
274
275         entry_fld = &entry_tbl[fld_id];
276         if (!(entry_fld->flags & ALE_FLD_ALLOWED)) {
277                 dev_err(ale->params.dev, "get: wrong ale fld id %d\n", fld_id);
278                 return -ENOENT;
279         }
280
281         bits = entry_fld->num_bits;
282         if (entry_fld->flags & ALE_FLD_SIZE_PORT_MASK_BITS)
283                 bits = ale->port_mask_bits;
284
285         return cpsw_ale_get_field(ale_entry, entry_fld->start_bit, bits);
286 }
287
288 static void cpsw_ale_entry_set_fld(struct cpsw_ale *ale,
289                                    u32 *ale_entry,
290                                    const struct ale_entry_fld *entry_tbl,
291                                    int fld_id,
292                                    u32 value)
293 {
294         const struct ale_entry_fld *entry_fld;
295         u32 bits;
296
297         if (!ale || !ale_entry)
298                 return;
299
300         entry_fld = &entry_tbl[fld_id];
301         if (!(entry_fld->flags & ALE_FLD_ALLOWED)) {
302                 dev_err(ale->params.dev, "set: wrong ale fld id %d\n", fld_id);
303                 return;
304         }
305
306         bits = entry_fld->num_bits;
307         if (entry_fld->flags & ALE_FLD_SIZE_PORT_MASK_BITS)
308                 bits = ale->port_mask_bits;
309
310         cpsw_ale_set_field(ale_entry, entry_fld->start_bit, bits, value);
311 }
312
313 static int cpsw_ale_vlan_get_fld(struct cpsw_ale *ale,
314                                  u32 *ale_entry,
315                                  int fld_id)
316 {
317         return cpsw_ale_entry_get_fld(ale, ale_entry,
318                                       ale->vlan_entry_tbl, fld_id);
319 }
320
321 static void cpsw_ale_vlan_set_fld(struct cpsw_ale *ale,
322                                   u32 *ale_entry,
323                                   int fld_id,
324                                   u32 value)
325 {
326         cpsw_ale_entry_set_fld(ale, ale_entry,
327                                ale->vlan_entry_tbl, fld_id, value);
328 }
329
330 /* The MAC address field in the ALE entry cannot be macroized as above */
331 static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr)
332 {
333         int i;
334
335         for (i = 0; i < 6; i++)
336                 addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8);
337 }
338
339 static inline void cpsw_ale_set_addr(u32 *ale_entry, const u8 *addr)
340 {
341         int i;
342
343         for (i = 0; i < 6; i++)
344                 cpsw_ale_set_field(ale_entry, 40 - 8*i, 8, addr[i]);
345 }
346
347 static int cpsw_ale_read(struct cpsw_ale *ale, int idx, u32 *ale_entry)
348 {
349         int i;
350
351         WARN_ON(idx > ale->params.ale_entries);
352
353         writel_relaxed(idx, ale->params.ale_regs + ALE_TABLE_CONTROL);
354
355         for (i = 0; i < ALE_ENTRY_WORDS; i++)
356                 ale_entry[i] = readl_relaxed(ale->params.ale_regs +
357                                              ALE_TABLE + 4 * i);
358
359         return idx;
360 }
361
362 static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry)
363 {
364         int i;
365
366         WARN_ON(idx > ale->params.ale_entries);
367
368         for (i = 0; i < ALE_ENTRY_WORDS; i++)
369                 writel_relaxed(ale_entry[i], ale->params.ale_regs +
370                                ALE_TABLE + 4 * i);
371
372         writel_relaxed(idx | ALE_TABLE_WRITE, ale->params.ale_regs +
373                        ALE_TABLE_CONTROL);
374
375         return idx;
376 }
377
378 static int cpsw_ale_match_addr(struct cpsw_ale *ale, const u8 *addr, u16 vid)
379 {
380         u32 ale_entry[ALE_ENTRY_WORDS];
381         int type, idx;
382
383         for (idx = 0; idx < ale->params.ale_entries; idx++) {
384                 u8 entry_addr[6];
385
386                 cpsw_ale_read(ale, idx, ale_entry);
387                 type = cpsw_ale_get_entry_type(ale_entry);
388                 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
389                         continue;
390                 if (cpsw_ale_get_vlan_id(ale_entry) != vid)
391                         continue;
392                 cpsw_ale_get_addr(ale_entry, entry_addr);
393                 if (ether_addr_equal(entry_addr, addr))
394                         return idx;
395         }
396         return -ENOENT;
397 }
398
399 static int cpsw_ale_match_vlan(struct cpsw_ale *ale, u16 vid)
400 {
401         u32 ale_entry[ALE_ENTRY_WORDS];
402         int type, idx;
403
404         for (idx = 0; idx < ale->params.ale_entries; idx++) {
405                 cpsw_ale_read(ale, idx, ale_entry);
406                 type = cpsw_ale_get_entry_type(ale_entry);
407                 if (type != ALE_TYPE_VLAN)
408                         continue;
409                 if (cpsw_ale_get_vlan_id(ale_entry) == vid)
410                         return idx;
411         }
412         return -ENOENT;
413 }
414
415 static int cpsw_ale_match_free(struct cpsw_ale *ale)
416 {
417         u32 ale_entry[ALE_ENTRY_WORDS];
418         int type, idx;
419
420         for (idx = 0; idx < ale->params.ale_entries; idx++) {
421                 cpsw_ale_read(ale, idx, ale_entry);
422                 type = cpsw_ale_get_entry_type(ale_entry);
423                 if (type == ALE_TYPE_FREE)
424                         return idx;
425         }
426         return -ENOENT;
427 }
428
429 static int cpsw_ale_find_ageable(struct cpsw_ale *ale)
430 {
431         u32 ale_entry[ALE_ENTRY_WORDS];
432         int type, idx;
433
434         for (idx = 0; idx < ale->params.ale_entries; idx++) {
435                 cpsw_ale_read(ale, idx, ale_entry);
436                 type = cpsw_ale_get_entry_type(ale_entry);
437                 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
438                         continue;
439                 if (cpsw_ale_get_mcast(ale_entry))
440                         continue;
441                 type = cpsw_ale_get_ucast_type(ale_entry);
442                 if (type != ALE_UCAST_PERSISTANT &&
443                     type != ALE_UCAST_OUI)
444                         return idx;
445         }
446         return -ENOENT;
447 }
448
449 static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry,
450                                  int port_mask)
451 {
452         int mask;
453
454         mask = cpsw_ale_get_port_mask(ale_entry,
455                                       ale->port_mask_bits);
456         if ((mask & port_mask) == 0)
457                 return; /* ports dont intersect, not interested */
458         mask &= ~port_mask;
459
460         /* free if only remaining port is host port */
461         if (mask)
462                 cpsw_ale_set_port_mask(ale_entry, mask,
463                                        ale->port_mask_bits);
464         else
465                 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
466 }
467
468 int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid)
469 {
470         u32 ale_entry[ALE_ENTRY_WORDS];
471         int ret, idx;
472
473         for (idx = 0; idx < ale->params.ale_entries; idx++) {
474                 cpsw_ale_read(ale, idx, ale_entry);
475                 ret = cpsw_ale_get_entry_type(ale_entry);
476                 if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR)
477                         continue;
478
479                 /* if vid passed is -1 then remove all multicast entry from
480                  * the table irrespective of vlan id, if a valid vlan id is
481                  * passed then remove only multicast added to that vlan id.
482                  * if vlan id doesn't match then move on to next entry.
483                  */
484                 if (vid != -1 && cpsw_ale_get_vlan_id(ale_entry) != vid)
485                         continue;
486
487                 if (cpsw_ale_get_mcast(ale_entry)) {
488                         u8 addr[6];
489
490                         if (cpsw_ale_get_super(ale_entry))
491                                 continue;
492
493                         cpsw_ale_get_addr(ale_entry, addr);
494                         if (!is_broadcast_ether_addr(addr))
495                                 cpsw_ale_flush_mcast(ale, ale_entry, port_mask);
496                 }
497
498                 cpsw_ale_write(ale, idx, ale_entry);
499         }
500         return 0;
501 }
502
503 static inline void cpsw_ale_set_vlan_entry_type(u32 *ale_entry,
504                                                 int flags, u16 vid)
505 {
506         if (flags & ALE_VLAN) {
507                 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN_ADDR);
508                 cpsw_ale_set_vlan_id(ale_entry, vid);
509         } else {
510                 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
511         }
512 }
513
514 int cpsw_ale_add_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
515                        int flags, u16 vid)
516 {
517         u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
518         int idx;
519
520         cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);
521
522         cpsw_ale_set_addr(ale_entry, addr);
523         cpsw_ale_set_ucast_type(ale_entry, ALE_UCAST_PERSISTANT);
524         cpsw_ale_set_secure(ale_entry, (flags & ALE_SECURE) ? 1 : 0);
525         cpsw_ale_set_blocked(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0);
526         cpsw_ale_set_port_num(ale_entry, port, ale->port_num_bits);
527
528         idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
529         if (idx < 0)
530                 idx = cpsw_ale_match_free(ale);
531         if (idx < 0)
532                 idx = cpsw_ale_find_ageable(ale);
533         if (idx < 0)
534                 return -ENOMEM;
535
536         cpsw_ale_write(ale, idx, ale_entry);
537         return 0;
538 }
539
540 int cpsw_ale_del_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
541                        int flags, u16 vid)
542 {
543         u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
544         int idx;
545
546         idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
547         if (idx < 0)
548                 return -ENOENT;
549
550         cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
551         cpsw_ale_write(ale, idx, ale_entry);
552         return 0;
553 }
554
555 int cpsw_ale_add_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
556                        int flags, u16 vid, int mcast_state)
557 {
558         u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
559         int idx, mask;
560
561         idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
562         if (idx >= 0)
563                 cpsw_ale_read(ale, idx, ale_entry);
564
565         cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);
566
567         cpsw_ale_set_addr(ale_entry, addr);
568         cpsw_ale_set_super(ale_entry, (flags & ALE_SUPER) ? 1 : 0);
569         cpsw_ale_set_mcast_state(ale_entry, mcast_state);
570
571         mask = cpsw_ale_get_port_mask(ale_entry,
572                                       ale->port_mask_bits);
573         port_mask |= mask;
574         cpsw_ale_set_port_mask(ale_entry, port_mask,
575                                ale->port_mask_bits);
576
577         if (idx < 0)
578                 idx = cpsw_ale_match_free(ale);
579         if (idx < 0)
580                 idx = cpsw_ale_find_ageable(ale);
581         if (idx < 0)
582                 return -ENOMEM;
583
584         cpsw_ale_write(ale, idx, ale_entry);
585         return 0;
586 }
587
588 int cpsw_ale_del_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
589                        int flags, u16 vid)
590 {
591         u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
592         int mcast_members = 0;
593         int idx;
594
595         idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
596         if (idx < 0)
597                 return -ENOENT;
598
599         cpsw_ale_read(ale, idx, ale_entry);
600
601         if (port_mask) {
602                 mcast_members = cpsw_ale_get_port_mask(ale_entry,
603                                                        ale->port_mask_bits);
604                 mcast_members &= ~port_mask;
605         }
606
607         if (mcast_members)
608                 cpsw_ale_set_port_mask(ale_entry, mcast_members,
609                                        ale->port_mask_bits);
610         else
611                 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
612
613         cpsw_ale_write(ale, idx, ale_entry);
614         return 0;
615 }
616
617 /* ALE NetCP NU switch specific vlan functions */
618 static void cpsw_ale_set_vlan_mcast(struct cpsw_ale *ale, u32 *ale_entry,
619                                     int reg_mcast, int unreg_mcast)
620 {
621         int idx;
622
623         /* Set VLAN registered multicast flood mask */
624         idx = cpsw_ale_vlan_get_fld(ale, ale_entry,
625                                     ALE_ENT_VID_REG_MCAST_IDX);
626         writel(reg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
627
628         /* Set VLAN unregistered multicast flood mask */
629         idx = cpsw_ale_vlan_get_fld(ale, ale_entry,
630                                     ALE_ENT_VID_UNREG_MCAST_IDX);
631         writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
632 }
633
634 static void cpsw_ale_set_vlan_untag(struct cpsw_ale *ale, u32 *ale_entry,
635                                     u16 vid, int untag_mask)
636 {
637         cpsw_ale_vlan_set_fld(ale, ale_entry,
638                               ALE_ENT_VID_FORCE_UNTAGGED_MSK,
639                               untag_mask);
640         if (untag_mask & ALE_PORT_HOST)
641                 bitmap_set(ale->p0_untag_vid_mask, vid, 1);
642         else
643                 bitmap_clear(ale->p0_untag_vid_mask, vid, 1);
644 }
645
646 int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port_mask, int untag,
647                       int reg_mcast, int unreg_mcast)
648 {
649         u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
650         int idx;
651
652         idx = cpsw_ale_match_vlan(ale, vid);
653         if (idx >= 0)
654                 cpsw_ale_read(ale, idx, ale_entry);
655
656         cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN);
657         cpsw_ale_set_vlan_id(ale_entry, vid);
658         cpsw_ale_set_vlan_untag(ale, ale_entry, vid, untag);
659
660         if (!ale->params.nu_switch_ale) {
661                 cpsw_ale_vlan_set_fld(ale, ale_entry,
662                                       ALE_ENT_VID_REG_MCAST_MSK, reg_mcast);
663                 cpsw_ale_vlan_set_fld(ale, ale_entry,
664                                       ALE_ENT_VID_UNREG_MCAST_MSK, unreg_mcast);
665         } else {
666                 cpsw_ale_vlan_set_fld(ale, ale_entry,
667                                       ALE_ENT_VID_UNREG_MCAST_IDX,
668                                       NU_VLAN_UNREG_MCAST_IDX);
669                 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast, unreg_mcast);
670         }
671
672         cpsw_ale_vlan_set_fld(ale, ale_entry,
673                               ALE_ENT_VID_MEMBER_LIST, port_mask);
674
675         if (idx < 0)
676                 idx = cpsw_ale_match_free(ale);
677         if (idx < 0)
678                 idx = cpsw_ale_find_ageable(ale);
679         if (idx < 0)
680                 return -ENOMEM;
681
682         cpsw_ale_write(ale, idx, ale_entry);
683         return 0;
684 }
685
686 static void cpsw_ale_vlan_del_modify_int(struct cpsw_ale *ale,  u32 *ale_entry,
687                                          u16 vid, int port_mask)
688 {
689         int reg_mcast, unreg_mcast;
690         int members, untag;
691
692         members = cpsw_ale_vlan_get_fld(ale, ale_entry,
693                                         ALE_ENT_VID_MEMBER_LIST);
694         members &= ~port_mask;
695         if (!members) {
696                 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, 0);
697                 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
698                 return;
699         }
700
701         untag = cpsw_ale_vlan_get_fld(ale, ale_entry,
702                                       ALE_ENT_VID_FORCE_UNTAGGED_MSK);
703         reg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry,
704                                           ALE_ENT_VID_REG_MCAST_MSK);
705         unreg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry,
706                                             ALE_ENT_VID_UNREG_MCAST_MSK);
707         untag &= members;
708         reg_mcast &= members;
709         unreg_mcast &= members;
710
711         cpsw_ale_set_vlan_untag(ale, ale_entry, vid, untag);
712
713         if (!ale->params.nu_switch_ale) {
714                 cpsw_ale_vlan_set_fld(ale, ale_entry,
715                                       ALE_ENT_VID_REG_MCAST_MSK, reg_mcast);
716                 cpsw_ale_vlan_set_fld(ale, ale_entry,
717                                       ALE_ENT_VID_UNREG_MCAST_MSK, unreg_mcast);
718         } else {
719                 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast,
720                                         unreg_mcast);
721         }
722         cpsw_ale_vlan_set_fld(ale, ale_entry,
723                               ALE_ENT_VID_MEMBER_LIST, members);
724 }
725
726 int cpsw_ale_vlan_del_modify(struct cpsw_ale *ale, u16 vid, int port_mask)
727 {
728         u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
729         int idx;
730
731         idx = cpsw_ale_match_vlan(ale, vid);
732         if (idx < 0)
733                 return -ENOENT;
734
735         cpsw_ale_read(ale, idx, ale_entry);
736
737         cpsw_ale_vlan_del_modify_int(ale, ale_entry, vid, port_mask);
738         cpsw_ale_write(ale, idx, ale_entry);
739
740         return 0;
741 }
742
743 int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask)
744 {
745         u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
746         int members, idx;
747
748         idx = cpsw_ale_match_vlan(ale, vid);
749         if (idx < 0)
750                 return -ENOENT;
751
752         cpsw_ale_read(ale, idx, ale_entry);
753
754         /* if !port_mask - force remove VLAN (legacy).
755          * Check if there are other VLAN members ports
756          * if no - remove VLAN.
757          * if yes it means same VLAN was added to >1 port in multi port mode, so
758          * remove port_mask ports from VLAN ALE entry excluding Host port.
759          */
760         members = cpsw_ale_vlan_get_fld(ale, ale_entry, ALE_ENT_VID_MEMBER_LIST);
761         members &= ~port_mask;
762
763         if (!port_mask || !members) {
764                 /* last port or force remove - remove VLAN */
765                 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, 0);
766                 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
767         } else {
768                 port_mask &= ~ALE_PORT_HOST;
769                 cpsw_ale_vlan_del_modify_int(ale, ale_entry, vid, port_mask);
770         }
771
772         cpsw_ale_write(ale, idx, ale_entry);
773
774         return 0;
775 }
776
777 int cpsw_ale_vlan_add_modify(struct cpsw_ale *ale, u16 vid, int port_mask,
778                              int untag_mask, int reg_mask, int unreg_mask)
779 {
780         u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
781         int reg_mcast_members, unreg_mcast_members;
782         int vlan_members, untag_members;
783         int idx, ret = 0;
784
785         idx = cpsw_ale_match_vlan(ale, vid);
786         if (idx >= 0)
787                 cpsw_ale_read(ale, idx, ale_entry);
788
789         vlan_members = cpsw_ale_vlan_get_fld(ale, ale_entry,
790                                              ALE_ENT_VID_MEMBER_LIST);
791         reg_mcast_members = cpsw_ale_vlan_get_fld(ale, ale_entry,
792                                                   ALE_ENT_VID_REG_MCAST_MSK);
793         unreg_mcast_members =
794                 cpsw_ale_vlan_get_fld(ale, ale_entry,
795                                       ALE_ENT_VID_UNREG_MCAST_MSK);
796         untag_members = cpsw_ale_vlan_get_fld(ale, ale_entry,
797                                               ALE_ENT_VID_FORCE_UNTAGGED_MSK);
798
799         vlan_members |= port_mask;
800         untag_members = (untag_members & ~port_mask) | untag_mask;
801         reg_mcast_members = (reg_mcast_members & ~port_mask) | reg_mask;
802         unreg_mcast_members = (unreg_mcast_members & ~port_mask) | unreg_mask;
803
804         ret = cpsw_ale_add_vlan(ale, vid, vlan_members, untag_members,
805                                 reg_mcast_members, unreg_mcast_members);
806         if (ret) {
807                 dev_err(ale->params.dev, "Unable to add vlan\n");
808                 return ret;
809         }
810         dev_dbg(ale->params.dev, "port mask 0x%x untag 0x%x\n", vlan_members,
811                 untag_mask);
812
813         return ret;
814 }
815
816 void cpsw_ale_set_unreg_mcast(struct cpsw_ale *ale, int unreg_mcast_mask,
817                               bool add)
818 {
819         u32 ale_entry[ALE_ENTRY_WORDS];
820         int unreg_members = 0;
821         int type, idx;
822
823         for (idx = 0; idx < ale->params.ale_entries; idx++) {
824                 cpsw_ale_read(ale, idx, ale_entry);
825                 type = cpsw_ale_get_entry_type(ale_entry);
826                 if (type != ALE_TYPE_VLAN)
827                         continue;
828
829                 unreg_members =
830                         cpsw_ale_vlan_get_fld(ale, ale_entry,
831                                               ALE_ENT_VID_UNREG_MCAST_MSK);
832                 if (add)
833                         unreg_members |= unreg_mcast_mask;
834                 else
835                         unreg_members &= ~unreg_mcast_mask;
836                 cpsw_ale_vlan_set_fld(ale, ale_entry,
837                                       ALE_ENT_VID_UNREG_MCAST_MSK,
838                                       unreg_members);
839                 cpsw_ale_write(ale, idx, ale_entry);
840         }
841 }
842
843 static void cpsw_ale_vlan_set_unreg_mcast(struct cpsw_ale *ale, u32 *ale_entry,
844                                           int allmulti)
845 {
846         int unreg_mcast;
847
848         unreg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry,
849                                             ALE_ENT_VID_UNREG_MCAST_MSK);
850         if (allmulti)
851                 unreg_mcast |= ALE_PORT_HOST;
852         else
853                 unreg_mcast &= ~ALE_PORT_HOST;
854
855         cpsw_ale_vlan_set_fld(ale, ale_entry,
856                               ALE_ENT_VID_UNREG_MCAST_MSK, unreg_mcast);
857 }
858
859 static void
860 cpsw_ale_vlan_set_unreg_mcast_idx(struct cpsw_ale *ale, u32 *ale_entry,
861                                   int allmulti)
862 {
863         int unreg_mcast;
864         int idx;
865
866         idx = cpsw_ale_vlan_get_fld(ale, ale_entry,
867                                     ALE_ENT_VID_UNREG_MCAST_IDX);
868
869         unreg_mcast = readl(ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
870
871         if (allmulti)
872                 unreg_mcast |= ALE_PORT_HOST;
873         else
874                 unreg_mcast &= ~ALE_PORT_HOST;
875
876         writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
877 }
878
879 void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti, int port)
880 {
881         u32 ale_entry[ALE_ENTRY_WORDS];
882         int type, idx;
883
884         for (idx = 0; idx < ale->params.ale_entries; idx++) {
885                 int vlan_members;
886
887                 cpsw_ale_read(ale, idx, ale_entry);
888                 type = cpsw_ale_get_entry_type(ale_entry);
889                 if (type != ALE_TYPE_VLAN)
890                         continue;
891
892                 vlan_members = cpsw_ale_vlan_get_fld(ale, ale_entry,
893                                                      ALE_ENT_VID_MEMBER_LIST);
894
895                 if (port != -1 && !(vlan_members & BIT(port)))
896                         continue;
897
898                 if (!ale->params.nu_switch_ale)
899                         cpsw_ale_vlan_set_unreg_mcast(ale, ale_entry, allmulti);
900                 else
901                         cpsw_ale_vlan_set_unreg_mcast_idx(ale, ale_entry,
902                                                           allmulti);
903
904                 cpsw_ale_write(ale, idx, ale_entry);
905         }
906 }
907
908 struct ale_control_info {
909         const char      *name;
910         int             offset, port_offset;
911         int             shift, port_shift;
912         int             bits;
913 };
914
915 static struct ale_control_info ale_controls[ALE_NUM_CONTROLS] = {
916         [ALE_ENABLE]            = {
917                 .name           = "enable",
918                 .offset         = ALE_CONTROL,
919                 .port_offset    = 0,
920                 .shift          = 31,
921                 .port_shift     = 0,
922                 .bits           = 1,
923         },
924         [ALE_CLEAR]             = {
925                 .name           = "clear",
926                 .offset         = ALE_CONTROL,
927                 .port_offset    = 0,
928                 .shift          = 30,
929                 .port_shift     = 0,
930                 .bits           = 1,
931         },
932         [ALE_AGEOUT]            = {
933                 .name           = "ageout",
934                 .offset         = ALE_CONTROL,
935                 .port_offset    = 0,
936                 .shift          = 29,
937                 .port_shift     = 0,
938                 .bits           = 1,
939         },
940         [ALE_P0_UNI_FLOOD]      = {
941                 .name           = "port0_unicast_flood",
942                 .offset         = ALE_CONTROL,
943                 .port_offset    = 0,
944                 .shift          = 8,
945                 .port_shift     = 0,
946                 .bits           = 1,
947         },
948         [ALE_VLAN_NOLEARN]      = {
949                 .name           = "vlan_nolearn",
950                 .offset         = ALE_CONTROL,
951                 .port_offset    = 0,
952                 .shift          = 7,
953                 .port_shift     = 0,
954                 .bits           = 1,
955         },
956         [ALE_NO_PORT_VLAN]      = {
957                 .name           = "no_port_vlan",
958                 .offset         = ALE_CONTROL,
959                 .port_offset    = 0,
960                 .shift          = 6,
961                 .port_shift     = 0,
962                 .bits           = 1,
963         },
964         [ALE_OUI_DENY]          = {
965                 .name           = "oui_deny",
966                 .offset         = ALE_CONTROL,
967                 .port_offset    = 0,
968                 .shift          = 5,
969                 .port_shift     = 0,
970                 .bits           = 1,
971         },
972         [ALE_BYPASS]            = {
973                 .name           = "bypass",
974                 .offset         = ALE_CONTROL,
975                 .port_offset    = 0,
976                 .shift          = 4,
977                 .port_shift     = 0,
978                 .bits           = 1,
979         },
980         [ALE_RATE_LIMIT_TX]     = {
981                 .name           = "rate_limit_tx",
982                 .offset         = ALE_CONTROL,
983                 .port_offset    = 0,
984                 .shift          = 3,
985                 .port_shift     = 0,
986                 .bits           = 1,
987         },
988         [ALE_VLAN_AWARE]        = {
989                 .name           = "vlan_aware",
990                 .offset         = ALE_CONTROL,
991                 .port_offset    = 0,
992                 .shift          = 2,
993                 .port_shift     = 0,
994                 .bits           = 1,
995         },
996         [ALE_AUTH_ENABLE]       = {
997                 .name           = "auth_enable",
998                 .offset         = ALE_CONTROL,
999                 .port_offset    = 0,
1000                 .shift          = 1,
1001                 .port_shift     = 0,
1002                 .bits           = 1,
1003         },
1004         [ALE_RATE_LIMIT]        = {
1005                 .name           = "rate_limit",
1006                 .offset         = ALE_CONTROL,
1007                 .port_offset    = 0,
1008                 .shift          = 0,
1009                 .port_shift     = 0,
1010                 .bits           = 1,
1011         },
1012         [ALE_PORT_STATE]        = {
1013                 .name           = "port_state",
1014                 .offset         = ALE_PORTCTL,
1015                 .port_offset    = 4,
1016                 .shift          = 0,
1017                 .port_shift     = 0,
1018                 .bits           = 2,
1019         },
1020         [ALE_PORT_DROP_UNTAGGED] = {
1021                 .name           = "drop_untagged",
1022                 .offset         = ALE_PORTCTL,
1023                 .port_offset    = 4,
1024                 .shift          = 2,
1025                 .port_shift     = 0,
1026                 .bits           = 1,
1027         },
1028         [ALE_PORT_DROP_UNKNOWN_VLAN] = {
1029                 .name           = "drop_unknown",
1030                 .offset         = ALE_PORTCTL,
1031                 .port_offset    = 4,
1032                 .shift          = 3,
1033                 .port_shift     = 0,
1034                 .bits           = 1,
1035         },
1036         [ALE_PORT_NOLEARN]      = {
1037                 .name           = "nolearn",
1038                 .offset         = ALE_PORTCTL,
1039                 .port_offset    = 4,
1040                 .shift          = 4,
1041                 .port_shift     = 0,
1042                 .bits           = 1,
1043         },
1044         [ALE_PORT_NO_SA_UPDATE] = {
1045                 .name           = "no_source_update",
1046                 .offset         = ALE_PORTCTL,
1047                 .port_offset    = 4,
1048                 .shift          = 5,
1049                 .port_shift     = 0,
1050                 .bits           = 1,
1051         },
1052         [ALE_PORT_MACONLY]      = {
1053                 .name           = "mac_only_port_mode",
1054                 .offset         = ALE_PORTCTL,
1055                 .port_offset    = 4,
1056                 .shift          = 11,
1057                 .port_shift     = 0,
1058                 .bits           = 1,
1059         },
1060         [ALE_PORT_MACONLY_CAF]  = {
1061                 .name           = "mac_only_port_caf",
1062                 .offset         = ALE_PORTCTL,
1063                 .port_offset    = 4,
1064                 .shift          = 13,
1065                 .port_shift     = 0,
1066                 .bits           = 1,
1067         },
1068         [ALE_PORT_MCAST_LIMIT]  = {
1069                 .name           = "mcast_limit",
1070                 .offset         = ALE_PORTCTL,
1071                 .port_offset    = 4,
1072                 .shift          = 16,
1073                 .port_shift     = 0,
1074                 .bits           = 8,
1075         },
1076         [ALE_PORT_BCAST_LIMIT]  = {
1077                 .name           = "bcast_limit",
1078                 .offset         = ALE_PORTCTL,
1079                 .port_offset    = 4,
1080                 .shift          = 24,
1081                 .port_shift     = 0,
1082                 .bits           = 8,
1083         },
1084         [ALE_PORT_UNKNOWN_VLAN_MEMBER] = {
1085                 .name           = "unknown_vlan_member",
1086                 .offset         = ALE_UNKNOWNVLAN,
1087                 .port_offset    = 0,
1088                 .shift          = 0,
1089                 .port_shift     = 0,
1090                 .bits           = 6,
1091         },
1092         [ALE_PORT_UNKNOWN_MCAST_FLOOD] = {
1093                 .name           = "unknown_mcast_flood",
1094                 .offset         = ALE_UNKNOWNVLAN,
1095                 .port_offset    = 0,
1096                 .shift          = 8,
1097                 .port_shift     = 0,
1098                 .bits           = 6,
1099         },
1100         [ALE_PORT_UNKNOWN_REG_MCAST_FLOOD] = {
1101                 .name           = "unknown_reg_flood",
1102                 .offset         = ALE_UNKNOWNVLAN,
1103                 .port_offset    = 0,
1104                 .shift          = 16,
1105                 .port_shift     = 0,
1106                 .bits           = 6,
1107         },
1108         [ALE_PORT_UNTAGGED_EGRESS] = {
1109                 .name           = "untagged_egress",
1110                 .offset         = ALE_UNKNOWNVLAN,
1111                 .port_offset    = 0,
1112                 .shift          = 24,
1113                 .port_shift     = 0,
1114                 .bits           = 6,
1115         },
1116         [ALE_DEFAULT_THREAD_ID] = {
1117                 .name           = "default_thread_id",
1118                 .offset         = AM65_CPSW_ALE_THREAD_DEF_REG,
1119                 .port_offset    = 0,
1120                 .shift          = 0,
1121                 .port_shift     = 0,
1122                 .bits           = 6,
1123         },
1124         [ALE_DEFAULT_THREAD_ENABLE] = {
1125                 .name           = "default_thread_id_enable",
1126                 .offset         = AM65_CPSW_ALE_THREAD_DEF_REG,
1127                 .port_offset    = 0,
1128                 .shift          = 15,
1129                 .port_shift     = 0,
1130                 .bits           = 1,
1131         },
1132 };
1133
1134 int cpsw_ale_control_set(struct cpsw_ale *ale, int port, int control,
1135                          int value)
1136 {
1137         const struct ale_control_info *info;
1138         int offset, shift;
1139         u32 tmp, mask;
1140
1141         if (control < 0 || control >= ARRAY_SIZE(ale_controls))
1142                 return -EINVAL;
1143
1144         info = &ale_controls[control];
1145         if (info->port_offset == 0 && info->port_shift == 0)
1146                 port = 0; /* global, port is a dont care */
1147
1148         if (port < 0 || port >= ale->params.ale_ports)
1149                 return -EINVAL;
1150
1151         mask = BITMASK(info->bits);
1152         if (value & ~mask)
1153                 return -EINVAL;
1154
1155         offset = info->offset + (port * info->port_offset);
1156         shift  = info->shift  + (port * info->port_shift);
1157
1158         tmp = readl_relaxed(ale->params.ale_regs + offset);
1159         tmp = (tmp & ~(mask << shift)) | (value << shift);
1160         writel_relaxed(tmp, ale->params.ale_regs + offset);
1161
1162         return 0;
1163 }
1164
1165 int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control)
1166 {
1167         const struct ale_control_info *info;
1168         int offset, shift;
1169         u32 tmp;
1170
1171         if (control < 0 || control >= ARRAY_SIZE(ale_controls))
1172                 return -EINVAL;
1173
1174         info = &ale_controls[control];
1175         if (info->port_offset == 0 && info->port_shift == 0)
1176                 port = 0; /* global, port is a dont care */
1177
1178         if (port < 0 || port >= ale->params.ale_ports)
1179                 return -EINVAL;
1180
1181         offset = info->offset + (port * info->port_offset);
1182         shift  = info->shift  + (port * info->port_shift);
1183
1184         tmp = readl_relaxed(ale->params.ale_regs + offset) >> shift;
1185         return tmp & BITMASK(info->bits);
1186 }
1187
1188 int cpsw_ale_rx_ratelimit_mc(struct cpsw_ale *ale, int port, unsigned int ratelimit_pps)
1189
1190 {
1191         int val = ratelimit_pps / ALE_RATE_LIMIT_MIN_PPS;
1192         u32 remainder = ratelimit_pps % ALE_RATE_LIMIT_MIN_PPS;
1193
1194         if (ratelimit_pps && !val) {
1195                 dev_err(ale->params.dev, "ALE MC port:%d ratelimit min value 1000pps\n", port);
1196                 return -EINVAL;
1197         }
1198
1199         if (remainder)
1200                 dev_info(ale->params.dev, "ALE port:%d MC ratelimit set to %dpps (requested %d)\n",
1201                          port, ratelimit_pps - remainder, ratelimit_pps);
1202
1203         cpsw_ale_control_set(ale, port, ALE_PORT_MCAST_LIMIT, val);
1204
1205         dev_dbg(ale->params.dev, "ALE port:%d MC ratelimit set %d\n",
1206                 port, val * ALE_RATE_LIMIT_MIN_PPS);
1207         return 0;
1208 }
1209
1210 int cpsw_ale_rx_ratelimit_bc(struct cpsw_ale *ale, int port, unsigned int ratelimit_pps)
1211
1212 {
1213         int val = ratelimit_pps / ALE_RATE_LIMIT_MIN_PPS;
1214         u32 remainder = ratelimit_pps % ALE_RATE_LIMIT_MIN_PPS;
1215
1216         if (ratelimit_pps && !val) {
1217                 dev_err(ale->params.dev, "ALE port:%d BC ratelimit min value 1000pps\n", port);
1218                 return -EINVAL;
1219         }
1220
1221         if (remainder)
1222                 dev_info(ale->params.dev, "ALE port:%d BC ratelimit set to %dpps (requested %d)\n",
1223                          port, ratelimit_pps - remainder, ratelimit_pps);
1224
1225         cpsw_ale_control_set(ale, port, ALE_PORT_BCAST_LIMIT, val);
1226
1227         dev_dbg(ale->params.dev, "ALE port:%d BC ratelimit set %d\n",
1228                 port, val * ALE_RATE_LIMIT_MIN_PPS);
1229         return 0;
1230 }
1231
1232 static void cpsw_ale_timer(struct timer_list *t)
1233 {
1234         struct cpsw_ale *ale = from_timer(ale, t, timer);
1235
1236         cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
1237
1238         if (ale->ageout) {
1239                 ale->timer.expires = jiffies + ale->ageout;
1240                 add_timer(&ale->timer);
1241         }
1242 }
1243
1244 static void cpsw_ale_hw_aging_timer_start(struct cpsw_ale *ale)
1245 {
1246         u32 aging_timer;
1247
1248         aging_timer = ale->params.bus_freq / 1000000;
1249         aging_timer *= ale->params.ale_ageout;
1250
1251         if (aging_timer & ~ALE_AGING_TIMER_MASK) {
1252                 aging_timer = ALE_AGING_TIMER_MASK;
1253                 dev_warn(ale->params.dev,
1254                          "ALE aging timer overflow, set to max\n");
1255         }
1256
1257         writel(aging_timer, ale->params.ale_regs + ALE_AGING_TIMER);
1258 }
1259
1260 static void cpsw_ale_hw_aging_timer_stop(struct cpsw_ale *ale)
1261 {
1262         writel(0, ale->params.ale_regs + ALE_AGING_TIMER);
1263 }
1264
1265 static void cpsw_ale_aging_start(struct cpsw_ale *ale)
1266 {
1267         if (!ale->params.ale_ageout)
1268                 return;
1269
1270         if (ale->features & CPSW_ALE_F_HW_AUTOAGING) {
1271                 cpsw_ale_hw_aging_timer_start(ale);
1272                 return;
1273         }
1274
1275         timer_setup(&ale->timer, cpsw_ale_timer, 0);
1276         ale->timer.expires = jiffies + ale->ageout;
1277         add_timer(&ale->timer);
1278 }
1279
1280 static void cpsw_ale_aging_stop(struct cpsw_ale *ale)
1281 {
1282         if (!ale->params.ale_ageout)
1283                 return;
1284
1285         if (ale->features & CPSW_ALE_F_HW_AUTOAGING) {
1286                 cpsw_ale_hw_aging_timer_stop(ale);
1287                 return;
1288         }
1289
1290         del_timer_sync(&ale->timer);
1291 }
1292
1293 void cpsw_ale_start(struct cpsw_ale *ale)
1294 {
1295         unsigned long ale_prescale;
1296
1297         /* configure Broadcast and Multicast Rate Limit
1298          * number_of_packets = (Fclk / ALE_PRESCALE) * port.BCAST/MCAST_LIMIT
1299          * ALE_PRESCALE width is 19bit and min value 0x10
1300          * port.BCAST/MCAST_LIMIT is 8bit
1301          *
1302          * For multi port configuration support the ALE_PRESCALE is configured to 1ms interval,
1303          * which allows to configure port.BCAST/MCAST_LIMIT per port and achieve:
1304          * min number_of_packets = 1000 when port.BCAST/MCAST_LIMIT = 1
1305          * max number_of_packets = 1000 * 255 = 255000 when port.BCAST/MCAST_LIMIT = 0xFF
1306          */
1307         ale_prescale = ale->params.bus_freq / ALE_RATE_LIMIT_MIN_PPS;
1308         writel((u32)ale_prescale, ale->params.ale_regs + ALE_PRESCALE);
1309
1310         /* Allow MC/BC rate limiting globally.
1311          * The actual Rate Limit cfg enabled per-port by port.BCAST/MCAST_LIMIT
1312          */
1313         cpsw_ale_control_set(ale, 0, ALE_RATE_LIMIT, 1);
1314
1315         cpsw_ale_control_set(ale, 0, ALE_ENABLE, 1);
1316         cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
1317
1318         cpsw_ale_aging_start(ale);
1319 }
1320
1321 void cpsw_ale_stop(struct cpsw_ale *ale)
1322 {
1323         cpsw_ale_aging_stop(ale);
1324         cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
1325         cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0);
1326 }
1327
1328 static const struct reg_field ale_fields_cpsw[] = {
1329         /* CPSW_ALE_IDVER_REG */
1330         [MINOR_VER]     = REG_FIELD(ALE_IDVER, 0, 7),
1331         [MAJOR_VER]     = REG_FIELD(ALE_IDVER, 8, 15),
1332 };
1333
1334 static const struct reg_field ale_fields_cpsw_nu[] = {
1335         /* CPSW_ALE_IDVER_REG */
1336         [MINOR_VER]     = REG_FIELD(ALE_IDVER, 0, 7),
1337         [MAJOR_VER]     = REG_FIELD(ALE_IDVER, 8, 10),
1338         /* CPSW_ALE_STATUS_REG */
1339         [ALE_ENTRIES]   = REG_FIELD(ALE_STATUS, 0, 7),
1340         [ALE_POLICERS]  = REG_FIELD(ALE_STATUS, 8, 15),
1341         /* CPSW_ALE_POLICER_PORT_OUI_REG */
1342         [POL_PORT_MEN]  = REG_FIELD(ALE_POLICER_PORT_OUI, 31, 31),
1343         [POL_TRUNK_ID]  = REG_FIELD(ALE_POLICER_PORT_OUI, 30, 30),
1344         [POL_PORT_NUM]  = REG_FIELD(ALE_POLICER_PORT_OUI, 25, 25),
1345         [POL_PRI_MEN]   = REG_FIELD(ALE_POLICER_PORT_OUI, 19, 19),
1346         [POL_PRI_VAL]   = REG_FIELD(ALE_POLICER_PORT_OUI, 16, 18),
1347         [POL_OUI_MEN]   = REG_FIELD(ALE_POLICER_PORT_OUI, 15, 15),
1348         [POL_OUI_INDEX] = REG_FIELD(ALE_POLICER_PORT_OUI, 0, 5),
1349
1350         /* CPSW_ALE_POLICER_DA_SA_REG */
1351         [POL_DST_MEN]   = REG_FIELD(ALE_POLICER_DA_SA, 31, 31),
1352         [POL_DST_INDEX] = REG_FIELD(ALE_POLICER_DA_SA, 16, 21),
1353         [POL_SRC_MEN]   = REG_FIELD(ALE_POLICER_DA_SA, 15, 15),
1354         [POL_SRC_INDEX] = REG_FIELD(ALE_POLICER_DA_SA, 0, 5),
1355
1356         /* CPSW_ALE_POLICER_VLAN_REG */
1357         [POL_OVLAN_MEN]         = REG_FIELD(ALE_POLICER_VLAN, 31, 31),
1358         [POL_OVLAN_INDEX]       = REG_FIELD(ALE_POLICER_VLAN, 16, 21),
1359         [POL_IVLAN_MEN]         = REG_FIELD(ALE_POLICER_VLAN, 15, 15),
1360         [POL_IVLAN_INDEX]       = REG_FIELD(ALE_POLICER_VLAN, 0, 5),
1361
1362         /* CPSW_ALE_POLICER_ETHERTYPE_IPSA_REG */
1363         [POL_ETHERTYPE_MEN]     = REG_FIELD(ALE_POLICER_ETHERTYPE_IPSA, 31, 31),
1364         [POL_ETHERTYPE_INDEX]   = REG_FIELD(ALE_POLICER_ETHERTYPE_IPSA, 16, 21),
1365         [POL_IPSRC_MEN]         = REG_FIELD(ALE_POLICER_ETHERTYPE_IPSA, 15, 15),
1366         [POL_IPSRC_INDEX]       = REG_FIELD(ALE_POLICER_ETHERTYPE_IPSA, 0, 5),
1367
1368         /* CPSW_ALE_POLICER_IPDA_REG */
1369         [POL_IPDST_MEN]         = REG_FIELD(ALE_POLICER_IPDA, 31, 31),
1370         [POL_IPDST_INDEX]       = REG_FIELD(ALE_POLICER_IPDA, 16, 21),
1371
1372         /* CPSW_ALE_POLICER_TBL_CTL_REG */
1373         /**
1374          * REG_FIELDS not defined for this as fields cannot be correctly
1375          * used independently
1376          */
1377
1378         /* CPSW_ALE_POLICER_CTL_REG */
1379         [POL_EN]                = REG_FIELD(ALE_POLICER_CTL, 31, 31),
1380         [POL_RED_DROP_EN]       = REG_FIELD(ALE_POLICER_CTL, 29, 29),
1381         [POL_YELLOW_DROP_EN]    = REG_FIELD(ALE_POLICER_CTL, 28, 28),
1382         [POL_YELLOW_THRESH]     = REG_FIELD(ALE_POLICER_CTL, 24, 26),
1383         [POL_POL_MATCH_MODE]    = REG_FIELD(ALE_POLICER_CTL, 22, 23),
1384         [POL_PRIORITY_THREAD_EN] = REG_FIELD(ALE_POLICER_CTL, 21, 21),
1385         [POL_MAC_ONLY_DEF_DIS]  = REG_FIELD(ALE_POLICER_CTL, 20, 20),
1386
1387         /* CPSW_ALE_POLICER_TEST_CTL_REG */
1388         [POL_TEST_CLR]          = REG_FIELD(ALE_POLICER_TEST_CTL, 31, 31),
1389         [POL_TEST_CLR_RED]      = REG_FIELD(ALE_POLICER_TEST_CTL, 30, 30),
1390         [POL_TEST_CLR_YELLOW]   = REG_FIELD(ALE_POLICER_TEST_CTL, 29, 29),
1391         [POL_TEST_CLR_SELECTED] = REG_FIELD(ALE_POLICER_TEST_CTL, 28, 28),
1392         [POL_TEST_ENTRY]        = REG_FIELD(ALE_POLICER_TEST_CTL, 0, 4),
1393
1394         /* CPSW_ALE_POLICER_HIT_STATUS_REG */
1395         [POL_STATUS_HIT]        = REG_FIELD(ALE_POLICER_HIT_STATUS, 31, 31),
1396         [POL_STATUS_HIT_RED]    = REG_FIELD(ALE_POLICER_HIT_STATUS, 30, 30),
1397         [POL_STATUS_HIT_YELLOW] = REG_FIELD(ALE_POLICER_HIT_STATUS, 29, 29),
1398
1399         /* CPSW_ALE_THREAD_DEF_REG */
1400         [ALE_DEFAULT_THREAD_EN]         = REG_FIELD(ALE_THREAD_DEF, 15, 15),
1401         [ALE_DEFAULT_THREAD_VAL]        = REG_FIELD(ALE_THREAD_DEF, 0, 5),
1402
1403         /* CPSW_ALE_THREAD_CTL_REG */
1404         [ALE_THREAD_CLASS_INDEX] = REG_FIELD(ALE_THREAD_CTL, 0, 4),
1405
1406         /* CPSW_ALE_THREAD_VAL_REG */
1407         [ALE_THREAD_ENABLE]     = REG_FIELD(ALE_THREAD_VAL, 15, 15),
1408         [ALE_THREAD_VALUE]      = REG_FIELD(ALE_THREAD_VAL, 0, 5),
1409 };
1410
1411 static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = {
1412         {
1413                 /* am3/4/5, dra7. dm814x, 66ak2hk-gbe */
1414                 .dev_id = "cpsw",
1415                 .tbl_entries = 1024,
1416                 .reg_fields = ale_fields_cpsw,
1417                 .num_fields = ARRAY_SIZE(ale_fields_cpsw),
1418                 .vlan_entry_tbl = vlan_entry_cpsw,
1419         },
1420         {
1421                 /* 66ak2h_xgbe */
1422                 .dev_id = "66ak2h-xgbe",
1423                 .tbl_entries = 2048,
1424                 .reg_fields = ale_fields_cpsw,
1425                 .num_fields = ARRAY_SIZE(ale_fields_cpsw),
1426                 .vlan_entry_tbl = vlan_entry_cpsw,
1427         },
1428         {
1429                 .dev_id = "66ak2el",
1430                 .features = CPSW_ALE_F_STATUS_REG,
1431                 .reg_fields = ale_fields_cpsw_nu,
1432                 .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu),
1433                 .nu_switch_ale = true,
1434                 .vlan_entry_tbl = vlan_entry_nu,
1435         },
1436         {
1437                 .dev_id = "66ak2g",
1438                 .features = CPSW_ALE_F_STATUS_REG,
1439                 .tbl_entries = 64,
1440                 .reg_fields = ale_fields_cpsw_nu,
1441                 .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu),
1442                 .nu_switch_ale = true,
1443                 .vlan_entry_tbl = vlan_entry_nu,
1444         },
1445         {
1446                 .dev_id = "am65x-cpsw2g",
1447                 .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
1448                 .tbl_entries = 64,
1449                 .reg_fields = ale_fields_cpsw_nu,
1450                 .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu),
1451                 .nu_switch_ale = true,
1452                 .vlan_entry_tbl = vlan_entry_nu,
1453         },
1454         {
1455                 .dev_id = "j721e-cpswxg",
1456                 .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
1457                 .reg_fields = ale_fields_cpsw_nu,
1458                 .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu),
1459                 .vlan_entry_tbl = vlan_entry_k3_cpswxg,
1460         },
1461         {
1462                 .dev_id = "am64-cpswxg",
1463                 .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
1464                 .reg_fields = ale_fields_cpsw_nu,
1465                 .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu),
1466                 .vlan_entry_tbl = vlan_entry_k3_cpswxg,
1467                 .tbl_entries = 512,
1468         },
1469         { },
1470 };
1471
1472 static const struct
1473 cpsw_ale_dev_id *cpsw_ale_match_id(const struct cpsw_ale_dev_id *id,
1474                                    const char *dev_id)
1475 {
1476         if (!dev_id)
1477                 return NULL;
1478
1479         while (id->dev_id) {
1480                 if (strcmp(dev_id, id->dev_id) == 0)
1481                         return id;
1482                 id++;
1483         }
1484         return NULL;
1485 }
1486
1487 static const struct regmap_config ale_regmap_cfg = {
1488         .reg_bits = 32,
1489         .val_bits = 32,
1490         .reg_stride = 4,
1491         .name = "cpsw-ale",
1492 };
1493
1494 static int cpsw_ale_regfield_init(struct cpsw_ale *ale)
1495 {
1496         const struct reg_field *reg_fields = ale->params.reg_fields;
1497         struct device *dev = ale->params.dev;
1498         struct regmap *regmap = ale->regmap;
1499         int i;
1500
1501         for (i = 0; i < ale->params.num_fields; i++) {
1502                 ale->fields[i] = devm_regmap_field_alloc(dev, regmap,
1503                                                          reg_fields[i]);
1504                 if (IS_ERR(ale->fields[i])) {
1505                         dev_err(dev, "Unable to allocate regmap field %d\n", i);
1506                         return PTR_ERR(ale->fields[i]);
1507                 }
1508         }
1509
1510         return 0;
1511 }
1512
1513 struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params)
1514 {
1515         u32 ale_entries, rev_major, rev_minor, policers;
1516         const struct cpsw_ale_dev_id *ale_dev_id;
1517         struct cpsw_ale *ale;
1518         int ret;
1519
1520         ale_dev_id = cpsw_ale_match_id(cpsw_ale_id_match, params->dev_id);
1521         if (!ale_dev_id)
1522                 return ERR_PTR(-EINVAL);
1523
1524         params->ale_entries = ale_dev_id->tbl_entries;
1525         params->nu_switch_ale = ale_dev_id->nu_switch_ale;
1526         params->reg_fields = ale_dev_id->reg_fields;
1527         params->num_fields = ale_dev_id->num_fields;
1528
1529         ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL);
1530         if (!ale)
1531                 return ERR_PTR(-ENOMEM);
1532         ale->regmap = devm_regmap_init_mmio(params->dev, params->ale_regs,
1533                                             &ale_regmap_cfg);
1534         if (IS_ERR(ale->regmap)) {
1535                 dev_err(params->dev, "Couldn't create CPSW ALE regmap\n");
1536                 return ERR_PTR(-ENOMEM);
1537         }
1538
1539         ale->params = *params;
1540         ret = cpsw_ale_regfield_init(ale);
1541         if (ret)
1542                 return ERR_PTR(ret);
1543
1544         ale->p0_untag_vid_mask = devm_bitmap_zalloc(params->dev, VLAN_N_VID,
1545                                                     GFP_KERNEL);
1546         if (!ale->p0_untag_vid_mask)
1547                 return ERR_PTR(-ENOMEM);
1548
1549         ale->ageout = ale->params.ale_ageout * HZ;
1550         ale->features = ale_dev_id->features;
1551         ale->vlan_entry_tbl = ale_dev_id->vlan_entry_tbl;
1552
1553         regmap_field_read(ale->fields[MINOR_VER], &rev_minor);
1554         regmap_field_read(ale->fields[MAJOR_VER], &rev_major);
1555         ale->version = rev_major << 8 | rev_minor;
1556         dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n",
1557                  rev_major, rev_minor);
1558
1559         if (ale->features & CPSW_ALE_F_STATUS_REG &&
1560             !ale->params.ale_entries) {
1561                 regmap_field_read(ale->fields[ALE_ENTRIES], &ale_entries);
1562                 /* ALE available on newer NetCP switches has introduced
1563                  * a register, ALE_STATUS, to indicate the size of ALE
1564                  * table which shows the size as a multiple of 1024 entries.
1565                  * For these, params.ale_entries will be set to zero. So
1566                  * read the register and update the value of ale_entries.
1567                  * return error if ale_entries is zero in ALE_STATUS.
1568                  */
1569                 if (!ale_entries)
1570                         return ERR_PTR(-EINVAL);
1571
1572                 ale_entries *= ALE_TABLE_SIZE_MULTIPLIER;
1573                 ale->params.ale_entries = ale_entries;
1574         }
1575
1576         if (ale->features & CPSW_ALE_F_STATUS_REG &&
1577             !ale->params.num_policers) {
1578                 regmap_field_read(ale->fields[ALE_POLICERS], &policers);
1579                 if (!policers)
1580                         return ERR_PTR(-EINVAL);
1581
1582                 policers *= ALE_POLICER_SIZE_MULTIPLIER;
1583                 ale->params.num_policers = policers;
1584         }
1585
1586         dev_info(ale->params.dev,
1587                  "ALE Table size %ld, Policers %ld\n", ale->params.ale_entries,
1588                  ale->params.num_policers);
1589
1590         /* set default bits for existing h/w */
1591         ale->port_mask_bits = ale->params.ale_ports;
1592         ale->port_num_bits = order_base_2(ale->params.ale_ports);
1593         ale->vlan_field_bits = ale->params.ale_ports;
1594
1595         /* Set defaults override for ALE on NetCP NU switch and for version
1596          * 1R3
1597          */
1598         if (ale->params.nu_switch_ale) {
1599                 /* Separate registers for unknown vlan configuration.
1600                  * Also there are N bits, where N is number of ale
1601                  * ports and shift value should be 0
1602                  */
1603                 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].bits =
1604                                         ale->params.ale_ports;
1605                 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].offset =
1606                                         ALE_UNKNOWNVLAN_MEMBER;
1607                 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].bits =
1608                                         ale->params.ale_ports;
1609                 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].shift = 0;
1610                 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].offset =
1611                                         ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD;
1612                 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].bits =
1613                                         ale->params.ale_ports;
1614                 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].shift = 0;
1615                 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].offset =
1616                                         ALE_UNKNOWNVLAN_REG_MCAST_FLOOD;
1617                 ale_controls[ALE_PORT_UNTAGGED_EGRESS].bits =
1618                                         ale->params.ale_ports;
1619                 ale_controls[ALE_PORT_UNTAGGED_EGRESS].shift = 0;
1620                 ale_controls[ALE_PORT_UNTAGGED_EGRESS].offset =
1621                                         ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS;
1622         }
1623
1624         cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
1625         return ale;
1626 }
1627
1628 void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data)
1629 {
1630         int i;
1631
1632         for (i = 0; i < ale->params.ale_entries; i++) {
1633                 cpsw_ale_read(ale, i, data);
1634                 data += ALE_ENTRY_WORDS;
1635         }
1636 }
1637
1638 void cpsw_ale_restore(struct cpsw_ale *ale, u32 *data)
1639 {
1640         int i;
1641
1642         for (i = 0; i < ale->params.ale_entries; i++) {
1643                 cpsw_ale_write(ale, i, data);
1644                 data += ALE_ENTRY_WORDS;
1645         }
1646 }
1647
1648 u32 cpsw_ale_get_num_entries(struct cpsw_ale *ale)
1649 {
1650         return ale ? ale->params.ale_entries : 0;
1651 }
1652
1653 /* Reads the specified policer index into ALE POLICER registers */
1654 static void cpsw_ale_policer_read_idx(struct cpsw_ale *ale, u32 idx)
1655 {
1656         idx &= ALE_POLICER_TBL_INDEX_MASK;
1657         writel_relaxed(idx, ale->params.ale_regs + ALE_POLICER_TBL_CTL);
1658 }
1659
1660 /* Writes the ALE POLICER registers into the specified policer index */
1661 static void cpsw_ale_policer_write_idx(struct cpsw_ale *ale, u32 idx)
1662 {
1663         idx &= ALE_POLICER_TBL_INDEX_MASK;
1664         idx |= ALE_POLICER_TBL_WRITE_ENABLE;
1665         writel_relaxed(idx, ale->params.ale_regs + ALE_POLICER_TBL_CTL);
1666 }
1667
1668 /* enables/disables the custom thread value for the specified policer index */
1669 static void cpsw_ale_policer_thread_idx_enable(struct cpsw_ale *ale, u32 idx,
1670                                                u32 thread_id, bool enable)
1671 {
1672         regmap_field_write(ale->fields[ALE_THREAD_CLASS_INDEX], idx);
1673         regmap_field_write(ale->fields[ALE_THREAD_VALUE], thread_id);
1674         regmap_field_write(ale->fields[ALE_THREAD_ENABLE], enable ? 1 : 0);
1675 }
1676
1677 /* Disable all policer entries and thread mappings */
1678 static void cpsw_ale_policer_reset(struct cpsw_ale *ale)
1679 {
1680         int i;
1681
1682         for (i = 0; i < ale->params.num_policers ; i++) {
1683                 cpsw_ale_policer_read_idx(ale, i);
1684                 regmap_field_write(ale->fields[POL_PORT_MEN], 0);
1685                 regmap_field_write(ale->fields[POL_PRI_MEN], 0);
1686                 regmap_field_write(ale->fields[POL_OUI_MEN], 0);
1687                 regmap_field_write(ale->fields[POL_DST_MEN], 0);
1688                 regmap_field_write(ale->fields[POL_SRC_MEN], 0);
1689                 regmap_field_write(ale->fields[POL_OVLAN_MEN], 0);
1690                 regmap_field_write(ale->fields[POL_IVLAN_MEN], 0);
1691                 regmap_field_write(ale->fields[POL_ETHERTYPE_MEN], 0);
1692                 regmap_field_write(ale->fields[POL_IPSRC_MEN], 0);
1693                 regmap_field_write(ale->fields[POL_IPDST_MEN], 0);
1694                 regmap_field_write(ale->fields[POL_EN], 0);
1695                 regmap_field_write(ale->fields[POL_RED_DROP_EN], 0);
1696                 regmap_field_write(ale->fields[POL_YELLOW_DROP_EN], 0);
1697                 regmap_field_write(ale->fields[POL_PRIORITY_THREAD_EN], 0);
1698
1699                 cpsw_ale_policer_thread_idx_enable(ale, i, 0, 0);
1700         }
1701 }
1702
1703 /* Default classifier is to map 8 user priorities to N receive channels */
1704 void cpsw_ale_classifier_setup_default(struct cpsw_ale *ale, int num_rx_ch)
1705 {
1706         int pri, idx;
1707
1708         /* Reference:
1709          * IEEE802.1Q-2014, Standard for Local and metropolitan area networks
1710          *    Table I-2 - Traffic type acronyms
1711          *    Table I-3 - Defining traffic types
1712          * Section I.4 Traffic types and priority values, states:
1713          * "0 is thus used both for default priority and for Best Effort, and
1714          *  Background is associated with a priority value of 1. This means
1715          * that the value 1 effectively communicates a lower priority than 0."
1716          *
1717          * In the table below, Priority Code Point (PCP) 0 is assigned
1718          * to a higher priority thread than PCP 1 wherever possible.
1719          * The table maps which thread the PCP traffic needs to be
1720          * sent to for a given number of threads (RX channels). Upper threads
1721          * have higher priority.
1722          * e.g. if number of threads is 8 then user priority 0 will map to
1723          * pri_thread_map[8-1][0] i.e. thread 1
1724          */
1725
1726         int pri_thread_map[8][8] = {   /* BK,BE,EE,CA,VI,VO,IC,NC */
1727                                         { 0, 0, 0, 0, 0, 0, 0, 0, },
1728                                         { 0, 0, 0, 0, 1, 1, 1, 1, },
1729                                         { 0, 0, 0, 0, 1, 1, 2, 2, },
1730                                         { 0, 0, 1, 1, 2, 2, 3, 3, },
1731                                         { 0, 0, 1, 1, 2, 2, 3, 4, },
1732                                         { 1, 0, 2, 2, 3, 3, 4, 5, },
1733                                         { 1, 0, 2, 3, 4, 4, 5, 6, },
1734                                         { 1, 0, 2, 3, 4, 5, 6, 7 } };
1735
1736         cpsw_ale_policer_reset(ale);
1737
1738         /* use first 8 classifiers to map 8 (DSCP/PCP) priorities to channels */
1739         for (pri = 0; pri < 8; pri++) {
1740                 idx = pri;
1741
1742                 /* Classifier 'idx' match on priority 'pri' */
1743                 cpsw_ale_policer_read_idx(ale, idx);
1744                 regmap_field_write(ale->fields[POL_PRI_VAL], pri);
1745                 regmap_field_write(ale->fields[POL_PRI_MEN], 1);
1746                 cpsw_ale_policer_write_idx(ale, idx);
1747
1748                 /* Map Classifier 'idx' to thread provided by the map */
1749                 cpsw_ale_policer_thread_idx_enable(ale, idx,
1750                                                    pri_thread_map[num_rx_ch - 1][pri],
1751                                                    1);
1752         }
1753 }
This page took 0.134394 seconds and 4 git commands to generate.