Linux Audio

Check our new training course

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