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