0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/bitmap.h>
0009 #include <linux/if_vlan.h>
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/seq_file.h>
0014 #include <linux/slab.h>
0015 #include <linux/err.h>
0016 #include <linux/io.h>
0017 #include <linux/stat.h>
0018 #include <linux/sysfs.h>
0019 #include <linux/etherdevice.h>
0020
0021 #include "cpsw_ale.h"
0022
0023 #define BITMASK(bits) (BIT(bits) - 1)
0024
0025 #define ALE_VERSION_MAJOR(rev, mask) (((rev) >> 8) & (mask))
0026 #define ALE_VERSION_MINOR(rev) (rev & 0xff)
0027 #define ALE_VERSION_1R3 0x0103
0028 #define ALE_VERSION_1R4 0x0104
0029
0030
0031 #define ALE_IDVER 0x00
0032 #define ALE_STATUS 0x04
0033 #define ALE_CONTROL 0x08
0034 #define ALE_PRESCALE 0x10
0035 #define ALE_AGING_TIMER 0x14
0036 #define ALE_UNKNOWNVLAN 0x18
0037 #define ALE_TABLE_CONTROL 0x20
0038 #define ALE_TABLE 0x34
0039 #define ALE_PORTCTL 0x40
0040
0041
0042 #define ALE_UNKNOWNVLAN_MEMBER 0x90
0043 #define ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD 0x94
0044 #define ALE_UNKNOWNVLAN_REG_MCAST_FLOOD 0x98
0045 #define ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS 0x9C
0046 #define ALE_VLAN_MASK_MUX(reg) (0xc0 + (0x4 * (reg)))
0047
0048 #define AM65_CPSW_ALE_THREAD_DEF_REG 0x134
0049
0050
0051 #define ALE_AGING_TIMER_MASK GENMASK(23, 0)
0052
0053 #define ALE_RATE_LIMIT_MIN_PPS 1000
0054
0055
0056
0057
0058
0059
0060
0061 struct ale_entry_fld {
0062 u8 start_bit;
0063 u8 num_bits;
0064 u8 flags;
0065 };
0066
0067 enum {
0068 CPSW_ALE_F_STATUS_REG = BIT(0),
0069 CPSW_ALE_F_HW_AUTOAGING = BIT(1),
0070
0071 CPSW_ALE_F_COUNT
0072 };
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 struct cpsw_ale_dev_id {
0084 const char *dev_id;
0085 u32 features;
0086 u32 tbl_entries;
0087 u32 major_ver_mask;
0088 bool nu_switch_ale;
0089 const struct ale_entry_fld *vlan_entry_tbl;
0090 };
0091
0092 #define ALE_TABLE_WRITE BIT(31)
0093
0094 #define ALE_TYPE_FREE 0
0095 #define ALE_TYPE_ADDR 1
0096 #define ALE_TYPE_VLAN 2
0097 #define ALE_TYPE_VLAN_ADDR 3
0098
0099 #define ALE_UCAST_PERSISTANT 0
0100 #define ALE_UCAST_UNTOUCHED 1
0101 #define ALE_UCAST_OUI 2
0102 #define ALE_UCAST_TOUCHED 3
0103
0104 #define ALE_TABLE_SIZE_MULTIPLIER 1024
0105 #define ALE_STATUS_SIZE_MASK 0x1f
0106
0107 static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
0108 {
0109 int idx;
0110
0111 idx = start / 32;
0112 start -= idx * 32;
0113 idx = 2 - idx;
0114 return (ale_entry[idx] >> start) & BITMASK(bits);
0115 }
0116
0117 static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
0118 u32 value)
0119 {
0120 int idx;
0121
0122 value &= BITMASK(bits);
0123 idx = start / 32;
0124 start -= idx * 32;
0125 idx = 2 - idx;
0126 ale_entry[idx] &= ~(BITMASK(bits) << start);
0127 ale_entry[idx] |= (value << start);
0128 }
0129
0130 #define DEFINE_ALE_FIELD(name, start, bits) \
0131 static inline int cpsw_ale_get_##name(u32 *ale_entry) \
0132 { \
0133 return cpsw_ale_get_field(ale_entry, start, bits); \
0134 } \
0135 static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value) \
0136 { \
0137 cpsw_ale_set_field(ale_entry, start, bits, value); \
0138 }
0139
0140 #define DEFINE_ALE_FIELD1(name, start) \
0141 static inline int cpsw_ale_get_##name(u32 *ale_entry, u32 bits) \
0142 { \
0143 return cpsw_ale_get_field(ale_entry, start, bits); \
0144 } \
0145 static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value, \
0146 u32 bits) \
0147 { \
0148 cpsw_ale_set_field(ale_entry, start, bits, value); \
0149 }
0150
0151 enum {
0152 ALE_ENT_VID_MEMBER_LIST = 0,
0153 ALE_ENT_VID_UNREG_MCAST_MSK,
0154 ALE_ENT_VID_REG_MCAST_MSK,
0155 ALE_ENT_VID_FORCE_UNTAGGED_MSK,
0156 ALE_ENT_VID_UNREG_MCAST_IDX,
0157 ALE_ENT_VID_REG_MCAST_IDX,
0158 ALE_ENT_VID_LAST,
0159 };
0160
0161 #define ALE_FLD_ALLOWED BIT(0)
0162 #define ALE_FLD_SIZE_PORT_MASK_BITS BIT(1)
0163 #define ALE_FLD_SIZE_PORT_NUM_BITS BIT(2)
0164
0165 #define ALE_ENTRY_FLD(id, start, bits) \
0166 [id] = { \
0167 .start_bit = start, \
0168 .num_bits = bits, \
0169 .flags = ALE_FLD_ALLOWED, \
0170 }
0171
0172 #define ALE_ENTRY_FLD_DYN_MSK_SIZE(id, start) \
0173 [id] = { \
0174 .start_bit = start, \
0175 .num_bits = 0, \
0176 .flags = ALE_FLD_ALLOWED | \
0177 ALE_FLD_SIZE_PORT_MASK_BITS, \
0178 }
0179
0180
0181 static const struct ale_entry_fld vlan_entry_cpsw[ALE_ENT_VID_LAST] = {
0182 ALE_ENTRY_FLD(ALE_ENT_VID_MEMBER_LIST, 0, 3),
0183 ALE_ENTRY_FLD(ALE_ENT_VID_UNREG_MCAST_MSK, 8, 3),
0184 ALE_ENTRY_FLD(ALE_ENT_VID_REG_MCAST_MSK, 16, 3),
0185 ALE_ENTRY_FLD(ALE_ENT_VID_FORCE_UNTAGGED_MSK, 24, 3),
0186 };
0187
0188
0189 static const struct ale_entry_fld vlan_entry_nu[ALE_ENT_VID_LAST] = {
0190 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_MEMBER_LIST, 0),
0191 ALE_ENTRY_FLD(ALE_ENT_VID_UNREG_MCAST_IDX, 20, 3),
0192 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_FORCE_UNTAGGED_MSK, 24),
0193 ALE_ENTRY_FLD(ALE_ENT_VID_REG_MCAST_IDX, 44, 3),
0194 };
0195
0196
0197 static const struct ale_entry_fld vlan_entry_k3_cpswxg[] = {
0198 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_MEMBER_LIST, 0),
0199 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_UNREG_MCAST_MSK, 12),
0200 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_FORCE_UNTAGGED_MSK, 24),
0201 ALE_ENTRY_FLD_DYN_MSK_SIZE(ALE_ENT_VID_REG_MCAST_MSK, 36),
0202 };
0203
0204 DEFINE_ALE_FIELD(entry_type, 60, 2)
0205 DEFINE_ALE_FIELD(vlan_id, 48, 12)
0206 DEFINE_ALE_FIELD(mcast_state, 62, 2)
0207 DEFINE_ALE_FIELD1(port_mask, 66)
0208 DEFINE_ALE_FIELD(super, 65, 1)
0209 DEFINE_ALE_FIELD(ucast_type, 62, 2)
0210 DEFINE_ALE_FIELD1(port_num, 66)
0211 DEFINE_ALE_FIELD(blocked, 65, 1)
0212 DEFINE_ALE_FIELD(secure, 64, 1)
0213 DEFINE_ALE_FIELD(mcast, 40, 1)
0214
0215 #define NU_VLAN_UNREG_MCAST_IDX 1
0216
0217 static int cpsw_ale_entry_get_fld(struct cpsw_ale *ale,
0218 u32 *ale_entry,
0219 const struct ale_entry_fld *entry_tbl,
0220 int fld_id)
0221 {
0222 const struct ale_entry_fld *entry_fld;
0223 u32 bits;
0224
0225 if (!ale || !ale_entry)
0226 return -EINVAL;
0227
0228 entry_fld = &entry_tbl[fld_id];
0229 if (!(entry_fld->flags & ALE_FLD_ALLOWED)) {
0230 dev_err(ale->params.dev, "get: wrong ale fld id %d\n", fld_id);
0231 return -ENOENT;
0232 }
0233
0234 bits = entry_fld->num_bits;
0235 if (entry_fld->flags & ALE_FLD_SIZE_PORT_MASK_BITS)
0236 bits = ale->port_mask_bits;
0237
0238 return cpsw_ale_get_field(ale_entry, entry_fld->start_bit, bits);
0239 }
0240
0241 static void cpsw_ale_entry_set_fld(struct cpsw_ale *ale,
0242 u32 *ale_entry,
0243 const struct ale_entry_fld *entry_tbl,
0244 int fld_id,
0245 u32 value)
0246 {
0247 const struct ale_entry_fld *entry_fld;
0248 u32 bits;
0249
0250 if (!ale || !ale_entry)
0251 return;
0252
0253 entry_fld = &entry_tbl[fld_id];
0254 if (!(entry_fld->flags & ALE_FLD_ALLOWED)) {
0255 dev_err(ale->params.dev, "set: wrong ale fld id %d\n", fld_id);
0256 return;
0257 }
0258
0259 bits = entry_fld->num_bits;
0260 if (entry_fld->flags & ALE_FLD_SIZE_PORT_MASK_BITS)
0261 bits = ale->port_mask_bits;
0262
0263 cpsw_ale_set_field(ale_entry, entry_fld->start_bit, bits, value);
0264 }
0265
0266 static int cpsw_ale_vlan_get_fld(struct cpsw_ale *ale,
0267 u32 *ale_entry,
0268 int fld_id)
0269 {
0270 return cpsw_ale_entry_get_fld(ale, ale_entry,
0271 ale->vlan_entry_tbl, fld_id);
0272 }
0273
0274 static void cpsw_ale_vlan_set_fld(struct cpsw_ale *ale,
0275 u32 *ale_entry,
0276 int fld_id,
0277 u32 value)
0278 {
0279 cpsw_ale_entry_set_fld(ale, ale_entry,
0280 ale->vlan_entry_tbl, fld_id, value);
0281 }
0282
0283
0284 static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr)
0285 {
0286 int i;
0287
0288 for (i = 0; i < 6; i++)
0289 addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8);
0290 }
0291
0292 static inline void cpsw_ale_set_addr(u32 *ale_entry, const u8 *addr)
0293 {
0294 int i;
0295
0296 for (i = 0; i < 6; i++)
0297 cpsw_ale_set_field(ale_entry, 40 - 8*i, 8, addr[i]);
0298 }
0299
0300 static int cpsw_ale_read(struct cpsw_ale *ale, int idx, u32 *ale_entry)
0301 {
0302 int i;
0303
0304 WARN_ON(idx > ale->params.ale_entries);
0305
0306 writel_relaxed(idx, ale->params.ale_regs + ALE_TABLE_CONTROL);
0307
0308 for (i = 0; i < ALE_ENTRY_WORDS; i++)
0309 ale_entry[i] = readl_relaxed(ale->params.ale_regs +
0310 ALE_TABLE + 4 * i);
0311
0312 return idx;
0313 }
0314
0315 static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry)
0316 {
0317 int i;
0318
0319 WARN_ON(idx > ale->params.ale_entries);
0320
0321 for (i = 0; i < ALE_ENTRY_WORDS; i++)
0322 writel_relaxed(ale_entry[i], ale->params.ale_regs +
0323 ALE_TABLE + 4 * i);
0324
0325 writel_relaxed(idx | ALE_TABLE_WRITE, ale->params.ale_regs +
0326 ALE_TABLE_CONTROL);
0327
0328 return idx;
0329 }
0330
0331 static int cpsw_ale_match_addr(struct cpsw_ale *ale, const u8 *addr, u16 vid)
0332 {
0333 u32 ale_entry[ALE_ENTRY_WORDS];
0334 int type, idx;
0335
0336 for (idx = 0; idx < ale->params.ale_entries; idx++) {
0337 u8 entry_addr[6];
0338
0339 cpsw_ale_read(ale, idx, ale_entry);
0340 type = cpsw_ale_get_entry_type(ale_entry);
0341 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
0342 continue;
0343 if (cpsw_ale_get_vlan_id(ale_entry) != vid)
0344 continue;
0345 cpsw_ale_get_addr(ale_entry, entry_addr);
0346 if (ether_addr_equal(entry_addr, addr))
0347 return idx;
0348 }
0349 return -ENOENT;
0350 }
0351
0352 static int cpsw_ale_match_vlan(struct cpsw_ale *ale, u16 vid)
0353 {
0354 u32 ale_entry[ALE_ENTRY_WORDS];
0355 int type, idx;
0356
0357 for (idx = 0; idx < ale->params.ale_entries; idx++) {
0358 cpsw_ale_read(ale, idx, ale_entry);
0359 type = cpsw_ale_get_entry_type(ale_entry);
0360 if (type != ALE_TYPE_VLAN)
0361 continue;
0362 if (cpsw_ale_get_vlan_id(ale_entry) == vid)
0363 return idx;
0364 }
0365 return -ENOENT;
0366 }
0367
0368 static int cpsw_ale_match_free(struct cpsw_ale *ale)
0369 {
0370 u32 ale_entry[ALE_ENTRY_WORDS];
0371 int type, idx;
0372
0373 for (idx = 0; idx < ale->params.ale_entries; idx++) {
0374 cpsw_ale_read(ale, idx, ale_entry);
0375 type = cpsw_ale_get_entry_type(ale_entry);
0376 if (type == ALE_TYPE_FREE)
0377 return idx;
0378 }
0379 return -ENOENT;
0380 }
0381
0382 static int cpsw_ale_find_ageable(struct cpsw_ale *ale)
0383 {
0384 u32 ale_entry[ALE_ENTRY_WORDS];
0385 int type, idx;
0386
0387 for (idx = 0; idx < ale->params.ale_entries; idx++) {
0388 cpsw_ale_read(ale, idx, ale_entry);
0389 type = cpsw_ale_get_entry_type(ale_entry);
0390 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
0391 continue;
0392 if (cpsw_ale_get_mcast(ale_entry))
0393 continue;
0394 type = cpsw_ale_get_ucast_type(ale_entry);
0395 if (type != ALE_UCAST_PERSISTANT &&
0396 type != ALE_UCAST_OUI)
0397 return idx;
0398 }
0399 return -ENOENT;
0400 }
0401
0402 static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry,
0403 int port_mask)
0404 {
0405 int mask;
0406
0407 mask = cpsw_ale_get_port_mask(ale_entry,
0408 ale->port_mask_bits);
0409 if ((mask & port_mask) == 0)
0410 return;
0411 mask &= ~port_mask;
0412
0413
0414 if (mask)
0415 cpsw_ale_set_port_mask(ale_entry, mask,
0416 ale->port_mask_bits);
0417 else
0418 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
0419 }
0420
0421 int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid)
0422 {
0423 u32 ale_entry[ALE_ENTRY_WORDS];
0424 int ret, idx;
0425
0426 for (idx = 0; idx < ale->params.ale_entries; idx++) {
0427 cpsw_ale_read(ale, idx, ale_entry);
0428 ret = cpsw_ale_get_entry_type(ale_entry);
0429 if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR)
0430 continue;
0431
0432
0433
0434
0435
0436
0437 if (vid != -1 && cpsw_ale_get_vlan_id(ale_entry) != vid)
0438 continue;
0439
0440 if (cpsw_ale_get_mcast(ale_entry)) {
0441 u8 addr[6];
0442
0443 if (cpsw_ale_get_super(ale_entry))
0444 continue;
0445
0446 cpsw_ale_get_addr(ale_entry, addr);
0447 if (!is_broadcast_ether_addr(addr))
0448 cpsw_ale_flush_mcast(ale, ale_entry, port_mask);
0449 }
0450
0451 cpsw_ale_write(ale, idx, ale_entry);
0452 }
0453 return 0;
0454 }
0455
0456 static inline void cpsw_ale_set_vlan_entry_type(u32 *ale_entry,
0457 int flags, u16 vid)
0458 {
0459 if (flags & ALE_VLAN) {
0460 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN_ADDR);
0461 cpsw_ale_set_vlan_id(ale_entry, vid);
0462 } else {
0463 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
0464 }
0465 }
0466
0467 int cpsw_ale_add_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
0468 int flags, u16 vid)
0469 {
0470 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
0471 int idx;
0472
0473 cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);
0474
0475 cpsw_ale_set_addr(ale_entry, addr);
0476 cpsw_ale_set_ucast_type(ale_entry, ALE_UCAST_PERSISTANT);
0477 cpsw_ale_set_secure(ale_entry, (flags & ALE_SECURE) ? 1 : 0);
0478 cpsw_ale_set_blocked(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0);
0479 cpsw_ale_set_port_num(ale_entry, port, ale->port_num_bits);
0480
0481 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
0482 if (idx < 0)
0483 idx = cpsw_ale_match_free(ale);
0484 if (idx < 0)
0485 idx = cpsw_ale_find_ageable(ale);
0486 if (idx < 0)
0487 return -ENOMEM;
0488
0489 cpsw_ale_write(ale, idx, ale_entry);
0490 return 0;
0491 }
0492
0493 int cpsw_ale_del_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
0494 int flags, u16 vid)
0495 {
0496 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
0497 int idx;
0498
0499 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
0500 if (idx < 0)
0501 return -ENOENT;
0502
0503 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
0504 cpsw_ale_write(ale, idx, ale_entry);
0505 return 0;
0506 }
0507
0508 int cpsw_ale_add_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
0509 int flags, u16 vid, int mcast_state)
0510 {
0511 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
0512 int idx, mask;
0513
0514 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
0515 if (idx >= 0)
0516 cpsw_ale_read(ale, idx, ale_entry);
0517
0518 cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);
0519
0520 cpsw_ale_set_addr(ale_entry, addr);
0521 cpsw_ale_set_super(ale_entry, (flags & ALE_SUPER) ? 1 : 0);
0522 cpsw_ale_set_mcast_state(ale_entry, mcast_state);
0523
0524 mask = cpsw_ale_get_port_mask(ale_entry,
0525 ale->port_mask_bits);
0526 port_mask |= mask;
0527 cpsw_ale_set_port_mask(ale_entry, port_mask,
0528 ale->port_mask_bits);
0529
0530 if (idx < 0)
0531 idx = cpsw_ale_match_free(ale);
0532 if (idx < 0)
0533 idx = cpsw_ale_find_ageable(ale);
0534 if (idx < 0)
0535 return -ENOMEM;
0536
0537 cpsw_ale_write(ale, idx, ale_entry);
0538 return 0;
0539 }
0540
0541 int cpsw_ale_del_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
0542 int flags, u16 vid)
0543 {
0544 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
0545 int mcast_members = 0;
0546 int idx;
0547
0548 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
0549 if (idx < 0)
0550 return -ENOENT;
0551
0552 cpsw_ale_read(ale, idx, ale_entry);
0553
0554 if (port_mask) {
0555 mcast_members = cpsw_ale_get_port_mask(ale_entry,
0556 ale->port_mask_bits);
0557 mcast_members &= ~port_mask;
0558 }
0559
0560 if (mcast_members)
0561 cpsw_ale_set_port_mask(ale_entry, mcast_members,
0562 ale->port_mask_bits);
0563 else
0564 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
0565
0566 cpsw_ale_write(ale, idx, ale_entry);
0567 return 0;
0568 }
0569
0570
0571 static void cpsw_ale_set_vlan_mcast(struct cpsw_ale *ale, u32 *ale_entry,
0572 int reg_mcast, int unreg_mcast)
0573 {
0574 int idx;
0575
0576
0577 idx = cpsw_ale_vlan_get_fld(ale, ale_entry,
0578 ALE_ENT_VID_REG_MCAST_IDX);
0579 writel(reg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
0580
0581
0582 idx = cpsw_ale_vlan_get_fld(ale, ale_entry,
0583 ALE_ENT_VID_UNREG_MCAST_IDX);
0584 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
0585 }
0586
0587 static void cpsw_ale_set_vlan_untag(struct cpsw_ale *ale, u32 *ale_entry,
0588 u16 vid, int untag_mask)
0589 {
0590 cpsw_ale_vlan_set_fld(ale, ale_entry,
0591 ALE_ENT_VID_FORCE_UNTAGGED_MSK,
0592 untag_mask);
0593 if (untag_mask & ALE_PORT_HOST)
0594 bitmap_set(ale->p0_untag_vid_mask, vid, 1);
0595 else
0596 bitmap_clear(ale->p0_untag_vid_mask, vid, 1);
0597 }
0598
0599 int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port_mask, int untag,
0600 int reg_mcast, int unreg_mcast)
0601 {
0602 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
0603 int idx;
0604
0605 idx = cpsw_ale_match_vlan(ale, vid);
0606 if (idx >= 0)
0607 cpsw_ale_read(ale, idx, ale_entry);
0608
0609 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN);
0610 cpsw_ale_set_vlan_id(ale_entry, vid);
0611 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, untag);
0612
0613 if (!ale->params.nu_switch_ale) {
0614 cpsw_ale_vlan_set_fld(ale, ale_entry,
0615 ALE_ENT_VID_REG_MCAST_MSK, reg_mcast);
0616 cpsw_ale_vlan_set_fld(ale, ale_entry,
0617 ALE_ENT_VID_UNREG_MCAST_MSK, unreg_mcast);
0618 } else {
0619 cpsw_ale_vlan_set_fld(ale, ale_entry,
0620 ALE_ENT_VID_UNREG_MCAST_IDX,
0621 NU_VLAN_UNREG_MCAST_IDX);
0622 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast, unreg_mcast);
0623 }
0624
0625 cpsw_ale_vlan_set_fld(ale, ale_entry,
0626 ALE_ENT_VID_MEMBER_LIST, port_mask);
0627
0628 if (idx < 0)
0629 idx = cpsw_ale_match_free(ale);
0630 if (idx < 0)
0631 idx = cpsw_ale_find_ageable(ale);
0632 if (idx < 0)
0633 return -ENOMEM;
0634
0635 cpsw_ale_write(ale, idx, ale_entry);
0636 return 0;
0637 }
0638
0639 static void cpsw_ale_vlan_del_modify_int(struct cpsw_ale *ale, u32 *ale_entry,
0640 u16 vid, int port_mask)
0641 {
0642 int reg_mcast, unreg_mcast;
0643 int members, untag;
0644
0645 members = cpsw_ale_vlan_get_fld(ale, ale_entry,
0646 ALE_ENT_VID_MEMBER_LIST);
0647 members &= ~port_mask;
0648 if (!members) {
0649 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, 0);
0650 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
0651 return;
0652 }
0653
0654 untag = cpsw_ale_vlan_get_fld(ale, ale_entry,
0655 ALE_ENT_VID_FORCE_UNTAGGED_MSK);
0656 reg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry,
0657 ALE_ENT_VID_REG_MCAST_MSK);
0658 unreg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry,
0659 ALE_ENT_VID_UNREG_MCAST_MSK);
0660 untag &= members;
0661 reg_mcast &= members;
0662 unreg_mcast &= members;
0663
0664 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, untag);
0665
0666 if (!ale->params.nu_switch_ale) {
0667 cpsw_ale_vlan_set_fld(ale, ale_entry,
0668 ALE_ENT_VID_REG_MCAST_MSK, reg_mcast);
0669 cpsw_ale_vlan_set_fld(ale, ale_entry,
0670 ALE_ENT_VID_UNREG_MCAST_MSK, unreg_mcast);
0671 } else {
0672 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast,
0673 unreg_mcast);
0674 }
0675 cpsw_ale_vlan_set_fld(ale, ale_entry,
0676 ALE_ENT_VID_MEMBER_LIST, members);
0677 }
0678
0679 int cpsw_ale_vlan_del_modify(struct cpsw_ale *ale, u16 vid, int port_mask)
0680 {
0681 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
0682 int idx;
0683
0684 idx = cpsw_ale_match_vlan(ale, vid);
0685 if (idx < 0)
0686 return -ENOENT;
0687
0688 cpsw_ale_read(ale, idx, ale_entry);
0689
0690 cpsw_ale_vlan_del_modify_int(ale, ale_entry, vid, port_mask);
0691 cpsw_ale_write(ale, idx, ale_entry);
0692
0693 return 0;
0694 }
0695
0696 int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask)
0697 {
0698 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
0699 int members, idx;
0700
0701 idx = cpsw_ale_match_vlan(ale, vid);
0702 if (idx < 0)
0703 return -ENOENT;
0704
0705 cpsw_ale_read(ale, idx, ale_entry);
0706
0707
0708
0709
0710
0711
0712
0713 members = cpsw_ale_vlan_get_fld(ale, ale_entry, ALE_ENT_VID_MEMBER_LIST);
0714 members &= ~port_mask;
0715
0716 if (!port_mask || !members) {
0717
0718 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, 0);
0719 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
0720 } else {
0721 port_mask &= ~ALE_PORT_HOST;
0722 cpsw_ale_vlan_del_modify_int(ale, ale_entry, vid, port_mask);
0723 }
0724
0725 cpsw_ale_write(ale, idx, ale_entry);
0726
0727 return 0;
0728 }
0729
0730 int cpsw_ale_vlan_add_modify(struct cpsw_ale *ale, u16 vid, int port_mask,
0731 int untag_mask, int reg_mask, int unreg_mask)
0732 {
0733 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
0734 int reg_mcast_members, unreg_mcast_members;
0735 int vlan_members, untag_members;
0736 int idx, ret = 0;
0737
0738 idx = cpsw_ale_match_vlan(ale, vid);
0739 if (idx >= 0)
0740 cpsw_ale_read(ale, idx, ale_entry);
0741
0742 vlan_members = cpsw_ale_vlan_get_fld(ale, ale_entry,
0743 ALE_ENT_VID_MEMBER_LIST);
0744 reg_mcast_members = cpsw_ale_vlan_get_fld(ale, ale_entry,
0745 ALE_ENT_VID_REG_MCAST_MSK);
0746 unreg_mcast_members =
0747 cpsw_ale_vlan_get_fld(ale, ale_entry,
0748 ALE_ENT_VID_UNREG_MCAST_MSK);
0749 untag_members = cpsw_ale_vlan_get_fld(ale, ale_entry,
0750 ALE_ENT_VID_FORCE_UNTAGGED_MSK);
0751
0752 vlan_members |= port_mask;
0753 untag_members = (untag_members & ~port_mask) | untag_mask;
0754 reg_mcast_members = (reg_mcast_members & ~port_mask) | reg_mask;
0755 unreg_mcast_members = (unreg_mcast_members & ~port_mask) | unreg_mask;
0756
0757 ret = cpsw_ale_add_vlan(ale, vid, vlan_members, untag_members,
0758 reg_mcast_members, unreg_mcast_members);
0759 if (ret) {
0760 dev_err(ale->params.dev, "Unable to add vlan\n");
0761 return ret;
0762 }
0763 dev_dbg(ale->params.dev, "port mask 0x%x untag 0x%x\n", vlan_members,
0764 untag_mask);
0765
0766 return ret;
0767 }
0768
0769 void cpsw_ale_set_unreg_mcast(struct cpsw_ale *ale, int unreg_mcast_mask,
0770 bool add)
0771 {
0772 u32 ale_entry[ALE_ENTRY_WORDS];
0773 int unreg_members = 0;
0774 int type, idx;
0775
0776 for (idx = 0; idx < ale->params.ale_entries; idx++) {
0777 cpsw_ale_read(ale, idx, ale_entry);
0778 type = cpsw_ale_get_entry_type(ale_entry);
0779 if (type != ALE_TYPE_VLAN)
0780 continue;
0781
0782 unreg_members =
0783 cpsw_ale_vlan_get_fld(ale, ale_entry,
0784 ALE_ENT_VID_UNREG_MCAST_MSK);
0785 if (add)
0786 unreg_members |= unreg_mcast_mask;
0787 else
0788 unreg_members &= ~unreg_mcast_mask;
0789 cpsw_ale_vlan_set_fld(ale, ale_entry,
0790 ALE_ENT_VID_UNREG_MCAST_MSK,
0791 unreg_members);
0792 cpsw_ale_write(ale, idx, ale_entry);
0793 }
0794 }
0795
0796 static void cpsw_ale_vlan_set_unreg_mcast(struct cpsw_ale *ale, u32 *ale_entry,
0797 int allmulti)
0798 {
0799 int unreg_mcast;
0800
0801 unreg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry,
0802 ALE_ENT_VID_UNREG_MCAST_MSK);
0803 if (allmulti)
0804 unreg_mcast |= ALE_PORT_HOST;
0805 else
0806 unreg_mcast &= ~ALE_PORT_HOST;
0807
0808 cpsw_ale_vlan_set_fld(ale, ale_entry,
0809 ALE_ENT_VID_UNREG_MCAST_MSK, unreg_mcast);
0810 }
0811
0812 static void
0813 cpsw_ale_vlan_set_unreg_mcast_idx(struct cpsw_ale *ale, u32 *ale_entry,
0814 int allmulti)
0815 {
0816 int unreg_mcast;
0817 int idx;
0818
0819 idx = cpsw_ale_vlan_get_fld(ale, ale_entry,
0820 ALE_ENT_VID_UNREG_MCAST_IDX);
0821
0822 unreg_mcast = readl(ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
0823
0824 if (allmulti)
0825 unreg_mcast |= ALE_PORT_HOST;
0826 else
0827 unreg_mcast &= ~ALE_PORT_HOST;
0828
0829 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
0830 }
0831
0832 void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti, int port)
0833 {
0834 u32 ale_entry[ALE_ENTRY_WORDS];
0835 int type, idx;
0836
0837 for (idx = 0; idx < ale->params.ale_entries; idx++) {
0838 int vlan_members;
0839
0840 cpsw_ale_read(ale, idx, ale_entry);
0841 type = cpsw_ale_get_entry_type(ale_entry);
0842 if (type != ALE_TYPE_VLAN)
0843 continue;
0844
0845 vlan_members = cpsw_ale_vlan_get_fld(ale, ale_entry,
0846 ALE_ENT_VID_MEMBER_LIST);
0847
0848 if (port != -1 && !(vlan_members & BIT(port)))
0849 continue;
0850
0851 if (!ale->params.nu_switch_ale)
0852 cpsw_ale_vlan_set_unreg_mcast(ale, ale_entry, allmulti);
0853 else
0854 cpsw_ale_vlan_set_unreg_mcast_idx(ale, ale_entry,
0855 allmulti);
0856
0857 cpsw_ale_write(ale, idx, ale_entry);
0858 }
0859 }
0860
0861 struct ale_control_info {
0862 const char *name;
0863 int offset, port_offset;
0864 int shift, port_shift;
0865 int bits;
0866 };
0867
0868 static struct ale_control_info ale_controls[ALE_NUM_CONTROLS] = {
0869 [ALE_ENABLE] = {
0870 .name = "enable",
0871 .offset = ALE_CONTROL,
0872 .port_offset = 0,
0873 .shift = 31,
0874 .port_shift = 0,
0875 .bits = 1,
0876 },
0877 [ALE_CLEAR] = {
0878 .name = "clear",
0879 .offset = ALE_CONTROL,
0880 .port_offset = 0,
0881 .shift = 30,
0882 .port_shift = 0,
0883 .bits = 1,
0884 },
0885 [ALE_AGEOUT] = {
0886 .name = "ageout",
0887 .offset = ALE_CONTROL,
0888 .port_offset = 0,
0889 .shift = 29,
0890 .port_shift = 0,
0891 .bits = 1,
0892 },
0893 [ALE_P0_UNI_FLOOD] = {
0894 .name = "port0_unicast_flood",
0895 .offset = ALE_CONTROL,
0896 .port_offset = 0,
0897 .shift = 8,
0898 .port_shift = 0,
0899 .bits = 1,
0900 },
0901 [ALE_VLAN_NOLEARN] = {
0902 .name = "vlan_nolearn",
0903 .offset = ALE_CONTROL,
0904 .port_offset = 0,
0905 .shift = 7,
0906 .port_shift = 0,
0907 .bits = 1,
0908 },
0909 [ALE_NO_PORT_VLAN] = {
0910 .name = "no_port_vlan",
0911 .offset = ALE_CONTROL,
0912 .port_offset = 0,
0913 .shift = 6,
0914 .port_shift = 0,
0915 .bits = 1,
0916 },
0917 [ALE_OUI_DENY] = {
0918 .name = "oui_deny",
0919 .offset = ALE_CONTROL,
0920 .port_offset = 0,
0921 .shift = 5,
0922 .port_shift = 0,
0923 .bits = 1,
0924 },
0925 [ALE_BYPASS] = {
0926 .name = "bypass",
0927 .offset = ALE_CONTROL,
0928 .port_offset = 0,
0929 .shift = 4,
0930 .port_shift = 0,
0931 .bits = 1,
0932 },
0933 [ALE_RATE_LIMIT_TX] = {
0934 .name = "rate_limit_tx",
0935 .offset = ALE_CONTROL,
0936 .port_offset = 0,
0937 .shift = 3,
0938 .port_shift = 0,
0939 .bits = 1,
0940 },
0941 [ALE_VLAN_AWARE] = {
0942 .name = "vlan_aware",
0943 .offset = ALE_CONTROL,
0944 .port_offset = 0,
0945 .shift = 2,
0946 .port_shift = 0,
0947 .bits = 1,
0948 },
0949 [ALE_AUTH_ENABLE] = {
0950 .name = "auth_enable",
0951 .offset = ALE_CONTROL,
0952 .port_offset = 0,
0953 .shift = 1,
0954 .port_shift = 0,
0955 .bits = 1,
0956 },
0957 [ALE_RATE_LIMIT] = {
0958 .name = "rate_limit",
0959 .offset = ALE_CONTROL,
0960 .port_offset = 0,
0961 .shift = 0,
0962 .port_shift = 0,
0963 .bits = 1,
0964 },
0965 [ALE_PORT_STATE] = {
0966 .name = "port_state",
0967 .offset = ALE_PORTCTL,
0968 .port_offset = 4,
0969 .shift = 0,
0970 .port_shift = 0,
0971 .bits = 2,
0972 },
0973 [ALE_PORT_DROP_UNTAGGED] = {
0974 .name = "drop_untagged",
0975 .offset = ALE_PORTCTL,
0976 .port_offset = 4,
0977 .shift = 2,
0978 .port_shift = 0,
0979 .bits = 1,
0980 },
0981 [ALE_PORT_DROP_UNKNOWN_VLAN] = {
0982 .name = "drop_unknown",
0983 .offset = ALE_PORTCTL,
0984 .port_offset = 4,
0985 .shift = 3,
0986 .port_shift = 0,
0987 .bits = 1,
0988 },
0989 [ALE_PORT_NOLEARN] = {
0990 .name = "nolearn",
0991 .offset = ALE_PORTCTL,
0992 .port_offset = 4,
0993 .shift = 4,
0994 .port_shift = 0,
0995 .bits = 1,
0996 },
0997 [ALE_PORT_NO_SA_UPDATE] = {
0998 .name = "no_source_update",
0999 .offset = ALE_PORTCTL,
1000 .port_offset = 4,
1001 .shift = 5,
1002 .port_shift = 0,
1003 .bits = 1,
1004 },
1005 [ALE_PORT_MACONLY] = {
1006 .name = "mac_only_port_mode",
1007 .offset = ALE_PORTCTL,
1008 .port_offset = 4,
1009 .shift = 11,
1010 .port_shift = 0,
1011 .bits = 1,
1012 },
1013 [ALE_PORT_MACONLY_CAF] = {
1014 .name = "mac_only_port_caf",
1015 .offset = ALE_PORTCTL,
1016 .port_offset = 4,
1017 .shift = 13,
1018 .port_shift = 0,
1019 .bits = 1,
1020 },
1021 [ALE_PORT_MCAST_LIMIT] = {
1022 .name = "mcast_limit",
1023 .offset = ALE_PORTCTL,
1024 .port_offset = 4,
1025 .shift = 16,
1026 .port_shift = 0,
1027 .bits = 8,
1028 },
1029 [ALE_PORT_BCAST_LIMIT] = {
1030 .name = "bcast_limit",
1031 .offset = ALE_PORTCTL,
1032 .port_offset = 4,
1033 .shift = 24,
1034 .port_shift = 0,
1035 .bits = 8,
1036 },
1037 [ALE_PORT_UNKNOWN_VLAN_MEMBER] = {
1038 .name = "unknown_vlan_member",
1039 .offset = ALE_UNKNOWNVLAN,
1040 .port_offset = 0,
1041 .shift = 0,
1042 .port_shift = 0,
1043 .bits = 6,
1044 },
1045 [ALE_PORT_UNKNOWN_MCAST_FLOOD] = {
1046 .name = "unknown_mcast_flood",
1047 .offset = ALE_UNKNOWNVLAN,
1048 .port_offset = 0,
1049 .shift = 8,
1050 .port_shift = 0,
1051 .bits = 6,
1052 },
1053 [ALE_PORT_UNKNOWN_REG_MCAST_FLOOD] = {
1054 .name = "unknown_reg_flood",
1055 .offset = ALE_UNKNOWNVLAN,
1056 .port_offset = 0,
1057 .shift = 16,
1058 .port_shift = 0,
1059 .bits = 6,
1060 },
1061 [ALE_PORT_UNTAGGED_EGRESS] = {
1062 .name = "untagged_egress",
1063 .offset = ALE_UNKNOWNVLAN,
1064 .port_offset = 0,
1065 .shift = 24,
1066 .port_shift = 0,
1067 .bits = 6,
1068 },
1069 [ALE_DEFAULT_THREAD_ID] = {
1070 .name = "default_thread_id",
1071 .offset = AM65_CPSW_ALE_THREAD_DEF_REG,
1072 .port_offset = 0,
1073 .shift = 0,
1074 .port_shift = 0,
1075 .bits = 6,
1076 },
1077 [ALE_DEFAULT_THREAD_ENABLE] = {
1078 .name = "default_thread_id_enable",
1079 .offset = AM65_CPSW_ALE_THREAD_DEF_REG,
1080 .port_offset = 0,
1081 .shift = 15,
1082 .port_shift = 0,
1083 .bits = 1,
1084 },
1085 };
1086
1087 int cpsw_ale_control_set(struct cpsw_ale *ale, int port, int control,
1088 int value)
1089 {
1090 const struct ale_control_info *info;
1091 int offset, shift;
1092 u32 tmp, mask;
1093
1094 if (control < 0 || control >= ARRAY_SIZE(ale_controls))
1095 return -EINVAL;
1096
1097 info = &ale_controls[control];
1098 if (info->port_offset == 0 && info->port_shift == 0)
1099 port = 0;
1100
1101 if (port < 0 || port >= ale->params.ale_ports)
1102 return -EINVAL;
1103
1104 mask = BITMASK(info->bits);
1105 if (value & ~mask)
1106 return -EINVAL;
1107
1108 offset = info->offset + (port * info->port_offset);
1109 shift = info->shift + (port * info->port_shift);
1110
1111 tmp = readl_relaxed(ale->params.ale_regs + offset);
1112 tmp = (tmp & ~(mask << shift)) | (value << shift);
1113 writel_relaxed(tmp, ale->params.ale_regs + offset);
1114
1115 return 0;
1116 }
1117
1118 int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control)
1119 {
1120 const struct ale_control_info *info;
1121 int offset, shift;
1122 u32 tmp;
1123
1124 if (control < 0 || control >= ARRAY_SIZE(ale_controls))
1125 return -EINVAL;
1126
1127 info = &ale_controls[control];
1128 if (info->port_offset == 0 && info->port_shift == 0)
1129 port = 0;
1130
1131 if (port < 0 || port >= ale->params.ale_ports)
1132 return -EINVAL;
1133
1134 offset = info->offset + (port * info->port_offset);
1135 shift = info->shift + (port * info->port_shift);
1136
1137 tmp = readl_relaxed(ale->params.ale_regs + offset) >> shift;
1138 return tmp & BITMASK(info->bits);
1139 }
1140
1141 int cpsw_ale_rx_ratelimit_mc(struct cpsw_ale *ale, int port, unsigned int ratelimit_pps)
1142
1143 {
1144 int val = ratelimit_pps / ALE_RATE_LIMIT_MIN_PPS;
1145 u32 remainder = ratelimit_pps % ALE_RATE_LIMIT_MIN_PPS;
1146
1147 if (ratelimit_pps && !val) {
1148 dev_err(ale->params.dev, "ALE MC port:%d ratelimit min value 1000pps\n", port);
1149 return -EINVAL;
1150 }
1151
1152 if (remainder)
1153 dev_info(ale->params.dev, "ALE port:%d MC ratelimit set to %dpps (requested %d)\n",
1154 port, ratelimit_pps - remainder, ratelimit_pps);
1155
1156 cpsw_ale_control_set(ale, port, ALE_PORT_MCAST_LIMIT, val);
1157
1158 dev_dbg(ale->params.dev, "ALE port:%d MC ratelimit set %d\n",
1159 port, val * ALE_RATE_LIMIT_MIN_PPS);
1160 return 0;
1161 }
1162
1163 int cpsw_ale_rx_ratelimit_bc(struct cpsw_ale *ale, int port, unsigned int ratelimit_pps)
1164
1165 {
1166 int val = ratelimit_pps / ALE_RATE_LIMIT_MIN_PPS;
1167 u32 remainder = ratelimit_pps % ALE_RATE_LIMIT_MIN_PPS;
1168
1169 if (ratelimit_pps && !val) {
1170 dev_err(ale->params.dev, "ALE port:%d BC ratelimit min value 1000pps\n", port);
1171 return -EINVAL;
1172 }
1173
1174 if (remainder)
1175 dev_info(ale->params.dev, "ALE port:%d BC ratelimit set to %dpps (requested %d)\n",
1176 port, ratelimit_pps - remainder, ratelimit_pps);
1177
1178 cpsw_ale_control_set(ale, port, ALE_PORT_BCAST_LIMIT, val);
1179
1180 dev_dbg(ale->params.dev, "ALE port:%d BC ratelimit set %d\n",
1181 port, val * ALE_RATE_LIMIT_MIN_PPS);
1182 return 0;
1183 }
1184
1185 static void cpsw_ale_timer(struct timer_list *t)
1186 {
1187 struct cpsw_ale *ale = from_timer(ale, t, timer);
1188
1189 cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
1190
1191 if (ale->ageout) {
1192 ale->timer.expires = jiffies + ale->ageout;
1193 add_timer(&ale->timer);
1194 }
1195 }
1196
1197 static void cpsw_ale_hw_aging_timer_start(struct cpsw_ale *ale)
1198 {
1199 u32 aging_timer;
1200
1201 aging_timer = ale->params.bus_freq / 1000000;
1202 aging_timer *= ale->params.ale_ageout;
1203
1204 if (aging_timer & ~ALE_AGING_TIMER_MASK) {
1205 aging_timer = ALE_AGING_TIMER_MASK;
1206 dev_warn(ale->params.dev,
1207 "ALE aging timer overflow, set to max\n");
1208 }
1209
1210 writel(aging_timer, ale->params.ale_regs + ALE_AGING_TIMER);
1211 }
1212
1213 static void cpsw_ale_hw_aging_timer_stop(struct cpsw_ale *ale)
1214 {
1215 writel(0, ale->params.ale_regs + ALE_AGING_TIMER);
1216 }
1217
1218 static void cpsw_ale_aging_start(struct cpsw_ale *ale)
1219 {
1220 if (!ale->params.ale_ageout)
1221 return;
1222
1223 if (ale->features & CPSW_ALE_F_HW_AUTOAGING) {
1224 cpsw_ale_hw_aging_timer_start(ale);
1225 return;
1226 }
1227
1228 timer_setup(&ale->timer, cpsw_ale_timer, 0);
1229 ale->timer.expires = jiffies + ale->ageout;
1230 add_timer(&ale->timer);
1231 }
1232
1233 static void cpsw_ale_aging_stop(struct cpsw_ale *ale)
1234 {
1235 if (!ale->params.ale_ageout)
1236 return;
1237
1238 if (ale->features & CPSW_ALE_F_HW_AUTOAGING) {
1239 cpsw_ale_hw_aging_timer_stop(ale);
1240 return;
1241 }
1242
1243 del_timer_sync(&ale->timer);
1244 }
1245
1246 void cpsw_ale_start(struct cpsw_ale *ale)
1247 {
1248 unsigned long ale_prescale;
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260 ale_prescale = ale->params.bus_freq / ALE_RATE_LIMIT_MIN_PPS;
1261 writel((u32)ale_prescale, ale->params.ale_regs + ALE_PRESCALE);
1262
1263
1264
1265
1266 cpsw_ale_control_set(ale, 0, ALE_RATE_LIMIT, 1);
1267
1268 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 1);
1269 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
1270
1271 cpsw_ale_aging_start(ale);
1272 }
1273
1274 void cpsw_ale_stop(struct cpsw_ale *ale)
1275 {
1276 cpsw_ale_aging_stop(ale);
1277 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
1278 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0);
1279 }
1280
1281 static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = {
1282 {
1283
1284 .dev_id = "cpsw",
1285 .tbl_entries = 1024,
1286 .major_ver_mask = 0xff,
1287 .vlan_entry_tbl = vlan_entry_cpsw,
1288 },
1289 {
1290
1291 .dev_id = "66ak2h-xgbe",
1292 .tbl_entries = 2048,
1293 .major_ver_mask = 0xff,
1294 .vlan_entry_tbl = vlan_entry_cpsw,
1295 },
1296 {
1297 .dev_id = "66ak2el",
1298 .features = CPSW_ALE_F_STATUS_REG,
1299 .major_ver_mask = 0x7,
1300 .nu_switch_ale = true,
1301 .vlan_entry_tbl = vlan_entry_nu,
1302 },
1303 {
1304 .dev_id = "66ak2g",
1305 .features = CPSW_ALE_F_STATUS_REG,
1306 .tbl_entries = 64,
1307 .major_ver_mask = 0x7,
1308 .nu_switch_ale = true,
1309 .vlan_entry_tbl = vlan_entry_nu,
1310 },
1311 {
1312 .dev_id = "am65x-cpsw2g",
1313 .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
1314 .tbl_entries = 64,
1315 .major_ver_mask = 0x7,
1316 .nu_switch_ale = true,
1317 .vlan_entry_tbl = vlan_entry_nu,
1318 },
1319 {
1320 .dev_id = "j721e-cpswxg",
1321 .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
1322 .major_ver_mask = 0x7,
1323 .vlan_entry_tbl = vlan_entry_k3_cpswxg,
1324 },
1325 {
1326 .dev_id = "am64-cpswxg",
1327 .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
1328 .major_ver_mask = 0x7,
1329 .vlan_entry_tbl = vlan_entry_k3_cpswxg,
1330 .tbl_entries = 512,
1331 },
1332 { },
1333 };
1334
1335 static const struct
1336 cpsw_ale_dev_id *cpsw_ale_match_id(const struct cpsw_ale_dev_id *id,
1337 const char *dev_id)
1338 {
1339 if (!dev_id)
1340 return NULL;
1341
1342 while (id->dev_id) {
1343 if (strcmp(dev_id, id->dev_id) == 0)
1344 return id;
1345 id++;
1346 }
1347 return NULL;
1348 }
1349
1350 struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params)
1351 {
1352 const struct cpsw_ale_dev_id *ale_dev_id;
1353 struct cpsw_ale *ale;
1354 u32 rev, ale_entries;
1355
1356 ale_dev_id = cpsw_ale_match_id(cpsw_ale_id_match, params->dev_id);
1357 if (!ale_dev_id)
1358 return ERR_PTR(-EINVAL);
1359
1360 params->ale_entries = ale_dev_id->tbl_entries;
1361 params->major_ver_mask = ale_dev_id->major_ver_mask;
1362 params->nu_switch_ale = ale_dev_id->nu_switch_ale;
1363
1364 ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL);
1365 if (!ale)
1366 return ERR_PTR(-ENOMEM);
1367
1368 ale->p0_untag_vid_mask = devm_bitmap_zalloc(params->dev, VLAN_N_VID,
1369 GFP_KERNEL);
1370 if (!ale->p0_untag_vid_mask)
1371 return ERR_PTR(-ENOMEM);
1372
1373 ale->params = *params;
1374 ale->ageout = ale->params.ale_ageout * HZ;
1375 ale->features = ale_dev_id->features;
1376 ale->vlan_entry_tbl = ale_dev_id->vlan_entry_tbl;
1377
1378 rev = readl_relaxed(ale->params.ale_regs + ALE_IDVER);
1379 ale->version =
1380 (ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask) << 8) |
1381 ALE_VERSION_MINOR(rev);
1382 dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n",
1383 ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask),
1384 ALE_VERSION_MINOR(rev));
1385
1386 if (ale->features & CPSW_ALE_F_STATUS_REG &&
1387 !ale->params.ale_entries) {
1388 ale_entries =
1389 readl_relaxed(ale->params.ale_regs + ALE_STATUS) &
1390 ALE_STATUS_SIZE_MASK;
1391
1392
1393
1394
1395
1396
1397
1398 if (!ale_entries)
1399 return ERR_PTR(-EINVAL);
1400
1401 ale_entries *= ALE_TABLE_SIZE_MULTIPLIER;
1402 ale->params.ale_entries = ale_entries;
1403 }
1404 dev_info(ale->params.dev,
1405 "ALE Table size %ld\n", ale->params.ale_entries);
1406
1407
1408 ale->port_mask_bits = ale->params.ale_ports;
1409 ale->port_num_bits = order_base_2(ale->params.ale_ports);
1410 ale->vlan_field_bits = ale->params.ale_ports;
1411
1412
1413
1414
1415 if (ale->params.nu_switch_ale) {
1416
1417
1418
1419
1420 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].bits =
1421 ale->params.ale_ports;
1422 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].offset =
1423 ALE_UNKNOWNVLAN_MEMBER;
1424 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].bits =
1425 ale->params.ale_ports;
1426 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].shift = 0;
1427 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].offset =
1428 ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD;
1429 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].bits =
1430 ale->params.ale_ports;
1431 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].shift = 0;
1432 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].offset =
1433 ALE_UNKNOWNVLAN_REG_MCAST_FLOOD;
1434 ale_controls[ALE_PORT_UNTAGGED_EGRESS].bits =
1435 ale->params.ale_ports;
1436 ale_controls[ALE_PORT_UNTAGGED_EGRESS].shift = 0;
1437 ale_controls[ALE_PORT_UNTAGGED_EGRESS].offset =
1438 ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS;
1439 }
1440
1441 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
1442 return ale;
1443 }
1444
1445 void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data)
1446 {
1447 int i;
1448
1449 for (i = 0; i < ale->params.ale_entries; i++) {
1450 cpsw_ale_read(ale, i, data);
1451 data += ALE_ENTRY_WORDS;
1452 }
1453 }
1454
1455 u32 cpsw_ale_get_num_entries(struct cpsw_ale *ale)
1456 {
1457 return ale ? ale->params.ale_entries : 0;
1458 }