2 * Texas Instruments N-Port Ethernet Switch Address Lookup Engine
4 * Copyright (C) 2012 Texas Instruments
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/platform_device.h>
18 #include <linux/seq_file.h>
19 #include <linux/slab.h>
20 #include <linux/err.h>
22 #include <linux/stat.h>
23 #include <linux/sysfs.h>
24 #include <linux/etherdevice.h>
28 #define BITMASK(bits) (BIT(bits) - 1)
30 #define ALE_VERSION_MAJOR(rev, mask) (((rev) >> 8) & (mask))
31 #define ALE_VERSION_MINOR(rev) (rev & 0xff)
32 #define ALE_VERSION_1R3 0x0103
33 #define ALE_VERSION_1R4 0x0104
36 #define ALE_IDVER 0x00
37 #define ALE_STATUS 0x04
38 #define ALE_CONTROL 0x08
39 #define ALE_PRESCALE 0x10
40 #define ALE_UNKNOWNVLAN 0x18
41 #define ALE_TABLE_CONTROL 0x20
42 #define ALE_TABLE 0x34
43 #define ALE_PORTCTL 0x40
45 /* ALE NetCP NU switch specific Registers */
46 #define ALE_UNKNOWNVLAN_MEMBER 0x90
47 #define ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD 0x94
48 #define ALE_UNKNOWNVLAN_REG_MCAST_FLOOD 0x98
49 #define ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS 0x9C
50 #define ALE_VLAN_MASK_MUX(reg) (0xc0 + (0x4 * (reg)))
52 #define ALE_TABLE_WRITE BIT(31)
54 #define ALE_TYPE_FREE 0
55 #define ALE_TYPE_ADDR 1
56 #define ALE_TYPE_VLAN 2
57 #define ALE_TYPE_VLAN_ADDR 3
59 #define ALE_UCAST_PERSISTANT 0
60 #define ALE_UCAST_UNTOUCHED 1
61 #define ALE_UCAST_OUI 2
62 #define ALE_UCAST_TOUCHED 3
64 #define ALE_TABLE_SIZE_MULTIPLIER 1024
65 #define ALE_STATUS_SIZE_MASK 0x1f
66 #define ALE_TABLE_SIZE_DEFAULT 64
68 static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
74 idx = 2 - idx; /* flip */
75 return (ale_entry[idx] >> start) & BITMASK(bits);
78 static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
83 value &= BITMASK(bits);
86 idx = 2 - idx; /* flip */
87 ale_entry[idx] &= ~(BITMASK(bits) << start);
88 ale_entry[idx] |= (value << start);
91 #define DEFINE_ALE_FIELD(name, start, bits) \
92 static inline int cpsw_ale_get_##name(u32 *ale_entry) \
94 return cpsw_ale_get_field(ale_entry, start, bits); \
96 static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value) \
98 cpsw_ale_set_field(ale_entry, start, bits, value); \
101 #define DEFINE_ALE_FIELD1(name, start) \
102 static inline int cpsw_ale_get_##name(u32 *ale_entry, u32 bits) \
104 return cpsw_ale_get_field(ale_entry, start, bits); \
106 static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value, \
109 cpsw_ale_set_field(ale_entry, start, bits, value); \
112 DEFINE_ALE_FIELD(entry_type, 60, 2)
113 DEFINE_ALE_FIELD(vlan_id, 48, 12)
114 DEFINE_ALE_FIELD(mcast_state, 62, 2)
115 DEFINE_ALE_FIELD1(port_mask, 66)
116 DEFINE_ALE_FIELD(super, 65, 1)
117 DEFINE_ALE_FIELD(ucast_type, 62, 2)
118 DEFINE_ALE_FIELD1(port_num, 66)
119 DEFINE_ALE_FIELD(blocked, 65, 1)
120 DEFINE_ALE_FIELD(secure, 64, 1)
121 DEFINE_ALE_FIELD1(vlan_untag_force, 24)
122 DEFINE_ALE_FIELD1(vlan_reg_mcast, 16)
123 DEFINE_ALE_FIELD1(vlan_unreg_mcast, 8)
124 DEFINE_ALE_FIELD1(vlan_member_list, 0)
125 DEFINE_ALE_FIELD(mcast, 40, 1)
126 /* ALE NetCP nu switch specific */
127 DEFINE_ALE_FIELD(vlan_unreg_mcast_idx, 20, 3)
128 DEFINE_ALE_FIELD(vlan_reg_mcast_idx, 44, 3)
130 /* The MAC address field in the ALE entry cannot be macroized as above */
131 static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr)
135 for (i = 0; i < 6; i++)
136 addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8);
139 static inline void cpsw_ale_set_addr(u32 *ale_entry, u8 *addr)
143 for (i = 0; i < 6; i++)
144 cpsw_ale_set_field(ale_entry, 40 - 8*i, 8, addr[i]);
147 static int cpsw_ale_read(struct cpsw_ale *ale, int idx, u32 *ale_entry)
151 WARN_ON(idx > ale->params.ale_entries);
153 __raw_writel(idx, ale->params.ale_regs + ALE_TABLE_CONTROL);
155 for (i = 0; i < ALE_ENTRY_WORDS; i++)
156 ale_entry[i] = __raw_readl(ale->params.ale_regs +
162 static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry)
166 WARN_ON(idx > ale->params.ale_entries);
168 for (i = 0; i < ALE_ENTRY_WORDS; i++)
169 __raw_writel(ale_entry[i], ale->params.ale_regs +
172 __raw_writel(idx | ALE_TABLE_WRITE, ale->params.ale_regs +
178 static int cpsw_ale_match_addr(struct cpsw_ale *ale, u8 *addr, u16 vid)
180 u32 ale_entry[ALE_ENTRY_WORDS];
183 for (idx = 0; idx < ale->params.ale_entries; idx++) {
186 cpsw_ale_read(ale, idx, ale_entry);
187 type = cpsw_ale_get_entry_type(ale_entry);
188 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
190 if (cpsw_ale_get_vlan_id(ale_entry) != vid)
192 cpsw_ale_get_addr(ale_entry, entry_addr);
193 if (ether_addr_equal(entry_addr, addr))
199 static int cpsw_ale_match_vlan(struct cpsw_ale *ale, u16 vid)
201 u32 ale_entry[ALE_ENTRY_WORDS];
204 for (idx = 0; idx < ale->params.ale_entries; idx++) {
205 cpsw_ale_read(ale, idx, ale_entry);
206 type = cpsw_ale_get_entry_type(ale_entry);
207 if (type != ALE_TYPE_VLAN)
209 if (cpsw_ale_get_vlan_id(ale_entry) == vid)
215 static int cpsw_ale_match_free(struct cpsw_ale *ale)
217 u32 ale_entry[ALE_ENTRY_WORDS];
220 for (idx = 0; idx < ale->params.ale_entries; idx++) {
221 cpsw_ale_read(ale, idx, ale_entry);
222 type = cpsw_ale_get_entry_type(ale_entry);
223 if (type == ALE_TYPE_FREE)
229 static int cpsw_ale_find_ageable(struct cpsw_ale *ale)
231 u32 ale_entry[ALE_ENTRY_WORDS];
234 for (idx = 0; idx < ale->params.ale_entries; idx++) {
235 cpsw_ale_read(ale, idx, ale_entry);
236 type = cpsw_ale_get_entry_type(ale_entry);
237 if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
239 if (cpsw_ale_get_mcast(ale_entry))
241 type = cpsw_ale_get_ucast_type(ale_entry);
242 if (type != ALE_UCAST_PERSISTANT &&
243 type != ALE_UCAST_OUI)
249 static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry,
254 mask = cpsw_ale_get_port_mask(ale_entry,
255 ale->port_mask_bits);
256 if ((mask & port_mask) == 0)
257 return; /* ports dont intersect, not interested */
260 /* free if only remaining port is host port */
262 cpsw_ale_set_port_mask(ale_entry, mask,
263 ale->port_mask_bits);
265 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
268 int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid)
270 u32 ale_entry[ALE_ENTRY_WORDS];
273 for (idx = 0; idx < ale->params.ale_entries; idx++) {
274 cpsw_ale_read(ale, idx, ale_entry);
275 ret = cpsw_ale_get_entry_type(ale_entry);
276 if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR)
279 /* if vid passed is -1 then remove all multicast entry from
280 * the table irrespective of vlan id, if a valid vlan id is
281 * passed then remove only multicast added to that vlan id.
282 * if vlan id doesn't match then move on to next entry.
284 if (vid != -1 && cpsw_ale_get_vlan_id(ale_entry) != vid)
287 if (cpsw_ale_get_mcast(ale_entry)) {
290 cpsw_ale_get_addr(ale_entry, addr);
291 if (!is_broadcast_ether_addr(addr))
292 cpsw_ale_flush_mcast(ale, ale_entry, port_mask);
295 cpsw_ale_write(ale, idx, ale_entry);
299 EXPORT_SYMBOL_GPL(cpsw_ale_flush_multicast);
301 static inline void cpsw_ale_set_vlan_entry_type(u32 *ale_entry,
304 if (flags & ALE_VLAN) {
305 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN_ADDR);
306 cpsw_ale_set_vlan_id(ale_entry, vid);
308 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
312 int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port,
315 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
318 cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);
320 cpsw_ale_set_addr(ale_entry, addr);
321 cpsw_ale_set_ucast_type(ale_entry, ALE_UCAST_PERSISTANT);
322 cpsw_ale_set_secure(ale_entry, (flags & ALE_SECURE) ? 1 : 0);
323 cpsw_ale_set_blocked(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0);
324 cpsw_ale_set_port_num(ale_entry, port, ale->port_num_bits);
326 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
328 idx = cpsw_ale_match_free(ale);
330 idx = cpsw_ale_find_ageable(ale);
334 cpsw_ale_write(ale, idx, ale_entry);
337 EXPORT_SYMBOL_GPL(cpsw_ale_add_ucast);
339 int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port,
342 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
345 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
349 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
350 cpsw_ale_write(ale, idx, ale_entry);
353 EXPORT_SYMBOL_GPL(cpsw_ale_del_ucast);
355 int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
356 int flags, u16 vid, int mcast_state)
358 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
361 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
363 cpsw_ale_read(ale, idx, ale_entry);
365 cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);
367 cpsw_ale_set_addr(ale_entry, addr);
368 cpsw_ale_set_super(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0);
369 cpsw_ale_set_mcast_state(ale_entry, mcast_state);
371 mask = cpsw_ale_get_port_mask(ale_entry,
372 ale->port_mask_bits);
374 cpsw_ale_set_port_mask(ale_entry, port_mask,
375 ale->port_mask_bits);
378 idx = cpsw_ale_match_free(ale);
380 idx = cpsw_ale_find_ageable(ale);
384 cpsw_ale_write(ale, idx, ale_entry);
387 EXPORT_SYMBOL_GPL(cpsw_ale_add_mcast);
389 int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
392 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
395 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
399 cpsw_ale_read(ale, idx, ale_entry);
402 cpsw_ale_set_port_mask(ale_entry, port_mask,
403 ale->port_mask_bits);
405 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
407 cpsw_ale_write(ale, idx, ale_entry);
410 EXPORT_SYMBOL_GPL(cpsw_ale_del_mcast);
412 /* ALE NetCP NU switch specific vlan functions */
413 static void cpsw_ale_set_vlan_mcast(struct cpsw_ale *ale, u32 *ale_entry,
414 int reg_mcast, int unreg_mcast)
418 /* Set VLAN registered multicast flood mask */
419 idx = cpsw_ale_get_vlan_reg_mcast_idx(ale_entry);
420 writel(reg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
422 /* Set VLAN unregistered multicast flood mask */
423 idx = cpsw_ale_get_vlan_unreg_mcast_idx(ale_entry);
424 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
427 int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag,
428 int reg_mcast, int unreg_mcast)
430 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
433 idx = cpsw_ale_match_vlan(ale, vid);
435 cpsw_ale_read(ale, idx, ale_entry);
437 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN);
438 cpsw_ale_set_vlan_id(ale_entry, vid);
440 cpsw_ale_set_vlan_untag_force(ale_entry, untag, ale->vlan_field_bits);
441 if (!ale->params.nu_switch_ale) {
442 cpsw_ale_set_vlan_reg_mcast(ale_entry, reg_mcast,
443 ale->vlan_field_bits);
444 cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast,
445 ale->vlan_field_bits);
447 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast, unreg_mcast);
449 cpsw_ale_set_vlan_member_list(ale_entry, port, ale->vlan_field_bits);
452 idx = cpsw_ale_match_free(ale);
454 idx = cpsw_ale_find_ageable(ale);
458 cpsw_ale_write(ale, idx, ale_entry);
461 EXPORT_SYMBOL_GPL(cpsw_ale_add_vlan);
463 int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask)
465 u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
468 idx = cpsw_ale_match_vlan(ale, vid);
472 cpsw_ale_read(ale, idx, ale_entry);
475 cpsw_ale_set_vlan_member_list(ale_entry, port_mask,
476 ale->vlan_field_bits);
478 cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
480 cpsw_ale_write(ale, idx, ale_entry);
483 EXPORT_SYMBOL_GPL(cpsw_ale_del_vlan);
485 void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti)
487 u32 ale_entry[ALE_ENTRY_WORDS];
491 /* Only bother doing the work if the setting is actually changing */
492 if (ale->allmulti == allmulti)
495 /* Remember the new setting to check against next time */
496 ale->allmulti = allmulti;
498 for (idx = 0; idx < ale->params.ale_entries; idx++) {
499 cpsw_ale_read(ale, idx, ale_entry);
500 type = cpsw_ale_get_entry_type(ale_entry);
501 if (type != ALE_TYPE_VLAN)
505 cpsw_ale_get_vlan_unreg_mcast(ale_entry,
506 ale->vlan_field_bits);
511 cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast,
512 ale->vlan_field_bits);
513 cpsw_ale_write(ale, idx, ale_entry);
516 EXPORT_SYMBOL_GPL(cpsw_ale_set_allmulti);
518 struct ale_control_info {
520 int offset, port_offset;
521 int shift, port_shift;
525 static struct ale_control_info ale_controls[ALE_NUM_CONTROLS] = {
528 .offset = ALE_CONTROL,
536 .offset = ALE_CONTROL,
544 .offset = ALE_CONTROL,
550 [ALE_P0_UNI_FLOOD] = {
551 .name = "port0_unicast_flood",
552 .offset = ALE_CONTROL,
558 [ALE_VLAN_NOLEARN] = {
559 .name = "vlan_nolearn",
560 .offset = ALE_CONTROL,
566 [ALE_NO_PORT_VLAN] = {
567 .name = "no_port_vlan",
568 .offset = ALE_CONTROL,
576 .offset = ALE_CONTROL,
584 .offset = ALE_CONTROL,
590 [ALE_RATE_LIMIT_TX] = {
591 .name = "rate_limit_tx",
592 .offset = ALE_CONTROL,
599 .name = "vlan_aware",
600 .offset = ALE_CONTROL,
606 [ALE_AUTH_ENABLE] = {
607 .name = "auth_enable",
608 .offset = ALE_CONTROL,
615 .name = "rate_limit",
616 .offset = ALE_CONTROL,
623 .name = "port_state",
624 .offset = ALE_PORTCTL,
630 [ALE_PORT_DROP_UNTAGGED] = {
631 .name = "drop_untagged",
632 .offset = ALE_PORTCTL,
638 [ALE_PORT_DROP_UNKNOWN_VLAN] = {
639 .name = "drop_unknown",
640 .offset = ALE_PORTCTL,
646 [ALE_PORT_NOLEARN] = {
648 .offset = ALE_PORTCTL,
654 [ALE_PORT_NO_SA_UPDATE] = {
655 .name = "no_source_update",
656 .offset = ALE_PORTCTL,
662 [ALE_PORT_MCAST_LIMIT] = {
663 .name = "mcast_limit",
664 .offset = ALE_PORTCTL,
670 [ALE_PORT_BCAST_LIMIT] = {
671 .name = "bcast_limit",
672 .offset = ALE_PORTCTL,
678 [ALE_PORT_UNKNOWN_VLAN_MEMBER] = {
679 .name = "unknown_vlan_member",
680 .offset = ALE_UNKNOWNVLAN,
686 [ALE_PORT_UNKNOWN_MCAST_FLOOD] = {
687 .name = "unknown_mcast_flood",
688 .offset = ALE_UNKNOWNVLAN,
694 [ALE_PORT_UNKNOWN_REG_MCAST_FLOOD] = {
695 .name = "unknown_reg_flood",
696 .offset = ALE_UNKNOWNVLAN,
702 [ALE_PORT_UNTAGGED_EGRESS] = {
703 .name = "untagged_egress",
704 .offset = ALE_UNKNOWNVLAN,
712 int cpsw_ale_control_set(struct cpsw_ale *ale, int port, int control,
715 const struct ale_control_info *info;
719 if (control < 0 || control >= ARRAY_SIZE(ale_controls))
722 info = &ale_controls[control];
723 if (info->port_offset == 0 && info->port_shift == 0)
724 port = 0; /* global, port is a dont care */
726 if (port < 0 || port > ale->params.ale_ports)
729 mask = BITMASK(info->bits);
733 offset = info->offset + (port * info->port_offset);
734 shift = info->shift + (port * info->port_shift);
736 tmp = __raw_readl(ale->params.ale_regs + offset);
737 tmp = (tmp & ~(mask << shift)) | (value << shift);
738 __raw_writel(tmp, ale->params.ale_regs + offset);
742 EXPORT_SYMBOL_GPL(cpsw_ale_control_set);
744 int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control)
746 const struct ale_control_info *info;
750 if (control < 0 || control >= ARRAY_SIZE(ale_controls))
753 info = &ale_controls[control];
754 if (info->port_offset == 0 && info->port_shift == 0)
755 port = 0; /* global, port is a dont care */
757 if (port < 0 || port > ale->params.ale_ports)
760 offset = info->offset + (port * info->port_offset);
761 shift = info->shift + (port * info->port_shift);
763 tmp = __raw_readl(ale->params.ale_regs + offset) >> shift;
764 return tmp & BITMASK(info->bits);
766 EXPORT_SYMBOL_GPL(cpsw_ale_control_get);
768 static void cpsw_ale_timer(unsigned long arg)
770 struct cpsw_ale *ale = (struct cpsw_ale *)arg;
772 cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
775 ale->timer.expires = jiffies + ale->ageout;
776 add_timer(&ale->timer);
780 void cpsw_ale_start(struct cpsw_ale *ale)
782 u32 rev, ale_entries;
784 rev = __raw_readl(ale->params.ale_regs + ALE_IDVER);
785 if (!ale->params.major_ver_mask)
786 ale->params.major_ver_mask = 0xff;
788 (ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask) << 8) |
789 ALE_VERSION_MINOR(rev);
790 dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n",
791 ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask),
792 ALE_VERSION_MINOR(rev));
794 if (!ale->params.ale_entries) {
796 __raw_readl(ale->params.ale_regs + ALE_STATUS) &
797 ALE_STATUS_SIZE_MASK;
798 /* ALE available on newer NetCP switches has introduced
799 * a register, ALE_STATUS, to indicate the size of ALE
800 * table which shows the size as a multiple of 1024 entries.
801 * For these, params.ale_entries will be set to zero. So
802 * read the register and update the value of ale_entries.
803 * ALE table on NetCP lite, is much smaller and is indicated
804 * by a value of zero in ALE_STATUS. So use a default value
805 * of ALE_TABLE_SIZE_DEFAULT for this. Caller is expected
806 * to set the value of ale_entries for all other versions
810 ale_entries = ALE_TABLE_SIZE_DEFAULT;
812 ale_entries *= ALE_TABLE_SIZE_MULTIPLIER;
813 ale->params.ale_entries = ale_entries;
815 dev_info(ale->params.dev,
816 "ALE Table size %ld\n", ale->params.ale_entries);
818 /* set default bits for existing h/w */
819 ale->port_mask_bits = 3;
820 ale->port_num_bits = 2;
821 ale->vlan_field_bits = 3;
823 /* Set defaults override for ALE on NetCP NU switch and for version
826 if (ale->params.nu_switch_ale) {
827 /* Separate registers for unknown vlan configuration.
828 * Also there are N bits, where N is number of ale
829 * ports and shift value should be 0
831 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].bits =
832 ale->params.ale_ports;
833 ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].offset =
834 ALE_UNKNOWNVLAN_MEMBER;
835 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].bits =
836 ale->params.ale_ports;
837 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].shift = 0;
838 ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].offset =
839 ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD;
840 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].bits =
841 ale->params.ale_ports;
842 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].shift = 0;
843 ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].offset =
844 ALE_UNKNOWNVLAN_REG_MCAST_FLOOD;
845 ale_controls[ALE_PORT_UNTAGGED_EGRESS].bits =
846 ale->params.ale_ports;
847 ale_controls[ALE_PORT_UNTAGGED_EGRESS].shift = 0;
848 ale_controls[ALE_PORT_UNTAGGED_EGRESS].offset =
849 ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS;
850 ale->port_mask_bits = ale->params.ale_ports;
851 ale->port_num_bits = ale->params.ale_ports - 1;
852 ale->vlan_field_bits = ale->params.ale_ports;
853 } else if (ale->version == ALE_VERSION_1R3) {
854 ale->port_mask_bits = ale->params.ale_ports;
855 ale->port_num_bits = 3;
856 ale->vlan_field_bits = ale->params.ale_ports;
859 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 1);
860 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1);
862 init_timer(&ale->timer);
863 ale->timer.data = (unsigned long)ale;
864 ale->timer.function = cpsw_ale_timer;
866 ale->timer.expires = jiffies + ale->ageout;
867 add_timer(&ale->timer);
870 EXPORT_SYMBOL_GPL(cpsw_ale_start);
872 void cpsw_ale_stop(struct cpsw_ale *ale)
874 del_timer_sync(&ale->timer);
876 EXPORT_SYMBOL_GPL(cpsw_ale_stop);
878 struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params)
880 struct cpsw_ale *ale;
882 ale = kzalloc(sizeof(*ale), GFP_KERNEL);
886 ale->params = *params;
887 ale->ageout = ale->params.ale_ageout * HZ;
891 EXPORT_SYMBOL_GPL(cpsw_ale_create);
893 int cpsw_ale_destroy(struct cpsw_ale *ale)
897 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0);
901 EXPORT_SYMBOL_GPL(cpsw_ale_destroy);
903 void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data)
907 for (i = 0; i < ale->params.ale_entries; i++) {
908 cpsw_ale_read(ale, i, data);
909 data += ALE_ENTRY_WORDS;
912 EXPORT_SYMBOL_GPL(cpsw_ale_dump);
914 MODULE_LICENSE("GPL v2");
915 MODULE_DESCRIPTION("TI CPSW ALE driver");
916 MODULE_AUTHOR("Texas Instruments");