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