Linux Audio

Check our new training course

Linux BSP upgrade and security maintenance

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