File Index
Files and directories
Sign in
FILE

cpsw_ale.c

File preview with syntax highlighting.

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