1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Texas Instruments N-Port Ethernet Switch Address Lookup Engine APIs |
4 | * |
5 | * Copyright (C) 2012 Texas Instruments |
6 | * |
7 | */ |
8 | #ifndef __TI_CPSW_ALE_H__ |
9 | #define __TI_CPSW_ALE_H__ |
10 | |
11 | struct cpsw_ale_params { |
12 | struct device *dev; |
13 | void __iomem *ale_regs; |
14 | unsigned long ale_ageout; /* in secs */ |
15 | unsigned long ale_entries; |
16 | unsigned long ale_ports; |
17 | /* NU Switch has specific handling as number of bits in ALE entries |
18 | * are different than other versions of ALE. Also there are specific |
19 | * registers for unknown vlan specific fields. So use nu_switch_ale |
20 | * to identify this hardware. |
21 | */ |
22 | bool nu_switch_ale; |
23 | /* mask bit used in NU Switch ALE is 3 bits instead of 8 bits. So |
24 | * pass it from caller. |
25 | */ |
26 | u32 major_ver_mask; |
27 | const char *dev_id; |
28 | unsigned long bus_freq; |
29 | }; |
30 | |
31 | struct ale_entry_fld; |
32 | |
33 | struct cpsw_ale { |
34 | struct cpsw_ale_params params; |
35 | struct timer_list timer; |
36 | unsigned long ageout; |
37 | u32 version; |
38 | u32 features; |
39 | /* These bits are different on NetCP NU Switch ALE */ |
40 | u32 port_mask_bits; |
41 | u32 port_num_bits; |
42 | u32 vlan_field_bits; |
43 | unsigned long *p0_untag_vid_mask; |
44 | const struct ale_entry_fld *vlan_entry_tbl; |
45 | }; |
46 | |
47 | enum cpsw_ale_control { |
48 | /* global */ |
49 | ALE_ENABLE, |
50 | ALE_CLEAR, |
51 | ALE_AGEOUT, |
52 | ALE_P0_UNI_FLOOD, |
53 | ALE_VLAN_NOLEARN, |
54 | ALE_NO_PORT_VLAN, |
55 | ALE_OUI_DENY, |
56 | ALE_BYPASS, |
57 | ALE_RATE_LIMIT_TX, |
58 | ALE_VLAN_AWARE, |
59 | ALE_AUTH_ENABLE, |
60 | ALE_RATE_LIMIT, |
61 | /* port controls */ |
62 | ALE_PORT_STATE, |
63 | ALE_PORT_DROP_UNTAGGED, |
64 | ALE_PORT_DROP_UNKNOWN_VLAN, |
65 | ALE_PORT_NOLEARN, |
66 | ALE_PORT_NO_SA_UPDATE, |
67 | ALE_PORT_UNKNOWN_VLAN_MEMBER, |
68 | ALE_PORT_UNKNOWN_MCAST_FLOOD, |
69 | ALE_PORT_UNKNOWN_REG_MCAST_FLOOD, |
70 | ALE_PORT_UNTAGGED_EGRESS, |
71 | ALE_PORT_MACONLY, |
72 | ALE_PORT_MACONLY_CAF, |
73 | ALE_PORT_BCAST_LIMIT, |
74 | ALE_PORT_MCAST_LIMIT, |
75 | ALE_DEFAULT_THREAD_ID, |
76 | ALE_DEFAULT_THREAD_ENABLE, |
77 | ALE_NUM_CONTROLS, |
78 | }; |
79 | |
80 | enum cpsw_ale_port_state { |
81 | ALE_PORT_STATE_DISABLE = 0x00, |
82 | ALE_PORT_STATE_BLOCK = 0x01, |
83 | ALE_PORT_STATE_LEARN = 0x02, |
84 | ALE_PORT_STATE_FORWARD = 0x03, |
85 | }; |
86 | |
87 | /* ALE unicast entry flags - passed into cpsw_ale_add_ucast() */ |
88 | #define ALE_SECURE BIT(0) |
89 | #define ALE_BLOCKED BIT(1) |
90 | #define ALE_SUPER BIT(2) |
91 | #define ALE_VLAN BIT(3) |
92 | |
93 | #define ALE_PORT_HOST BIT(0) |
94 | #define ALE_PORT_1 BIT(1) |
95 | #define ALE_PORT_2 BIT(2) |
96 | |
97 | #define ALE_MCAST_FWD 0 |
98 | #define ALE_MCAST_BLOCK_LEARN_FWD 1 |
99 | #define ALE_MCAST_FWD_LEARN 2 |
100 | #define ALE_MCAST_FWD_2 3 |
101 | |
102 | #define ALE_ENTRY_BITS 68 |
103 | #define ALE_ENTRY_WORDS DIV_ROUND_UP(ALE_ENTRY_BITS, 32) |
104 | |
105 | struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params); |
106 | |
107 | void cpsw_ale_start(struct cpsw_ale *ale); |
108 | void cpsw_ale_stop(struct cpsw_ale *ale); |
109 | |
110 | int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid); |
111 | int cpsw_ale_add_ucast(struct cpsw_ale *ale, const u8 *addr, int port, |
112 | int flags, u16 vid); |
113 | int cpsw_ale_del_ucast(struct cpsw_ale *ale, const u8 *addr, int port, |
114 | int flags, u16 vid); |
115 | int cpsw_ale_add_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask, |
116 | int flags, u16 vid, int mcast_state); |
117 | int cpsw_ale_del_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask, |
118 | int flags, u16 vid); |
119 | int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag, |
120 | int reg_mcast, int unreg_mcast); |
121 | int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port); |
122 | void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti, int port); |
123 | int cpsw_ale_rx_ratelimit_bc(struct cpsw_ale *ale, int port, unsigned int ratelimit_pps); |
124 | int cpsw_ale_rx_ratelimit_mc(struct cpsw_ale *ale, int port, unsigned int ratelimit_pps); |
125 | |
126 | int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control); |
127 | int cpsw_ale_control_set(struct cpsw_ale *ale, int port, |
128 | int control, int value); |
129 | void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data); |
130 | void cpsw_ale_restore(struct cpsw_ale *ale, u32 *data); |
131 | u32 cpsw_ale_get_num_entries(struct cpsw_ale *ale); |
132 | |
133 | static inline int cpsw_ale_get_vlan_p0_untag(struct cpsw_ale *ale, u16 vid) |
134 | { |
135 | return test_bit(vid, ale->p0_untag_vid_mask); |
136 | } |
137 | |
138 | int cpsw_ale_vlan_add_modify(struct cpsw_ale *ale, u16 vid, int port_mask, |
139 | int untag_mask, int reg_mcast, int unreg_mcast); |
140 | int cpsw_ale_vlan_del_modify(struct cpsw_ale *ale, u16 vid, int port_mask); |
141 | void cpsw_ale_set_unreg_mcast(struct cpsw_ale *ale, int unreg_mcast_mask, |
142 | bool add); |
143 | |
144 | #endif |
145 | |