1d14abf15SRobert Mustacchi #ifndef ECORE_ERASE
2d14abf15SRobert Mustacchi #ifdef __LINUX
3d14abf15SRobert Mustacchi 
4d14abf15SRobert Mustacchi #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5d14abf15SRobert Mustacchi 
6d14abf15SRobert Mustacchi #include <linux/kernel.h>
7d14abf15SRobert Mustacchi #include <linux/types.h>
8d14abf15SRobert Mustacchi #include <asm/byteorder.h>
9d14abf15SRobert Mustacchi #include <linux/version.h>
10d14abf15SRobert Mustacchi #include <linux/module.h>
11d14abf15SRobert Mustacchi #include <linux/crc32.h>
12d14abf15SRobert Mustacchi #include <linux/etherdevice.h>
13d14abf15SRobert Mustacchi 
14d14abf15SRobert Mustacchi #define ECORE_ALIGN(x, a) ALIGN(x, a)
15d14abf15SRobert Mustacchi #endif
16d14abf15SRobert Mustacchi 
17d14abf15SRobert Mustacchi /* Always define ECORE_OOO for VBD */
18d14abf15SRobert Mustacchi #define ECORE_OOO
19d14abf15SRobert Mustacchi 
20d14abf15SRobert Mustacchi #include "bcmtype.h"
21d14abf15SRobert Mustacchi #include "utils.h"
22d14abf15SRobert Mustacchi #include "lm5710.h"
23d14abf15SRobert Mustacchi #include "ecore_sp_verbs.h"
24d14abf15SRobert Mustacchi #include "command.h"
25d14abf15SRobert Mustacchi #include "debug.h"
26d14abf15SRobert Mustacchi #include "ecore_common.h"
27d14abf15SRobert Mustacchi 
28d14abf15SRobert Mustacchi /************************ Debug print macros **********************************/
29d14abf15SRobert Mustacchi #if !defined(UEFI) && defined(DBG)
30d14abf15SRobert Mustacchi #define ECORE_MSG(pdev, m, ...) \
31d14abf15SRobert Mustacchi 	DbgMessage(pdev, WARNi, m, ##__VA_ARGS__)
32d14abf15SRobert Mustacchi #else
33d14abf15SRobert Mustacchi #define ECORE_MSG
34d14abf15SRobert Mustacchi #endif
35d14abf15SRobert Mustacchi 
36d14abf15SRobert Mustacchi /************************ Error prints ****************************************/
37d14abf15SRobert Mustacchi #if !defined(UEFI) && defined(DBG)
38d14abf15SRobert Mustacchi #define ECORE_ERR(str, ...) DbgMessage(pdev, FATAL, str, ##__VA_ARGS__)
39d14abf15SRobert Mustacchi #else
40d14abf15SRobert Mustacchi #define ECORE_ERR
41d14abf15SRobert Mustacchi #endif
42d14abf15SRobert Mustacchi 
43d14abf15SRobert Mustacchi 
44d14abf15SRobert Mustacchi /***********************  ECORE WRAPPER MACROS ********************************/
45d14abf15SRobert Mustacchi 
46d14abf15SRobert Mustacchi #define ECORE_RET_PENDING(pending_bit, pending) \
47d14abf15SRobert Mustacchi 	(ECORE_TEST_BIT(pending_bit, pending) ? ECORE_PENDING : ECORE_SUCCESS)
48d14abf15SRobert Mustacchi 
49d14abf15SRobert Mustacchi #define ECORE_ZALLOC(_size, _flags, _pdev) mm_rt_zalloc_mem(_pdev, _size)
50d14abf15SRobert Mustacchi #define ECORE_CALLOC(_len, _size, _flags, _pdev) mm_rt_zalloc_mem(_pdev, _len * _size)
51d14abf15SRobert Mustacchi #define ECORE_FREE(_pdev, _buf, _size) mm_rt_free_mem(_pdev, _buf, _size, 0)
52d14abf15SRobert Mustacchi 
53d14abf15SRobert Mustacchi /*
54d14abf15SRobert Mustacchi  *  Ecore implementation of set/get flag
55d14abf15SRobert Mustacchi  *  (differs from VBD set_flags, get_flags)
56d14abf15SRobert Mustacchi  */
57d14abf15SRobert Mustacchi #define ECORE_SET_FLAG(value, mask, flag) \
58d14abf15SRobert Mustacchi 	do {\
59d14abf15SRobert Mustacchi 		(value) &= ~(mask);\
60d14abf15SRobert Mustacchi 		(value) |= ((flag) << (mask##_SHIFT));\
61d14abf15SRobert Mustacchi 	} while (0)
62d14abf15SRobert Mustacchi 
63d14abf15SRobert Mustacchi #define ECORE_GET_FLAG(value, mask) \
64d14abf15SRobert Mustacchi 	(((value) &= (mask)) >> (mask##_SHIFT))
65d14abf15SRobert Mustacchi 
66d14abf15SRobert Mustacchi #define ecore_sp_post(_pdev, _cmd , _cid, _data, _con_type) \
67d14abf15SRobert Mustacchi 	lm_sq_post(_pdev, _cid, (u8)(_cmd), CMD_PRIORITY_NORMAL, _con_type, \
68d14abf15SRobert Mustacchi 	_data)
69d14abf15SRobert Mustacchi 
70d14abf15SRobert Mustacchi #define ECORE_SET_CTX_VALIDATION(_pdev, _cxt, _cid) \
71d14abf15SRobert Mustacchi 	lm_set_cdu_validation_data(_pdev, _cid, FALSE) /* context? type? */
72d14abf15SRobert Mustacchi /************************ TODO for LM people!!! *******************************/
73d14abf15SRobert Mustacchi #define ECORE_TODO_UPDATE_COALESCE_SB_INDEX(a1, a2, a3, a4, a5)
74d14abf15SRobert Mustacchi #define ECORE_TODO_LINK_REPORT(pdev)
75d14abf15SRobert Mustacchi #define ECORE_TODO_FW_COMMAND(_pdev, _drv_msg_code, _val) (-1)
76d14abf15SRobert Mustacchi 
77d14abf15SRobert Mustacchi /************************ Lists ***********************************************/
78d14abf15SRobert Mustacchi #define ECORE_LIST_FOR_EACH_ENTRY(pos, _head, _link, cast) \
79d14abf15SRobert Mustacchi 	for (pos = (cast *)d_list_peek_head(_head); \
80d14abf15SRobert Mustacchi 	     pos; \
81d14abf15SRobert Mustacchi 	     pos = (cast *)d_list_next_entry(&pos->_link))
82d14abf15SRobert Mustacchi 
83d14abf15SRobert Mustacchi /**
84d14abf15SRobert Mustacchi  * ECORE_LIST_FOR_EACH_ENTRY_SAFE - iterate over list of given type
85d14abf15SRobert Mustacchi  * @pos:        the type * to use as a loop cursor.
86d14abf15SRobert Mustacchi  * @n:          another type * to use as temporary storage
87d14abf15SRobert Mustacchi  * @head:       the head for your list.
88d14abf15SRobert Mustacchi  * @member:     the name of the list_struct within the struct.
89d14abf15SRobert Mustacchi  *
90d14abf15SRobert Mustacchi  * iterate over list of given type safe against removal of list entry
91d14abf15SRobert Mustacchi  */
92d14abf15SRobert Mustacchi #define ECORE_LIST_FOR_EACH_ENTRY_SAFE(pos, n, head, member, cast)   \
93d14abf15SRobert Mustacchi 	 for (pos = (cast *)d_list_peek_head(head), \
94d14abf15SRobert Mustacchi 	      n = (pos) ? (cast *)d_list_next_entry(&pos->member) : NULL; \
95d14abf15SRobert Mustacchi 	      pos != NULL;  \
96d14abf15SRobert Mustacchi 	      pos = (cast *)n, \
97d14abf15SRobert Mustacchi 	      n = (pos) ? (cast *)d_list_next_entry(&pos->member) : NULL)
98d14abf15SRobert Mustacchi 
99d14abf15SRobert Mustacchi #define ECORE_LIST_IS_LAST(_link, _list)                (_link == (_list)->tail)
100d14abf15SRobert Mustacchi 
101d14abf15SRobert Mustacchi #define ECORE_LIST_IS_EMPTY(head)                       \
102d14abf15SRobert Mustacchi 	d_list_is_empty(head)
103d14abf15SRobert Mustacchi 
104d14abf15SRobert Mustacchi #define ECORE_LIST_FIRST_ENTRY(head, cast, link)	\
105d14abf15SRobert Mustacchi 	(cast *)d_list_peek_head(head)
106d14abf15SRobert Mustacchi 
107d14abf15SRobert Mustacchi #define ECORE_LIST_NEXT(pos, link, cast)	\
108d14abf15SRobert Mustacchi 	(cast *)d_list_next_entry(&((pos)->link))
109d14abf15SRobert Mustacchi 
110d14abf15SRobert Mustacchi #define ECORE_LIST_INIT(head)				\
111d14abf15SRobert Mustacchi do { \
112d14abf15SRobert Mustacchi 	d_list_clear(head); \
113d14abf15SRobert Mustacchi } while (0)
114d14abf15SRobert Mustacchi 
115d14abf15SRobert Mustacchi #define ECORE_LIST_PUSH_TAIL(link, head)		\
116d14abf15SRobert Mustacchi do { \
117d14abf15SRobert Mustacchi 	d_list_push_tail(head, link); \
118d14abf15SRobert Mustacchi } while (0)
119d14abf15SRobert Mustacchi 
120d14abf15SRobert Mustacchi #define ECORE_LIST_PUSH_HEAD(link, head)		\
121d14abf15SRobert Mustacchi do { \
122d14abf15SRobert Mustacchi 	d_list_push_head(head, link); \
123d14abf15SRobert Mustacchi } while (0)
124d14abf15SRobert Mustacchi 
125d14abf15SRobert Mustacchi #define ECORE_LIST_REMOVE_ENTRY(link, head)		\
126d14abf15SRobert Mustacchi do { \
127d14abf15SRobert Mustacchi 	d_list_remove_entry(head, link); \
128d14abf15SRobert Mustacchi } while (0)
129d14abf15SRobert Mustacchi 
130d14abf15SRobert Mustacchi #define ECORE_LIST_SPLICE_INIT(new_head, head) \
131d14abf15SRobert Mustacchi do { \
132d14abf15SRobert Mustacchi 	d_list_add_head(head, new_head); \
133d14abf15SRobert Mustacchi 	d_list_clear(new_head); \
134d14abf15SRobert Mustacchi } while (0)
135d14abf15SRobert Mustacchi 
ecore_crc32_le(u32_t seed,u8_t * mac,u32_t len)136d14abf15SRobert Mustacchi static __inline u32_t ecore_crc32_le(u32_t seed, u8_t *mac, u32_t len)
137d14abf15SRobert Mustacchi {
138d14abf15SRobert Mustacchi 	u32_t packet_buf[2] = {0};
139d14abf15SRobert Mustacchi 
140d14abf15SRobert Mustacchi 	memcpy(((u8_t *)(&packet_buf[0]))+2, &mac[0], 2);
141d14abf15SRobert Mustacchi 	memcpy(&packet_buf[1], &mac[2], 4);
142d14abf15SRobert Mustacchi 	return SWAP_BYTES32(calc_crc32((u8_t *)packet_buf, 8, seed, 0));
143d14abf15SRobert Mustacchi }
144d14abf15SRobert Mustacchi 
145d14abf15SRobert Mustacchi /************************ Per compilation target ******************************/
146d14abf15SRobert Mustacchi #ifdef __LINUX
147d14abf15SRobert Mustacchi 
148d14abf15SRobert Mustacchi #define ECORE_UNLIKELY	unlikely
149d14abf15SRobert Mustacchi #define ECORE_LIKELY	likely
150d14abf15SRobert Mustacchi 
151d14abf15SRobert Mustacchi #define ecore_atomic_read		mm_atomic_read
152d14abf15SRobert Mustacchi #define ecore_atomic_cmpxchg		mm_atomic_cmpxchg
153d14abf15SRobert Mustacchi #define ecore_atomic_set(a, v)		mm_atomic_set((u32_t *)(a), v)
154d14abf15SRobert Mustacchi #define smp_mb__before_atomic() mm_barrier()
155d14abf15SRobert Mustacchi #define smp_mb__after_atomic()  mm_barrier()
156d14abf15SRobert Mustacchi 
157d14abf15SRobert Mustacchi /* Other */
158d14abf15SRobert Mustacchi #define ECORE_IS_VALID_ETHER_ADDR(_mac)               is_valid_ether_addr(_mac)
159d14abf15SRobert Mustacchi #define ECORE_SET_WAIT_COUNT(_cnt)
160d14abf15SRobert Mustacchi #define ECORE_SET_WAIT_DELAY_US(_cnt, _delay_us)
161d14abf15SRobert Mustacchi 
162d14abf15SRobert Mustacchi /* Mutex related */
163d14abf15SRobert Mustacchi #define ECORE_MUTEX_INIT(_mutex)	mutex_init(_mutex)
164d14abf15SRobert Mustacchi #define ECORE_MUTEX_LOCK(_mutex)	mutex_lock(_mutex)
165d14abf15SRobert Mustacchi #define ECORE_MUTEX_UNLOCK(_mutex)	mutex_unlock(_mutex)
166d14abf15SRobert Mustacchi 
167d14abf15SRobert Mustacchi #define ECORE_MIGHT_SLEEP() ediag_might_sleep()
168d14abf15SRobert Mustacchi #define ECORE_TEST_BIT(bit, var)  test_bit(bit, var)
169d14abf15SRobert Mustacchi #define ECORE_TEST_AND_CLEAR_BIT(bit, var) test_and_clear_bit(bit, var)
170d14abf15SRobert Mustacchi 
171d14abf15SRobert Mustacchi #else /* ! LINUX */
172d14abf15SRobert Mustacchi 
173d14abf15SRobert Mustacchi typedef u16 __le16;
174d14abf15SRobert Mustacchi 
175d14abf15SRobert Mustacchi #define ecore_atomic_read		mm_atomic_read
176d14abf15SRobert Mustacchi #define ecore_atomic_cmpxchg		mm_atomic_cmpxchg
177d14abf15SRobert Mustacchi #define ecore_atomic_set(a, val)	mm_atomic_set((u32_t *)(a), val)
178d14abf15SRobert Mustacchi 
179d14abf15SRobert Mustacchi #define ECORE_UNLIKELY(x)	(x)
180d14abf15SRobert Mustacchi #define ECORE_LIKELY(x)		(x)
181d14abf15SRobert Mustacchi #define BUG() DbgBreakMsg("Bug")
182d14abf15SRobert Mustacchi #define smp_mb()                   mm_barrier()
183d14abf15SRobert Mustacchi #define smp_mb__before_atomic() mm_barrier()
184d14abf15SRobert Mustacchi #define smp_mb__after_atomic()  mm_barrier()
185d14abf15SRobert Mustacchi #define mb()                       mm_barrier()
186d14abf15SRobert Mustacchi #define wmb()                      mm_barrier()
187d14abf15SRobert Mustacchi #define mmiowb()		   mm_barrier()
188d14abf15SRobert Mustacchi 
189d14abf15SRobert Mustacchi #define ECORE_MIGHT_SLEEP() /* IRQL_PASSIVE_CODE() */
190d14abf15SRobert Mustacchi 
191d14abf15SRobert Mustacchi /* Mutex related */
192d14abf15SRobert Mustacchi #define ECORE_MUTEX_INIT(_mutex)
193d14abf15SRobert Mustacchi #define ECORE_MUTEX_LOCK(_mutex)
194d14abf15SRobert Mustacchi #define ECORE_MUTEX_UNLOCK(_mutex)
195d14abf15SRobert Mustacchi 
196d14abf15SRobert Mustacchi /* Atomic Bit Manipulation */
197d14abf15SRobert Mustacchi #define ECORE_TEST_BIT(_bit, _var) \
198d14abf15SRobert Mustacchi 	(mm_atomic_long_read(_var) & (1 << (_bit)))
199d14abf15SRobert Mustacchi 
200d14abf15SRobert Mustacchi /* Other */
201d14abf15SRobert Mustacchi #define ECORE_IS_VALID_ETHER_ADDR(_mac)         TRUE
202d14abf15SRobert Mustacchi #define ECORE_SET_WAIT_DELAY_US(_cnt, _delay_us) \
203d14abf15SRobert Mustacchi do { \
204d14abf15SRobert Mustacchi 	_delay_us = (_cnt >= 2360) ? 100 : 25000; \
205d14abf15SRobert Mustacchi } while (0)
206d14abf15SRobert Mustacchi 
207d14abf15SRobert Mustacchi /*
208d14abf15SRobert Mustacchi  * In VBD We'll wait 10,000 times 100us (1 second) +
209d14abf15SRobert Mustacchi  * 2360 times 25000us (59sec) = total 60 sec
210d14abf15SRobert Mustacchi  * (Winodws only note) the 25000 wait will cause
211d14abf15SRobert Mustacchi  * wait to be without CPU stall (look in win_util.c)
212d14abf15SRobert Mustacchi  */
213d14abf15SRobert Mustacchi #define ECORE_SET_WAIT_COUNT(_cnt) \
214d14abf15SRobert Mustacchi do { \
215d14abf15SRobert Mustacchi 	_cnt = 10000 + 2360; \
216d14abf15SRobert Mustacchi } while (0)
217d14abf15SRobert Mustacchi 
ECORE_TEST_AND_CLEAR_BIT(int bit,unsigned long * vec)218d14abf15SRobert Mustacchi static __inline BOOL ECORE_TEST_AND_CLEAR_BIT(int bit, unsigned long *vec)
219d14abf15SRobert Mustacchi {
220d14abf15SRobert Mustacchi 	BOOL set = ECORE_TEST_BIT(bit, vec);
221d14abf15SRobert Mustacchi 	ECORE_CLEAR_BIT(bit, vec);
222d14abf15SRobert Mustacchi 
223d14abf15SRobert Mustacchi 	return set;
224d14abf15SRobert Mustacchi }
225d14abf15SRobert Mustacchi 
226d14abf15SRobert Mustacchi #endif /* END if "per LM target type" */
227d14abf15SRobert Mustacchi 
228d14abf15SRobert Mustacchi /* Spin lock related */
229d14abf15SRobert Mustacchi #define ECORE_SPIN_LOCK_INIT(_spin, _pdev)	mm_init_lock(_pdev, _spin)
230d14abf15SRobert Mustacchi #define ECORE_SPIN_LOCK_BH(_spin)		mm_acquire_lock(_spin)
231d14abf15SRobert Mustacchi #define ECORE_SPIN_UNLOCK_BH(_spin)		mm_release_lock(_spin)
232d14abf15SRobert Mustacchi 
233d14abf15SRobert Mustacchi #endif /* not ECORE_ERASE */
234d14abf15SRobert Mustacchi #if defined(__FreeBSD__) && !defined(NOT_LINUX)
235d14abf15SRobert Mustacchi #include "bxe.h"
236d14abf15SRobert Mustacchi #include "ecore_init.h"
237d14abf15SRobert Mustacchi #elif !defined(EDIAG)
238d14abf15SRobert Mustacchi #ifdef ECORE_ERASE
239d14abf15SRobert Mustacchi #include <linux/version.h>
240d14abf15SRobert Mustacchi #include <linux/module.h>
241d14abf15SRobert Mustacchi #include <linux/crc32.h>
242d14abf15SRobert Mustacchi #include <linux/netdevice.h>
243d14abf15SRobert Mustacchi #include <linux/etherdevice.h>
244d14abf15SRobert Mustacchi #if (LINUX_VERSION_CODE >= 0x02061b) && !defined(BNX2X_DRIVER_DISK) && !defined(__VMKLNX__) /* BNX2X_UPSTREAM */
245d14abf15SRobert Mustacchi #include <linux/crc32c.h>
246d14abf15SRobert Mustacchi #endif
247d14abf15SRobert Mustacchi #include "bnx2x.h"
248d14abf15SRobert Mustacchi #include "bnx2x_cmn.h"
249d14abf15SRobert Mustacchi #include "bnx2x_sp.h"
250d14abf15SRobert Mustacchi 
251d14abf15SRobert Mustacchi #define ECORE_MAX_EMUL_MULTI		16
252d14abf15SRobert Mustacchi #endif
253d14abf15SRobert Mustacchi #endif
254d14abf15SRobert Mustacchi 
255d14abf15SRobert Mustacchi /**** Exe Queue interfaces ****/
256d14abf15SRobert Mustacchi 
257d14abf15SRobert Mustacchi /**
258d14abf15SRobert Mustacchi  * ecore_exe_queue_init - init the Exe Queue object
259d14abf15SRobert Mustacchi  *
260d14abf15SRobert Mustacchi  * @o:		pointer to the object
261d14abf15SRobert Mustacchi  * @exe_len:	length
262d14abf15SRobert Mustacchi  * @owner:	pointer to the owner
263d14abf15SRobert Mustacchi  * @validate:	validate function pointer
264d14abf15SRobert Mustacchi  * @optimize:	optimize function pointer
265d14abf15SRobert Mustacchi  * @exec:	execute function pointer
266d14abf15SRobert Mustacchi  * @get:	get function pointer
267d14abf15SRobert Mustacchi  */
ecore_exe_queue_init(struct _lm_device_t * pdev,struct ecore_exe_queue_obj * o,int exe_len,union ecore_qable_obj * owner,exe_q_validate validate,exe_q_remove remove,exe_q_optimize optimize,exe_q_execute exec,exe_q_get get)268d14abf15SRobert Mustacchi static INLINE void ecore_exe_queue_init(struct _lm_device_t *pdev,
269d14abf15SRobert Mustacchi 					struct ecore_exe_queue_obj *o,
270d14abf15SRobert Mustacchi 					int exe_len,
271d14abf15SRobert Mustacchi 					union ecore_qable_obj *owner,
272d14abf15SRobert Mustacchi 					exe_q_validate validate,
273d14abf15SRobert Mustacchi 					exe_q_remove remove,
274d14abf15SRobert Mustacchi 					exe_q_optimize optimize,
275d14abf15SRobert Mustacchi 					exe_q_execute exec,
276d14abf15SRobert Mustacchi 					exe_q_get get)
277d14abf15SRobert Mustacchi {
278d14abf15SRobert Mustacchi 	mm_memset(o, 0, sizeof(*o));
279d14abf15SRobert Mustacchi 
280d14abf15SRobert Mustacchi 	ECORE_LIST_INIT(&o->exe_queue);
281d14abf15SRobert Mustacchi 	ECORE_LIST_INIT(&o->pending_comp);
282d14abf15SRobert Mustacchi 
283d14abf15SRobert Mustacchi 	ECORE_SPIN_LOCK_INIT(&o->lock, pdev);
284d14abf15SRobert Mustacchi 
285d14abf15SRobert Mustacchi 	o->exe_chunk_len = exe_len;
286d14abf15SRobert Mustacchi 	o->owner         = owner;
287d14abf15SRobert Mustacchi 
288d14abf15SRobert Mustacchi 	/* Owner specific callbacks */
289d14abf15SRobert Mustacchi 	o->validate      = validate;
290d14abf15SRobert Mustacchi 	o->remove        = remove;
291d14abf15SRobert Mustacchi 	o->optimize      = optimize;
292d14abf15SRobert Mustacchi 	o->execute       = exec;
293d14abf15SRobert Mustacchi 	o->get           = get;
294d14abf15SRobert Mustacchi 
295d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Setup the execution queue with the chunk length of %d\n",
296d14abf15SRobert Mustacchi 		  exe_len);
297d14abf15SRobert Mustacchi }
298d14abf15SRobert Mustacchi 
ecore_exe_queue_free_elem(struct _lm_device_t * pdev,struct ecore_exeq_elem * elem)299d14abf15SRobert Mustacchi static INLINE void ecore_exe_queue_free_elem(struct _lm_device_t *pdev,
300d14abf15SRobert Mustacchi 					     struct ecore_exeq_elem *elem)
301d14abf15SRobert Mustacchi {
302d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Deleting an exe_queue element\n");
303d14abf15SRobert Mustacchi 	ECORE_FREE(pdev, elem, sizeof(*elem));
304d14abf15SRobert Mustacchi }
305d14abf15SRobert Mustacchi 
ecore_exe_queue_length(struct ecore_exe_queue_obj * o)306d14abf15SRobert Mustacchi static INLINE int ecore_exe_queue_length(struct ecore_exe_queue_obj *o)
307d14abf15SRobert Mustacchi {
308d14abf15SRobert Mustacchi 	struct ecore_exeq_elem *elem;
309d14abf15SRobert Mustacchi 	int cnt = 0;
310d14abf15SRobert Mustacchi 
311d14abf15SRobert Mustacchi #ifdef ECORE_ERASE
312d14abf15SRobert Mustacchi 	spin_lock_bh(&o->lock);
313d14abf15SRobert Mustacchi #endif
314d14abf15SRobert Mustacchi 
315d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(elem, &o->exe_queue, link,
316d14abf15SRobert Mustacchi 				  struct ecore_exeq_elem)
317d14abf15SRobert Mustacchi 		cnt++;
318d14abf15SRobert Mustacchi 
319d14abf15SRobert Mustacchi #ifdef ECORE_ERASE
320d14abf15SRobert Mustacchi 	spin_unlock_bh(&o->lock);
321d14abf15SRobert Mustacchi #endif
322d14abf15SRobert Mustacchi 
323d14abf15SRobert Mustacchi 	return cnt;
324d14abf15SRobert Mustacchi }
325d14abf15SRobert Mustacchi 
326d14abf15SRobert Mustacchi /**
327d14abf15SRobert Mustacchi  * ecore_exe_queue_add - add a new element to the execution queue
328d14abf15SRobert Mustacchi  *
329d14abf15SRobert Mustacchi  * @pdev:	driver handle
330d14abf15SRobert Mustacchi  * @o:		queue
331d14abf15SRobert Mustacchi  * @cmd:	new command to add
332d14abf15SRobert Mustacchi  * @restore:	true - do not optimize the command
333d14abf15SRobert Mustacchi  *
334d14abf15SRobert Mustacchi  * If the element is optimized or is illegal, frees it.
335d14abf15SRobert Mustacchi  */
ecore_exe_queue_add(struct _lm_device_t * pdev,struct ecore_exe_queue_obj * o,struct ecore_exeq_elem * elem,BOOL restore)336d14abf15SRobert Mustacchi static INLINE int ecore_exe_queue_add(struct _lm_device_t *pdev,
337d14abf15SRobert Mustacchi 				      struct ecore_exe_queue_obj *o,
338d14abf15SRobert Mustacchi 				      struct ecore_exeq_elem *elem,
339d14abf15SRobert Mustacchi 				      BOOL restore)
340d14abf15SRobert Mustacchi {
341d14abf15SRobert Mustacchi 	int rc;
342d14abf15SRobert Mustacchi 
343d14abf15SRobert Mustacchi 	ECORE_SPIN_LOCK_BH(&o->lock);
344d14abf15SRobert Mustacchi 
345d14abf15SRobert Mustacchi 	if (!restore) {
346d14abf15SRobert Mustacchi 		/* Try to cancel this element queue */
347d14abf15SRobert Mustacchi 		rc = o->optimize(pdev, o->owner, elem);
348d14abf15SRobert Mustacchi 		if (rc)
349d14abf15SRobert Mustacchi 			goto free_and_exit;
350d14abf15SRobert Mustacchi 
351d14abf15SRobert Mustacchi 		/* Check if this request is ok */
352d14abf15SRobert Mustacchi 		rc = o->validate(pdev, o->owner, elem);
353d14abf15SRobert Mustacchi 		if (rc) {
354d14abf15SRobert Mustacchi 			ECORE_MSG(pdev, "Preamble failed: %d\n", rc);
355d14abf15SRobert Mustacchi 			goto free_and_exit;
356d14abf15SRobert Mustacchi 		}
357d14abf15SRobert Mustacchi 	}
358d14abf15SRobert Mustacchi 
359d14abf15SRobert Mustacchi 	/* If so, add it to the execution queue */
360d14abf15SRobert Mustacchi 	ECORE_LIST_PUSH_TAIL(&elem->link, &o->exe_queue);
361d14abf15SRobert Mustacchi 
362d14abf15SRobert Mustacchi 	ECORE_SPIN_UNLOCK_BH(&o->lock);
363d14abf15SRobert Mustacchi 
364d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
365d14abf15SRobert Mustacchi 
366d14abf15SRobert Mustacchi free_and_exit:
367d14abf15SRobert Mustacchi 	ecore_exe_queue_free_elem(pdev, elem);
368d14abf15SRobert Mustacchi 
369d14abf15SRobert Mustacchi 	ECORE_SPIN_UNLOCK_BH(&o->lock);
370d14abf15SRobert Mustacchi 
371d14abf15SRobert Mustacchi 	return rc;
372d14abf15SRobert Mustacchi }
373d14abf15SRobert Mustacchi 
__ecore_exe_queue_reset_pending(struct _lm_device_t * pdev,struct ecore_exe_queue_obj * o)374d14abf15SRobert Mustacchi static INLINE void __ecore_exe_queue_reset_pending(
375d14abf15SRobert Mustacchi 	struct _lm_device_t *pdev,
376d14abf15SRobert Mustacchi 	struct ecore_exe_queue_obj *o)
377d14abf15SRobert Mustacchi {
378d14abf15SRobert Mustacchi 	struct ecore_exeq_elem *elem;
379d14abf15SRobert Mustacchi 
380d14abf15SRobert Mustacchi 	while (!ECORE_LIST_IS_EMPTY(&o->pending_comp)) {
381d14abf15SRobert Mustacchi 		elem = ECORE_LIST_FIRST_ENTRY(&o->pending_comp,
382d14abf15SRobert Mustacchi 					      struct ecore_exeq_elem,
383d14abf15SRobert Mustacchi 					      link);
384d14abf15SRobert Mustacchi 
385d14abf15SRobert Mustacchi 		ECORE_LIST_REMOVE_ENTRY(&elem->link, &o->pending_comp);
386d14abf15SRobert Mustacchi 		ecore_exe_queue_free_elem(pdev, elem);
387d14abf15SRobert Mustacchi 	}
388d14abf15SRobert Mustacchi }
389d14abf15SRobert Mustacchi 
390d14abf15SRobert Mustacchi /**
391d14abf15SRobert Mustacchi  * ecore_exe_queue_step - execute one execution chunk atomically
392d14abf15SRobert Mustacchi  *
393d14abf15SRobert Mustacchi  * @pdev:		driver handle
394d14abf15SRobert Mustacchi  * @o:			queue
395d14abf15SRobert Mustacchi  * @ramrod_flags:	flags
396d14abf15SRobert Mustacchi  *
397d14abf15SRobert Mustacchi  * (Should be called while holding the exe_queue->lock).
398d14abf15SRobert Mustacchi  */
ecore_exe_queue_step(struct _lm_device_t * pdev,struct ecore_exe_queue_obj * o,unsigned long * ramrod_flags)399d14abf15SRobert Mustacchi static INLINE int ecore_exe_queue_step(struct _lm_device_t *pdev,
400d14abf15SRobert Mustacchi 				       struct ecore_exe_queue_obj *o,
401d14abf15SRobert Mustacchi 				       unsigned long *ramrod_flags)
402d14abf15SRobert Mustacchi {
403d14abf15SRobert Mustacchi 	struct ecore_exeq_elem *elem, spacer;
404d14abf15SRobert Mustacchi 	int cur_len = 0, rc;
405d14abf15SRobert Mustacchi 
406d14abf15SRobert Mustacchi 	mm_memset(&spacer, 0, sizeof(spacer));
407d14abf15SRobert Mustacchi 
408d14abf15SRobert Mustacchi 	/* Next step should not be performed until the current is finished,
409d14abf15SRobert Mustacchi 	 * unless a DRV_CLEAR_ONLY bit is set. In this case we just want to
410d14abf15SRobert Mustacchi 	 * properly clear object internals without sending any command to the FW
411d14abf15SRobert Mustacchi 	 * which also implies there won't be any completion to clear the
412d14abf15SRobert Mustacchi 	 * 'pending' list.
413d14abf15SRobert Mustacchi 	 */
414d14abf15SRobert Mustacchi 	if (!ECORE_LIST_IS_EMPTY(&o->pending_comp)) {
415d14abf15SRobert Mustacchi 		if (ECORE_TEST_BIT(RAMROD_DRV_CLR_ONLY, ramrod_flags)) {
416d14abf15SRobert Mustacchi 			ECORE_MSG(pdev, "RAMROD_DRV_CLR_ONLY requested: resetting a pending_comp list\n");
417d14abf15SRobert Mustacchi 			__ecore_exe_queue_reset_pending(pdev, o);
418d14abf15SRobert Mustacchi 		} else {
419d14abf15SRobert Mustacchi 			return ECORE_PENDING;
420d14abf15SRobert Mustacchi 		}
421d14abf15SRobert Mustacchi 	}
422d14abf15SRobert Mustacchi 
423d14abf15SRobert Mustacchi 	/* Run through the pending commands list and create a next
424d14abf15SRobert Mustacchi 	 * execution chunk.
425d14abf15SRobert Mustacchi 	 */
426d14abf15SRobert Mustacchi 	while (!ECORE_LIST_IS_EMPTY(&o->exe_queue)) {
427d14abf15SRobert Mustacchi 		elem = ECORE_LIST_FIRST_ENTRY(&o->exe_queue,
428d14abf15SRobert Mustacchi 					      struct ecore_exeq_elem,
429d14abf15SRobert Mustacchi 					      link);
430d14abf15SRobert Mustacchi 		DbgBreakIf(!elem->cmd_len);
431d14abf15SRobert Mustacchi 
432d14abf15SRobert Mustacchi 		if (cur_len + elem->cmd_len <= o->exe_chunk_len) {
433d14abf15SRobert Mustacchi 			cur_len += elem->cmd_len;
434d14abf15SRobert Mustacchi 			/* Prevent from both lists being empty when moving an
435d14abf15SRobert Mustacchi 			 * element. This will allow the call of
436d14abf15SRobert Mustacchi 			 * ecore_exe_queue_empty() without locking.
437d14abf15SRobert Mustacchi 			 */
438d14abf15SRobert Mustacchi 			ECORE_LIST_PUSH_TAIL(&spacer.link, &o->pending_comp);
439d14abf15SRobert Mustacchi 			mb();
440d14abf15SRobert Mustacchi 			ECORE_LIST_REMOVE_ENTRY(&elem->link, &o->exe_queue);
441d14abf15SRobert Mustacchi 			ECORE_LIST_PUSH_TAIL(&elem->link, &o->pending_comp);
442d14abf15SRobert Mustacchi 			ECORE_LIST_REMOVE_ENTRY(&spacer.link, &o->pending_comp);
443d14abf15SRobert Mustacchi 		} else
444d14abf15SRobert Mustacchi 			break;
445d14abf15SRobert Mustacchi 	}
446d14abf15SRobert Mustacchi 
447d14abf15SRobert Mustacchi 	/* Sanity check */
448d14abf15SRobert Mustacchi 	if (!cur_len)
449d14abf15SRobert Mustacchi 		return ECORE_SUCCESS;
450d14abf15SRobert Mustacchi 
451d14abf15SRobert Mustacchi 	rc = o->execute(pdev, o->owner, &o->pending_comp, ramrod_flags);
452d14abf15SRobert Mustacchi 	if (rc < 0)
453d14abf15SRobert Mustacchi 		/* In case of an error return the commands back to the queue
454d14abf15SRobert Mustacchi 		 *  and reset the pending_comp.
455d14abf15SRobert Mustacchi 		 */
456d14abf15SRobert Mustacchi 		ECORE_LIST_SPLICE_INIT(&o->pending_comp, &o->exe_queue);
457d14abf15SRobert Mustacchi 	else if (!rc)
458d14abf15SRobert Mustacchi 		/* If zero is returned, means there are no outstanding pending
459d14abf15SRobert Mustacchi 		 * completions and we may dismiss the pending list.
460d14abf15SRobert Mustacchi 		 */
461d14abf15SRobert Mustacchi 		__ecore_exe_queue_reset_pending(pdev, o);
462d14abf15SRobert Mustacchi 
463d14abf15SRobert Mustacchi 	return rc;
464d14abf15SRobert Mustacchi }
465d14abf15SRobert Mustacchi 
ecore_exe_queue_empty(struct ecore_exe_queue_obj * o)466d14abf15SRobert Mustacchi static INLINE BOOL ecore_exe_queue_empty(struct ecore_exe_queue_obj *o)
467d14abf15SRobert Mustacchi {
468d14abf15SRobert Mustacchi 	BOOL empty = ECORE_LIST_IS_EMPTY(&o->exe_queue);
469d14abf15SRobert Mustacchi 
470d14abf15SRobert Mustacchi 	/* Don't reorder!!! */
471d14abf15SRobert Mustacchi 	mb();
472d14abf15SRobert Mustacchi 
473d14abf15SRobert Mustacchi 	return empty && ECORE_LIST_IS_EMPTY(&o->pending_comp);
474d14abf15SRobert Mustacchi }
475d14abf15SRobert Mustacchi 
ecore_exe_queue_alloc_elem(struct _lm_device_t * pdev)476d14abf15SRobert Mustacchi static INLINE struct ecore_exeq_elem *ecore_exe_queue_alloc_elem(
477d14abf15SRobert Mustacchi 	struct _lm_device_t *pdev)
478d14abf15SRobert Mustacchi {
479d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Allocating a new exe_queue element\n");
480d14abf15SRobert Mustacchi 	return ECORE_ZALLOC(sizeof(struct ecore_exeq_elem), GFP_ATOMIC,
481d14abf15SRobert Mustacchi 			    pdev);
482d14abf15SRobert Mustacchi }
483d14abf15SRobert Mustacchi 
484d14abf15SRobert Mustacchi /************************ raw_obj functions ***********************************/
ecore_raw_check_pending(struct ecore_raw_obj * o)485d14abf15SRobert Mustacchi static BOOL ecore_raw_check_pending(struct ecore_raw_obj *o)
486d14abf15SRobert Mustacchi {
487d14abf15SRobert Mustacchi 	/*
488d14abf15SRobert Mustacchi      * !! converts the value returned by ECORE_TEST_BIT such that it
489d14abf15SRobert Mustacchi      * is guaranteed not to be truncated regardless of BOOL definition.
490d14abf15SRobert Mustacchi 	 *
491d14abf15SRobert Mustacchi 	 * Note we cannot simply define the function's return value type
492d14abf15SRobert Mustacchi      * to match the type returned by ECORE_TEST_BIT, as it varies by
493d14abf15SRobert Mustacchi      * platform/implementation.
494d14abf15SRobert Mustacchi 	 */
495d14abf15SRobert Mustacchi 
496d14abf15SRobert Mustacchi 	return !!ECORE_TEST_BIT(o->state, o->pstate);
497d14abf15SRobert Mustacchi }
498d14abf15SRobert Mustacchi 
ecore_raw_clear_pending(struct ecore_raw_obj * o)499d14abf15SRobert Mustacchi static void ecore_raw_clear_pending(struct ecore_raw_obj *o)
500d14abf15SRobert Mustacchi {
501d14abf15SRobert Mustacchi 	smp_mb__before_atomic();
502d14abf15SRobert Mustacchi 	ECORE_CLEAR_BIT(o->state, o->pstate);
503d14abf15SRobert Mustacchi 	smp_mb__after_atomic();
504d14abf15SRobert Mustacchi }
505d14abf15SRobert Mustacchi 
ecore_raw_set_pending(struct ecore_raw_obj * o)506d14abf15SRobert Mustacchi static void ecore_raw_set_pending(struct ecore_raw_obj *o)
507d14abf15SRobert Mustacchi {
508d14abf15SRobert Mustacchi 	smp_mb__before_atomic();
509d14abf15SRobert Mustacchi 	ECORE_SET_BIT(o->state, o->pstate);
510d14abf15SRobert Mustacchi 	smp_mb__after_atomic();
511d14abf15SRobert Mustacchi }
512d14abf15SRobert Mustacchi 
513d14abf15SRobert Mustacchi /**
514d14abf15SRobert Mustacchi  * ecore_state_wait - wait until the given bit(state) is cleared
515d14abf15SRobert Mustacchi  *
516d14abf15SRobert Mustacchi  * @pdev:	device handle
517d14abf15SRobert Mustacchi  * @state:	state which is to be cleared
518d14abf15SRobert Mustacchi  * @state_p:	state buffer
519d14abf15SRobert Mustacchi  *
520d14abf15SRobert Mustacchi  */
ecore_state_wait(struct _lm_device_t * pdev,int state,unsigned long * pstate)521d14abf15SRobert Mustacchi static INLINE int ecore_state_wait(struct _lm_device_t *pdev, int state,
522d14abf15SRobert Mustacchi 				   unsigned long *pstate)
523d14abf15SRobert Mustacchi {
524d14abf15SRobert Mustacchi 	/* can take a while if any port is running */
525d14abf15SRobert Mustacchi 	int cnt = 5000;
526d14abf15SRobert Mustacchi 
527d14abf15SRobert Mustacchi #ifndef ECORE_ERASE
528d14abf15SRobert Mustacchi 	int delay_us = 1000;
529d14abf15SRobert Mustacchi 
530d14abf15SRobert Mustacchi 	/* In VBD We'll wait 10,000 times 100us (1 second) +
531d14abf15SRobert Mustacchi 	* 2360 times 25000us (59sec) = total 60 sec
532d14abf15SRobert Mustacchi 	* (Winodws only note) the 25000 wait will cause wait
533d14abf15SRobert Mustacchi 	* to be without CPU stall (look in win_util.c)
534d14abf15SRobert Mustacchi 	*/
535d14abf15SRobert Mustacchi 	cnt = 10000 + 2360;
536d14abf15SRobert Mustacchi #endif
537d14abf15SRobert Mustacchi 
538d14abf15SRobert Mustacchi 	if (CHIP_REV_IS_EMUL(pdev))
539d14abf15SRobert Mustacchi 		cnt *= 20;
540d14abf15SRobert Mustacchi 
541d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "waiting for state to become %d\n", state);
542d14abf15SRobert Mustacchi 
543d14abf15SRobert Mustacchi 	ECORE_MIGHT_SLEEP();
544d14abf15SRobert Mustacchi 	while (cnt--) {
545d14abf15SRobert Mustacchi 		if (!ECORE_TEST_BIT(state, pstate)) {
546d14abf15SRobert Mustacchi #ifdef ECORE_STOP_ON_ERROR
547d14abf15SRobert Mustacchi 			ECORE_MSG(pdev, "exit  (cnt %d)\n", 5000 - cnt);
548d14abf15SRobert Mustacchi #endif
549d14abf15SRobert Mustacchi 			return ECORE_SUCCESS;
550d14abf15SRobert Mustacchi 		}
551d14abf15SRobert Mustacchi 
552d14abf15SRobert Mustacchi #ifndef ECORE_ERASE
553d14abf15SRobert Mustacchi 		/* in case reset is in progress we won't get completion */
554d14abf15SRobert Mustacchi 		if (lm_reset_is_inprogress(pdev))
555d14abf15SRobert Mustacchi 			return 0;
556d14abf15SRobert Mustacchi 
557d14abf15SRobert Mustacchi 		delay_us = (cnt >= 2360) ? 100 : 25000;
558d14abf15SRobert Mustacchi #endif
559d14abf15SRobert Mustacchi 		mm_wait(pdev, delay_us);
560d14abf15SRobert Mustacchi 
561d14abf15SRobert Mustacchi 		if (pdev->panic)
562d14abf15SRobert Mustacchi 			return ECORE_IO;
563d14abf15SRobert Mustacchi 	}
564d14abf15SRobert Mustacchi 
565d14abf15SRobert Mustacchi 	/* timeout! */
566d14abf15SRobert Mustacchi 	ECORE_ERR("timeout waiting for state %d\n", state);
567d14abf15SRobert Mustacchi #ifdef ECORE_STOP_ON_ERROR
568d14abf15SRobert Mustacchi 	ecore_panic();
569d14abf15SRobert Mustacchi #endif
570d14abf15SRobert Mustacchi 
571d14abf15SRobert Mustacchi 	return ECORE_TIMEOUT;
572d14abf15SRobert Mustacchi }
573d14abf15SRobert Mustacchi 
ecore_raw_wait(struct _lm_device_t * pdev,struct ecore_raw_obj * raw)574d14abf15SRobert Mustacchi static int ecore_raw_wait(struct _lm_device_t *pdev, struct ecore_raw_obj *raw)
575d14abf15SRobert Mustacchi {
576d14abf15SRobert Mustacchi 	return ecore_state_wait(pdev, raw->state, raw->pstate);
577d14abf15SRobert Mustacchi }
578d14abf15SRobert Mustacchi 
579d14abf15SRobert Mustacchi /***************** Classification verbs: Set/Del MAC/VLAN/VLAN-MAC ************/
580d14abf15SRobert Mustacchi /* credit handling callbacks */
ecore_get_cam_offset_mac(struct ecore_vlan_mac_obj * o,int * offset)581d14abf15SRobert Mustacchi static BOOL ecore_get_cam_offset_mac(struct ecore_vlan_mac_obj *o, int *offset)
582d14abf15SRobert Mustacchi {
583d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *mp = o->macs_pool;
584d14abf15SRobert Mustacchi 
585d14abf15SRobert Mustacchi 	DbgBreakIf(!mp);
586d14abf15SRobert Mustacchi 
587d14abf15SRobert Mustacchi 	return mp->get_entry(mp, offset);
588d14abf15SRobert Mustacchi }
589d14abf15SRobert Mustacchi 
ecore_get_credit_mac(struct ecore_vlan_mac_obj * o)590d14abf15SRobert Mustacchi static BOOL ecore_get_credit_mac(struct ecore_vlan_mac_obj *o)
591d14abf15SRobert Mustacchi {
592d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *mp = o->macs_pool;
593d14abf15SRobert Mustacchi 
594d14abf15SRobert Mustacchi 	DbgBreakIf(!mp);
595d14abf15SRobert Mustacchi 
596d14abf15SRobert Mustacchi 	return mp->get(mp, 1);
597d14abf15SRobert Mustacchi }
598d14abf15SRobert Mustacchi 
ecore_get_cam_offset_vlan(struct ecore_vlan_mac_obj * o,int * offset)599d14abf15SRobert Mustacchi static BOOL ecore_get_cam_offset_vlan(struct ecore_vlan_mac_obj *o, int *offset)
600d14abf15SRobert Mustacchi {
601d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *vp = o->vlans_pool;
602d14abf15SRobert Mustacchi 
603d14abf15SRobert Mustacchi 	DbgBreakIf(!vp);
604d14abf15SRobert Mustacchi 
605d14abf15SRobert Mustacchi 	return vp->get_entry(vp, offset);
606d14abf15SRobert Mustacchi }
607d14abf15SRobert Mustacchi 
ecore_get_credit_vlan(struct ecore_vlan_mac_obj * o)608d14abf15SRobert Mustacchi static BOOL ecore_get_credit_vlan(struct ecore_vlan_mac_obj *o)
609d14abf15SRobert Mustacchi {
610d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *vp = o->vlans_pool;
611d14abf15SRobert Mustacchi 
612d14abf15SRobert Mustacchi 	DbgBreakIf(!vp);
613d14abf15SRobert Mustacchi 
614d14abf15SRobert Mustacchi 	return vp->get(vp, 1);
615d14abf15SRobert Mustacchi }
616d14abf15SRobert Mustacchi 
ecore_get_credit_vlan_mac(struct ecore_vlan_mac_obj * o)617d14abf15SRobert Mustacchi static BOOL ecore_get_credit_vlan_mac(struct ecore_vlan_mac_obj *o)
618d14abf15SRobert Mustacchi {
619d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *mp = o->macs_pool;
620d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *vp = o->vlans_pool;
621d14abf15SRobert Mustacchi 
622d14abf15SRobert Mustacchi 	if (!mp->get(mp, 1))
623d14abf15SRobert Mustacchi 		return FALSE;
624d14abf15SRobert Mustacchi 
625d14abf15SRobert Mustacchi 	if (!vp->get(vp, 1)) {
626d14abf15SRobert Mustacchi 		mp->put(mp, 1);
627d14abf15SRobert Mustacchi 		return FALSE;
628d14abf15SRobert Mustacchi 	}
629d14abf15SRobert Mustacchi 
630d14abf15SRobert Mustacchi 	return TRUE;
631d14abf15SRobert Mustacchi }
632d14abf15SRobert Mustacchi 
ecore_put_cam_offset_mac(struct ecore_vlan_mac_obj * o,int offset)633d14abf15SRobert Mustacchi static BOOL ecore_put_cam_offset_mac(struct ecore_vlan_mac_obj *o, int offset)
634d14abf15SRobert Mustacchi {
635d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *mp = o->macs_pool;
636d14abf15SRobert Mustacchi 
637d14abf15SRobert Mustacchi 	return mp->put_entry(mp, offset);
638d14abf15SRobert Mustacchi }
639d14abf15SRobert Mustacchi 
ecore_put_credit_mac(struct ecore_vlan_mac_obj * o)640d14abf15SRobert Mustacchi static BOOL ecore_put_credit_mac(struct ecore_vlan_mac_obj *o)
641d14abf15SRobert Mustacchi {
642d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *mp = o->macs_pool;
643d14abf15SRobert Mustacchi 
644d14abf15SRobert Mustacchi 	return mp->put(mp, 1);
645d14abf15SRobert Mustacchi }
646d14abf15SRobert Mustacchi 
ecore_put_cam_offset_vlan(struct ecore_vlan_mac_obj * o,int offset)647d14abf15SRobert Mustacchi static BOOL ecore_put_cam_offset_vlan(struct ecore_vlan_mac_obj *o, int offset)
648d14abf15SRobert Mustacchi {
649d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *vp = o->vlans_pool;
650d14abf15SRobert Mustacchi 
651d14abf15SRobert Mustacchi 	return vp->put_entry(vp, offset);
652d14abf15SRobert Mustacchi }
653d14abf15SRobert Mustacchi 
ecore_put_credit_vlan(struct ecore_vlan_mac_obj * o)654d14abf15SRobert Mustacchi static BOOL ecore_put_credit_vlan(struct ecore_vlan_mac_obj *o)
655d14abf15SRobert Mustacchi {
656d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *vp = o->vlans_pool;
657d14abf15SRobert Mustacchi 
658d14abf15SRobert Mustacchi 	return vp->put(vp, 1);
659d14abf15SRobert Mustacchi }
660d14abf15SRobert Mustacchi 
ecore_put_credit_vlan_mac(struct ecore_vlan_mac_obj * o)661d14abf15SRobert Mustacchi static BOOL ecore_put_credit_vlan_mac(struct ecore_vlan_mac_obj *o)
662d14abf15SRobert Mustacchi {
663d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *mp = o->macs_pool;
664d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *vp = o->vlans_pool;
665d14abf15SRobert Mustacchi 
666d14abf15SRobert Mustacchi 	if (!mp->put(mp, 1))
667d14abf15SRobert Mustacchi 		return FALSE;
668d14abf15SRobert Mustacchi 
669d14abf15SRobert Mustacchi 	if (!vp->put(vp, 1)) {
670d14abf15SRobert Mustacchi 		mp->get(mp, 1);
671d14abf15SRobert Mustacchi 		return FALSE;
672d14abf15SRobert Mustacchi 	}
673d14abf15SRobert Mustacchi 
674d14abf15SRobert Mustacchi 	return TRUE;
675d14abf15SRobert Mustacchi }
676d14abf15SRobert Mustacchi 
677d14abf15SRobert Mustacchi /**
678d14abf15SRobert Mustacchi  * __ecore_vlan_mac_h_write_trylock - try getting the writer lock on vlan mac
679d14abf15SRobert Mustacchi  * head list.
680d14abf15SRobert Mustacchi  *
681d14abf15SRobert Mustacchi  * @pdev:	device handle
682d14abf15SRobert Mustacchi  * @o:		vlan_mac object
683d14abf15SRobert Mustacchi  *
684d14abf15SRobert Mustacchi  * @details: Non-blocking implementation; should be called under execution
685d14abf15SRobert Mustacchi  *           queue lock.
686d14abf15SRobert Mustacchi  */
__ecore_vlan_mac_h_write_trylock(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o)687d14abf15SRobert Mustacchi static int __ecore_vlan_mac_h_write_trylock(struct _lm_device_t *pdev,
688d14abf15SRobert Mustacchi 					    struct ecore_vlan_mac_obj *o)
689d14abf15SRobert Mustacchi {
690d14abf15SRobert Mustacchi 	if (o->head_reader) {
691d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "vlan_mac_lock writer - There are readers; Busy\n");
692d14abf15SRobert Mustacchi 		return ECORE_BUSY;
693d14abf15SRobert Mustacchi 	}
694d14abf15SRobert Mustacchi 
695d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "vlan_mac_lock writer - Taken\n");
696d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
697d14abf15SRobert Mustacchi }
698d14abf15SRobert Mustacchi 
699d14abf15SRobert Mustacchi /**
700d14abf15SRobert Mustacchi  * __ecore_vlan_mac_h_exec_pending - execute step instead of a previous step
701d14abf15SRobert Mustacchi  * which wasn't able to run due to a taken lock on vlan mac head list.
702d14abf15SRobert Mustacchi  *
703d14abf15SRobert Mustacchi  * @pdev:	device handle
704d14abf15SRobert Mustacchi  * @o:		vlan_mac object
705d14abf15SRobert Mustacchi  *
706d14abf15SRobert Mustacchi  * @details Should be called under execution queue lock; notice it might release
707d14abf15SRobert Mustacchi  *          and reclaim it during its run.
708d14abf15SRobert Mustacchi  */
__ecore_vlan_mac_h_exec_pending(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o)709d14abf15SRobert Mustacchi static void __ecore_vlan_mac_h_exec_pending(struct _lm_device_t *pdev,
710d14abf15SRobert Mustacchi 					    struct ecore_vlan_mac_obj *o)
711d14abf15SRobert Mustacchi {
712d14abf15SRobert Mustacchi 	int rc;
713d14abf15SRobert Mustacchi 	unsigned long ramrod_flags = o->saved_ramrod_flags;
714d14abf15SRobert Mustacchi 
715d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "vlan_mac_lock execute pending command with ramrod flags %lu\n",
716d14abf15SRobert Mustacchi 		  ramrod_flags);
717d14abf15SRobert Mustacchi 	o->head_exe_request = FALSE;
718d14abf15SRobert Mustacchi 	o->saved_ramrod_flags = 0;
719d14abf15SRobert Mustacchi 	rc = ecore_exe_queue_step(pdev, &o->exe_queue, &ramrod_flags);
720d14abf15SRobert Mustacchi 	if (rc != ECORE_SUCCESS) {
721d14abf15SRobert Mustacchi 		ECORE_ERR("execution of pending commands failed with rc %d\n",
722d14abf15SRobert Mustacchi 			  rc);
723d14abf15SRobert Mustacchi #ifdef ECORE_STOP_ON_ERROR
724d14abf15SRobert Mustacchi 		ecore_panic();
725d14abf15SRobert Mustacchi #endif
726d14abf15SRobert Mustacchi 	}
727d14abf15SRobert Mustacchi }
728d14abf15SRobert Mustacchi 
729d14abf15SRobert Mustacchi /**
730d14abf15SRobert Mustacchi  * __ecore_vlan_mac_h_pend - Pend an execution step which couldn't have been
731d14abf15SRobert Mustacchi  * called due to vlan mac head list lock being taken.
732d14abf15SRobert Mustacchi  *
733d14abf15SRobert Mustacchi  * @pdev:		device handle
734d14abf15SRobert Mustacchi  * @o:			vlan_mac object
735d14abf15SRobert Mustacchi  * @ramrod_flags:	ramrod flags of missed execution
736d14abf15SRobert Mustacchi  *
737d14abf15SRobert Mustacchi  * @details Should be called under execution queue lock.
738d14abf15SRobert Mustacchi  */
__ecore_vlan_mac_h_pend(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,unsigned long ramrod_flags)739d14abf15SRobert Mustacchi static void __ecore_vlan_mac_h_pend(struct _lm_device_t *pdev,
740d14abf15SRobert Mustacchi 				    struct ecore_vlan_mac_obj *o,
741d14abf15SRobert Mustacchi 				    unsigned long ramrod_flags)
742d14abf15SRobert Mustacchi {
743d14abf15SRobert Mustacchi 	o->head_exe_request = TRUE;
744d14abf15SRobert Mustacchi 	o->saved_ramrod_flags = ramrod_flags;
745d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Placing pending execution with ramrod flags %lu\n",
746d14abf15SRobert Mustacchi 		  ramrod_flags);
747d14abf15SRobert Mustacchi }
748d14abf15SRobert Mustacchi 
749d14abf15SRobert Mustacchi /**
750d14abf15SRobert Mustacchi  * __ecore_vlan_mac_h_write_unlock - unlock the vlan mac head list writer lock
751d14abf15SRobert Mustacchi  *
752d14abf15SRobert Mustacchi  * @pdev:		device handle
753d14abf15SRobert Mustacchi  * @o:			vlan_mac object
754d14abf15SRobert Mustacchi  *
755d14abf15SRobert Mustacchi  * @details Should be called under execution queue lock. Notice if a pending
756d14abf15SRobert Mustacchi  *          execution exists, it would perform it - possibly releasing and
757d14abf15SRobert Mustacchi  *          reclaiming the execution queue lock.
758d14abf15SRobert Mustacchi  */
__ecore_vlan_mac_h_write_unlock(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o)759d14abf15SRobert Mustacchi static void __ecore_vlan_mac_h_write_unlock(struct _lm_device_t *pdev,
760d14abf15SRobert Mustacchi 					    struct ecore_vlan_mac_obj *o)
761d14abf15SRobert Mustacchi {
762d14abf15SRobert Mustacchi 	/* It's possible a new pending execution was added since this writer
763d14abf15SRobert Mustacchi 	 * executed. If so, execute again. [Ad infinitum]
764d14abf15SRobert Mustacchi 	 */
765d14abf15SRobert Mustacchi 	while(o->head_exe_request) {
766d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "vlan_mac_lock - writer release encountered a pending request\n");
767d14abf15SRobert Mustacchi 		__ecore_vlan_mac_h_exec_pending(pdev, o);
768d14abf15SRobert Mustacchi 	}
769d14abf15SRobert Mustacchi }
770d14abf15SRobert Mustacchi 
771d14abf15SRobert Mustacchi /**
772d14abf15SRobert Mustacchi  * ecore_vlan_mac_h_write_unlock - unlock the vlan mac head list writer lock
773d14abf15SRobert Mustacchi  *
774d14abf15SRobert Mustacchi  * @pdev:		device handle
775d14abf15SRobert Mustacchi  * @o:			vlan_mac object
776d14abf15SRobert Mustacchi  *
777d14abf15SRobert Mustacchi  * @details Notice if a pending execution exists, it would perform it -
778d14abf15SRobert Mustacchi  *          possibly releasing and reclaiming the execution queue lock.
779d14abf15SRobert Mustacchi  */
ecore_vlan_mac_h_write_unlock(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o)780d14abf15SRobert Mustacchi void ecore_vlan_mac_h_write_unlock(struct _lm_device_t *pdev,
781d14abf15SRobert Mustacchi 				   struct ecore_vlan_mac_obj *o)
782d14abf15SRobert Mustacchi {
783d14abf15SRobert Mustacchi 	ECORE_SPIN_LOCK_BH(&o->exe_queue.lock);
784d14abf15SRobert Mustacchi 	__ecore_vlan_mac_h_write_unlock(pdev, o);
785d14abf15SRobert Mustacchi 	ECORE_SPIN_UNLOCK_BH(&o->exe_queue.lock);
786d14abf15SRobert Mustacchi }
787d14abf15SRobert Mustacchi 
788d14abf15SRobert Mustacchi /**
789d14abf15SRobert Mustacchi  * __ecore_vlan_mac_h_read_lock - lock the vlan mac head list reader lock
790d14abf15SRobert Mustacchi  *
791d14abf15SRobert Mustacchi  * @pdev:		device handle
792d14abf15SRobert Mustacchi  * @o:			vlan_mac object
793d14abf15SRobert Mustacchi  *
794d14abf15SRobert Mustacchi  * @details Should be called under the execution queue lock. May sleep. May
795d14abf15SRobert Mustacchi  *          release and reclaim execution queue lock during its run.
796d14abf15SRobert Mustacchi  */
__ecore_vlan_mac_h_read_lock(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o)797d14abf15SRobert Mustacchi static int __ecore_vlan_mac_h_read_lock(struct _lm_device_t *pdev,
798d14abf15SRobert Mustacchi 					struct ecore_vlan_mac_obj *o)
799d14abf15SRobert Mustacchi {
800d14abf15SRobert Mustacchi 	/* If we got here, we're holding lock --> no WRITER exists */
801d14abf15SRobert Mustacchi 	o->head_reader++;
802d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "vlan_mac_lock - locked reader - number %d\n",
803d14abf15SRobert Mustacchi 		  o->head_reader);
804d14abf15SRobert Mustacchi 
805d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
806d14abf15SRobert Mustacchi }
807d14abf15SRobert Mustacchi 
808d14abf15SRobert Mustacchi /**
809d14abf15SRobert Mustacchi  * ecore_vlan_mac_h_read_lock - lock the vlan mac head list reader lock
810d14abf15SRobert Mustacchi  *
811d14abf15SRobert Mustacchi  * @pdev:		device handle
812d14abf15SRobert Mustacchi  * @o:			vlan_mac object
813d14abf15SRobert Mustacchi  *
814d14abf15SRobert Mustacchi  * @details May sleep. Claims and releases execution queue lock during its run.
815d14abf15SRobert Mustacchi  */
ecore_vlan_mac_h_read_lock(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o)816d14abf15SRobert Mustacchi int ecore_vlan_mac_h_read_lock(struct _lm_device_t *pdev,
817d14abf15SRobert Mustacchi 			       struct ecore_vlan_mac_obj *o)
818d14abf15SRobert Mustacchi {
819d14abf15SRobert Mustacchi 	int rc;
820d14abf15SRobert Mustacchi 
821d14abf15SRobert Mustacchi 	ECORE_SPIN_LOCK_BH(&o->exe_queue.lock);
822d14abf15SRobert Mustacchi 	rc = __ecore_vlan_mac_h_read_lock(pdev, o);
823d14abf15SRobert Mustacchi 	ECORE_SPIN_UNLOCK_BH(&o->exe_queue.lock);
824d14abf15SRobert Mustacchi 
825d14abf15SRobert Mustacchi 	return rc;
826d14abf15SRobert Mustacchi }
827d14abf15SRobert Mustacchi 
828d14abf15SRobert Mustacchi /**
829d14abf15SRobert Mustacchi  * __ecore_vlan_mac_h_read_unlock - unlock the vlan mac head list reader lock
830d14abf15SRobert Mustacchi  *
831d14abf15SRobert Mustacchi  * @pdev:		device handle
832d14abf15SRobert Mustacchi  * @o:			vlan_mac object
833d14abf15SRobert Mustacchi  *
834d14abf15SRobert Mustacchi  * @details Should be called under execution queue lock. Notice if a pending
835d14abf15SRobert Mustacchi  *          execution exists, it would be performed if this was the last
836d14abf15SRobert Mustacchi  *          reader. possibly releasing and reclaiming the execution queue lock.
837d14abf15SRobert Mustacchi  */
__ecore_vlan_mac_h_read_unlock(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o)838d14abf15SRobert Mustacchi static void __ecore_vlan_mac_h_read_unlock(struct _lm_device_t *pdev,
839d14abf15SRobert Mustacchi 					  struct ecore_vlan_mac_obj *o)
840d14abf15SRobert Mustacchi {
841d14abf15SRobert Mustacchi 	if (!o->head_reader) {
842d14abf15SRobert Mustacchi 		ECORE_ERR("Need to release vlan mac reader lock, but lock isn't taken\n");
843d14abf15SRobert Mustacchi #ifdef ECORE_STOP_ON_ERROR
844d14abf15SRobert Mustacchi 		ecore_panic();
845d14abf15SRobert Mustacchi #endif
846d14abf15SRobert Mustacchi 	} else {
847d14abf15SRobert Mustacchi 		o->head_reader--;
848d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "vlan_mac_lock - decreased readers to %d\n",
849d14abf15SRobert Mustacchi 			  o->head_reader);
850d14abf15SRobert Mustacchi 	}
851d14abf15SRobert Mustacchi 
852d14abf15SRobert Mustacchi 	/* It's possible a new pending execution was added, and that this reader
853d14abf15SRobert Mustacchi 	 * was last - if so we need to execute the command.
854d14abf15SRobert Mustacchi 	 */
855d14abf15SRobert Mustacchi 	if (!o->head_reader && o->head_exe_request) {
856d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "vlan_mac_lock - reader release encountered a pending request\n");
857d14abf15SRobert Mustacchi 
858d14abf15SRobert Mustacchi 		/* Writer release will do the trick */
859d14abf15SRobert Mustacchi 		__ecore_vlan_mac_h_write_unlock(pdev, o);
860d14abf15SRobert Mustacchi 	}
861d14abf15SRobert Mustacchi }
862d14abf15SRobert Mustacchi 
863d14abf15SRobert Mustacchi /**
864d14abf15SRobert Mustacchi  * ecore_vlan_mac_h_read_unlock - unlock the vlan mac head list reader lock
865d14abf15SRobert Mustacchi  *
866d14abf15SRobert Mustacchi  * @pdev:		device handle
867d14abf15SRobert Mustacchi  * @o:			vlan_mac object
868d14abf15SRobert Mustacchi  *
869d14abf15SRobert Mustacchi  * @details Notice if a pending execution exists, it would be performed if this
870d14abf15SRobert Mustacchi  *          was the last reader. Claims and releases the execution queue lock
871d14abf15SRobert Mustacchi  *          during its run.
872d14abf15SRobert Mustacchi  */
ecore_vlan_mac_h_read_unlock(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o)873d14abf15SRobert Mustacchi void ecore_vlan_mac_h_read_unlock(struct _lm_device_t *pdev,
874d14abf15SRobert Mustacchi 				  struct ecore_vlan_mac_obj *o)
875d14abf15SRobert Mustacchi {
876d14abf15SRobert Mustacchi 	ECORE_SPIN_LOCK_BH(&o->exe_queue.lock);
877d14abf15SRobert Mustacchi 	__ecore_vlan_mac_h_read_unlock(pdev, o);
878d14abf15SRobert Mustacchi 	ECORE_SPIN_UNLOCK_BH(&o->exe_queue.lock);
879d14abf15SRobert Mustacchi }
880d14abf15SRobert Mustacchi 
881d14abf15SRobert Mustacchi /**
882d14abf15SRobert Mustacchi  * ecore_vlan_mac_h_read_unlock - unlock the vlan mac head list reader lock
883d14abf15SRobert Mustacchi  *
884d14abf15SRobert Mustacchi  * @pdev:		device handle
885d14abf15SRobert Mustacchi  * @o:			vlan_mac object
886d14abf15SRobert Mustacchi  * @n:			number of elements to get
887d14abf15SRobert Mustacchi  * @base:		base address for element placement
888d14abf15SRobert Mustacchi  * @stride:		stride between elements (in bytes)
889d14abf15SRobert Mustacchi  */
ecore_get_n_elements(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,int n,u8 * base,u8 stride,u8 size)890d14abf15SRobert Mustacchi static int ecore_get_n_elements(struct _lm_device_t *pdev, struct ecore_vlan_mac_obj *o,
891d14abf15SRobert Mustacchi 				 int n, u8 *base, u8 stride, u8 size)
892d14abf15SRobert Mustacchi {
893d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem *pos;
894d14abf15SRobert Mustacchi 	u8 *next = base;
895d14abf15SRobert Mustacchi 	int counter = 0;
896d14abf15SRobert Mustacchi 	int read_lock;
897d14abf15SRobert Mustacchi 
898d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "get_n_elements - taking vlan_mac_lock (reader)\n");
899d14abf15SRobert Mustacchi 	read_lock = ecore_vlan_mac_h_read_lock(pdev, o);
900d14abf15SRobert Mustacchi 	if (read_lock != ECORE_SUCCESS)
901d14abf15SRobert Mustacchi 		ECORE_ERR("get_n_elements failed to get vlan mac reader lock; Access without lock\n");
902d14abf15SRobert Mustacchi 
903d14abf15SRobert Mustacchi 	/* traverse list */
904d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(pos, &o->head, link,
905d14abf15SRobert Mustacchi 				  struct ecore_vlan_mac_registry_elem) {
906d14abf15SRobert Mustacchi 		if (counter < n) {
907d14abf15SRobert Mustacchi 			mm_memcpy(next, &pos->u, size);
908d14abf15SRobert Mustacchi 			counter++;
909d14abf15SRobert Mustacchi 			ECORE_MSG(pdev, "copied element number %d to address %p element was:\n",
910d14abf15SRobert Mustacchi 				  counter, next);
911d14abf15SRobert Mustacchi 			next += stride + size;
912d14abf15SRobert Mustacchi 		}
913d14abf15SRobert Mustacchi 	}
914d14abf15SRobert Mustacchi 
915d14abf15SRobert Mustacchi 	if (read_lock == ECORE_SUCCESS) {
916d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "get_n_elements - releasing vlan_mac_lock (reader)\n");
917d14abf15SRobert Mustacchi 		ecore_vlan_mac_h_read_unlock(pdev, o);
918d14abf15SRobert Mustacchi 	}
919d14abf15SRobert Mustacchi 
920d14abf15SRobert Mustacchi 	return counter * ETH_ALEN;
921d14abf15SRobert Mustacchi }
922d14abf15SRobert Mustacchi 
923d14abf15SRobert Mustacchi /* check_add() callbacks */
ecore_check_mac_add(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,union ecore_classification_ramrod_data * data)924d14abf15SRobert Mustacchi static int ecore_check_mac_add(struct _lm_device_t *pdev,
925d14abf15SRobert Mustacchi 			       struct ecore_vlan_mac_obj *o,
926d14abf15SRobert Mustacchi 			       union ecore_classification_ramrod_data *data)
927d14abf15SRobert Mustacchi {
928d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem *pos;
929d14abf15SRobert Mustacchi 
930d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Checking MAC %02x:%02x:%02x:%02x:%02x:%02x for ADD command\n", data->mac.mac[0], data->mac.mac[1], data->mac.mac[2], data->mac.mac[3], data->mac.mac[4], data->mac.mac[5]);
931d14abf15SRobert Mustacchi 
932d14abf15SRobert Mustacchi 	if (!ECORE_IS_VALID_ETHER_ADDR(data->mac.mac))
933d14abf15SRobert Mustacchi 		return ECORE_INVAL;
934d14abf15SRobert Mustacchi 
935d14abf15SRobert Mustacchi 	/* Check if a requested MAC already exists */
936d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(pos, &o->head, link,
937d14abf15SRobert Mustacchi 				  struct ecore_vlan_mac_registry_elem)
938d14abf15SRobert Mustacchi 		if (mm_memcmp(data->mac.mac, pos->u.mac.mac, ETH_ALEN) &&
939d14abf15SRobert Mustacchi 		    (data->mac.is_inner_mac == pos->u.mac.is_inner_mac))
940d14abf15SRobert Mustacchi 			return ECORE_EXISTS;
941d14abf15SRobert Mustacchi 
942d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
943d14abf15SRobert Mustacchi }
944d14abf15SRobert Mustacchi 
ecore_check_vlan_add(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,union ecore_classification_ramrod_data * data)945d14abf15SRobert Mustacchi static int ecore_check_vlan_add(struct _lm_device_t *pdev,
946d14abf15SRobert Mustacchi 				struct ecore_vlan_mac_obj *o,
947d14abf15SRobert Mustacchi 				union ecore_classification_ramrod_data *data)
948d14abf15SRobert Mustacchi {
949d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem *pos;
950d14abf15SRobert Mustacchi 
951d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Checking VLAN %d for ADD command\n", data->vlan.vlan);
952d14abf15SRobert Mustacchi 
953d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(pos, &o->head, link,
954d14abf15SRobert Mustacchi 				  struct ecore_vlan_mac_registry_elem)
955d14abf15SRobert Mustacchi 		if (data->vlan.vlan == pos->u.vlan.vlan)
956d14abf15SRobert Mustacchi 			return ECORE_EXISTS;
957d14abf15SRobert Mustacchi 
958d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
959d14abf15SRobert Mustacchi }
960d14abf15SRobert Mustacchi 
ecore_check_vlan_mac_add(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,union ecore_classification_ramrod_data * data)961d14abf15SRobert Mustacchi static int ecore_check_vlan_mac_add(struct _lm_device_t *pdev,
962d14abf15SRobert Mustacchi 				    struct ecore_vlan_mac_obj *o,
963d14abf15SRobert Mustacchi 				   union ecore_classification_ramrod_data *data)
964d14abf15SRobert Mustacchi {
965d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem *pos;
966d14abf15SRobert Mustacchi 
967d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Checking VLAN_MAC (%02x:%02x:%02x:%02x:%02x:%02x, %d) for ADD command\n",
968d14abf15SRobert Mustacchi 		  data->vlan_mac.mac[0], data->vlan_mac.mac[1], data->vlan_mac.mac[2], data->vlan_mac.mac[3], data->vlan_mac.mac[4], data->vlan_mac.mac[5], data->vlan_mac.vlan);
969d14abf15SRobert Mustacchi 
970d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(pos, &o->head, link,
971d14abf15SRobert Mustacchi 				  struct ecore_vlan_mac_registry_elem)
972d14abf15SRobert Mustacchi 		if ((data->vlan_mac.vlan == pos->u.vlan_mac.vlan) &&
973d14abf15SRobert Mustacchi 		    (mm_memcmp(data->vlan_mac.mac, pos->u.vlan_mac.mac,
974d14abf15SRobert Mustacchi 				  ETH_ALEN)) &&
975d14abf15SRobert Mustacchi 		    (data->vlan_mac.is_inner_mac ==
976d14abf15SRobert Mustacchi 		     pos->u.vlan_mac.is_inner_mac))
977d14abf15SRobert Mustacchi 			return ECORE_EXISTS;
978d14abf15SRobert Mustacchi 
979d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
980d14abf15SRobert Mustacchi }
981d14abf15SRobert Mustacchi 
982d14abf15SRobert Mustacchi /* check_del() callbacks */
983d14abf15SRobert Mustacchi static struct ecore_vlan_mac_registry_elem *
ecore_check_mac_del(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,union ecore_classification_ramrod_data * data)984d14abf15SRobert Mustacchi 	ecore_check_mac_del(struct _lm_device_t *pdev,
985d14abf15SRobert Mustacchi 			    struct ecore_vlan_mac_obj *o,
986d14abf15SRobert Mustacchi 			    union ecore_classification_ramrod_data *data)
987d14abf15SRobert Mustacchi {
988d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem *pos;
989d14abf15SRobert Mustacchi 
990d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Checking MAC %02x:%02x:%02x:%02x:%02x:%02x for DEL command\n", data->mac.mac[0], data->mac.mac[1], data->mac.mac[2], data->mac.mac[3], data->mac.mac[4], data->mac.mac[5]);
991d14abf15SRobert Mustacchi 
992d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(pos, &o->head, link,
993d14abf15SRobert Mustacchi 				  struct ecore_vlan_mac_registry_elem)
994d14abf15SRobert Mustacchi 		if ((mm_memcmp(data->mac.mac, pos->u.mac.mac, ETH_ALEN)) &&
995d14abf15SRobert Mustacchi 		    (data->mac.is_inner_mac == pos->u.mac.is_inner_mac))
996d14abf15SRobert Mustacchi 			return pos;
997d14abf15SRobert Mustacchi 
998d14abf15SRobert Mustacchi 	return NULL;
999d14abf15SRobert Mustacchi }
1000d14abf15SRobert Mustacchi 
1001d14abf15SRobert Mustacchi static struct ecore_vlan_mac_registry_elem *
ecore_check_vlan_del(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,union ecore_classification_ramrod_data * data)1002d14abf15SRobert Mustacchi 	ecore_check_vlan_del(struct _lm_device_t *pdev,
1003d14abf15SRobert Mustacchi 			     struct ecore_vlan_mac_obj *o,
1004d14abf15SRobert Mustacchi 			     union ecore_classification_ramrod_data *data)
1005d14abf15SRobert Mustacchi {
1006d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem *pos;
1007d14abf15SRobert Mustacchi 
1008d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Checking VLAN %d for DEL command\n", data->vlan.vlan);
1009d14abf15SRobert Mustacchi 
1010d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(pos, &o->head, link,
1011d14abf15SRobert Mustacchi 				  struct ecore_vlan_mac_registry_elem)
1012d14abf15SRobert Mustacchi 		if (data->vlan.vlan == pos->u.vlan.vlan)
1013d14abf15SRobert Mustacchi 			return pos;
1014d14abf15SRobert Mustacchi 
1015d14abf15SRobert Mustacchi 	return NULL;
1016d14abf15SRobert Mustacchi }
1017d14abf15SRobert Mustacchi 
1018d14abf15SRobert Mustacchi static struct ecore_vlan_mac_registry_elem *
ecore_check_vlan_mac_del(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,union ecore_classification_ramrod_data * data)1019d14abf15SRobert Mustacchi 	ecore_check_vlan_mac_del(struct _lm_device_t *pdev,
1020d14abf15SRobert Mustacchi 				 struct ecore_vlan_mac_obj *o,
1021d14abf15SRobert Mustacchi 				 union ecore_classification_ramrod_data *data)
1022d14abf15SRobert Mustacchi {
1023d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem *pos;
1024d14abf15SRobert Mustacchi 
1025d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Checking VLAN_MAC (%02x:%02x:%02x:%02x:%02x:%02x, %d) for DEL command\n",
1026d14abf15SRobert Mustacchi 		  data->vlan_mac.mac[0], data->vlan_mac.mac[1], data->vlan_mac.mac[2], data->vlan_mac.mac[3], data->vlan_mac.mac[4], data->vlan_mac.mac[5], data->vlan_mac.vlan);
1027d14abf15SRobert Mustacchi 
1028d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(pos, &o->head, link,
1029d14abf15SRobert Mustacchi 				  struct ecore_vlan_mac_registry_elem)
1030d14abf15SRobert Mustacchi 		if ((data->vlan_mac.vlan == pos->u.vlan_mac.vlan) &&
1031d14abf15SRobert Mustacchi 		    (mm_memcmp(data->vlan_mac.mac, pos->u.vlan_mac.mac,
1032d14abf15SRobert Mustacchi 			     ETH_ALEN)) &&
1033d14abf15SRobert Mustacchi 		    (data->vlan_mac.is_inner_mac ==
1034d14abf15SRobert Mustacchi 		     pos->u.vlan_mac.is_inner_mac))
1035d14abf15SRobert Mustacchi 			return pos;
1036d14abf15SRobert Mustacchi 
1037d14abf15SRobert Mustacchi 	return NULL;
1038d14abf15SRobert Mustacchi }
1039d14abf15SRobert Mustacchi 
1040d14abf15SRobert Mustacchi /* check_move() callback */
ecore_check_move(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * src_o,struct ecore_vlan_mac_obj * dst_o,union ecore_classification_ramrod_data * data)1041d14abf15SRobert Mustacchi static BOOL ecore_check_move(struct _lm_device_t *pdev,
1042d14abf15SRobert Mustacchi 			     struct ecore_vlan_mac_obj *src_o,
1043d14abf15SRobert Mustacchi 			     struct ecore_vlan_mac_obj *dst_o,
1044d14abf15SRobert Mustacchi 			     union ecore_classification_ramrod_data *data)
1045d14abf15SRobert Mustacchi {
1046d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem *pos;
1047d14abf15SRobert Mustacchi 	int rc;
1048d14abf15SRobert Mustacchi 
1049d14abf15SRobert Mustacchi 	/* Check if we can delete the requested configuration from the first
1050d14abf15SRobert Mustacchi 	 * object.
1051d14abf15SRobert Mustacchi 	 */
1052d14abf15SRobert Mustacchi 	pos = src_o->check_del(pdev, src_o, data);
1053d14abf15SRobert Mustacchi 
1054d14abf15SRobert Mustacchi 	/*  check if configuration can be added */
1055d14abf15SRobert Mustacchi 	rc = dst_o->check_add(pdev, dst_o, data);
1056d14abf15SRobert Mustacchi 
1057d14abf15SRobert Mustacchi 	/* If this classification can not be added (is already set)
1058d14abf15SRobert Mustacchi 	 * or can't be deleted - return an error.
1059d14abf15SRobert Mustacchi 	 */
1060d14abf15SRobert Mustacchi 	if (rc || !pos)
1061d14abf15SRobert Mustacchi 		return FALSE;
1062d14abf15SRobert Mustacchi 
1063d14abf15SRobert Mustacchi 	return TRUE;
1064d14abf15SRobert Mustacchi }
1065d14abf15SRobert Mustacchi 
ecore_check_move_always_err(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * src_o,struct ecore_vlan_mac_obj * dst_o,union ecore_classification_ramrod_data * data)1066d14abf15SRobert Mustacchi static BOOL ecore_check_move_always_err(
1067d14abf15SRobert Mustacchi 	struct _lm_device_t *pdev,
1068d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *src_o,
1069d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *dst_o,
1070d14abf15SRobert Mustacchi 	union ecore_classification_ramrod_data *data)
1071d14abf15SRobert Mustacchi {
1072d14abf15SRobert Mustacchi 	return FALSE;
1073d14abf15SRobert Mustacchi }
1074d14abf15SRobert Mustacchi 
ecore_vlan_mac_get_rx_tx_flag(struct ecore_vlan_mac_obj * o)1075d14abf15SRobert Mustacchi static INLINE u8 ecore_vlan_mac_get_rx_tx_flag(struct ecore_vlan_mac_obj *o)
1076d14abf15SRobert Mustacchi {
1077d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &o->raw;
1078d14abf15SRobert Mustacchi 	u8 rx_tx_flag = 0;
1079d14abf15SRobert Mustacchi 
1080d14abf15SRobert Mustacchi 	if ((raw->obj_type == ECORE_OBJ_TYPE_TX) ||
1081d14abf15SRobert Mustacchi 	    (raw->obj_type == ECORE_OBJ_TYPE_RX_TX))
1082d14abf15SRobert Mustacchi 		rx_tx_flag |= ETH_CLASSIFY_CMD_HEADER_TX_CMD;
1083d14abf15SRobert Mustacchi 
1084d14abf15SRobert Mustacchi 	if ((raw->obj_type == ECORE_OBJ_TYPE_RX) ||
1085d14abf15SRobert Mustacchi 	    (raw->obj_type == ECORE_OBJ_TYPE_RX_TX))
1086d14abf15SRobert Mustacchi 		rx_tx_flag |= ETH_CLASSIFY_CMD_HEADER_RX_CMD;
1087d14abf15SRobert Mustacchi 
1088d14abf15SRobert Mustacchi 	return rx_tx_flag;
1089d14abf15SRobert Mustacchi }
1090d14abf15SRobert Mustacchi 
ecore_set_mac_in_nig(struct _lm_device_t * pdev,BOOL add,unsigned char * dev_addr,int index)1091d14abf15SRobert Mustacchi void ecore_set_mac_in_nig(struct _lm_device_t *pdev,
1092d14abf15SRobert Mustacchi 			  BOOL add, unsigned char *dev_addr, int index)
1093d14abf15SRobert Mustacchi {
1094d14abf15SRobert Mustacchi 	u32 wb_data[2];
1095d14abf15SRobert Mustacchi 	u32 reg_offset = PORT_ID(pdev) ? NIG_REG_LLH1_FUNC_MEM :
1096d14abf15SRobert Mustacchi 			 NIG_REG_LLH0_FUNC_MEM;
1097d14abf15SRobert Mustacchi 
1098d14abf15SRobert Mustacchi 	if (!IS_MF_SI_MODE(pdev) && !IS_MF_AFEX(pdev))
1099d14abf15SRobert Mustacchi 		return;
1100d14abf15SRobert Mustacchi 
1101d14abf15SRobert Mustacchi 	if (index > ECORE_LLH_CAM_MAX_PF_LINE)
1102d14abf15SRobert Mustacchi 		return;
1103d14abf15SRobert Mustacchi 
1104d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Going to %s LLH configuration at entry %d\n",
1105d14abf15SRobert Mustacchi 		  (add ? "ADD" : "DELETE"), index);
1106d14abf15SRobert Mustacchi 
1107d14abf15SRobert Mustacchi 	if (add) {
1108d14abf15SRobert Mustacchi 		/* LLH_FUNC_MEM is a u64 WB register */
1109d14abf15SRobert Mustacchi 		reg_offset += 8*index;
1110d14abf15SRobert Mustacchi 
1111d14abf15SRobert Mustacchi 		wb_data[0] = ((dev_addr[2] << 24) | (dev_addr[3] << 16) |
1112d14abf15SRobert Mustacchi 			      (dev_addr[4] <<  8) |  dev_addr[5]);
1113d14abf15SRobert Mustacchi 		wb_data[1] = ((dev_addr[0] <<  8) |  dev_addr[1]);
1114d14abf15SRobert Mustacchi 
1115d14abf15SRobert Mustacchi 		REG_WR_DMAE_LEN(pdev, reg_offset, wb_data, 2);
1116d14abf15SRobert Mustacchi 	}
1117d14abf15SRobert Mustacchi 
1118d14abf15SRobert Mustacchi 	REG_WR(pdev, (PORT_ID(pdev) ? NIG_REG_LLH1_FUNC_MEM_ENABLE :
1119d14abf15SRobert Mustacchi 				  NIG_REG_LLH0_FUNC_MEM_ENABLE) + 4*index, add);
1120d14abf15SRobert Mustacchi }
1121d14abf15SRobert Mustacchi 
1122d14abf15SRobert Mustacchi /**
1123d14abf15SRobert Mustacchi  * ecore_vlan_mac_set_cmd_hdr_e2 - set a header in a single classify ramrod
1124d14abf15SRobert Mustacchi  *
1125d14abf15SRobert Mustacchi  * @pdev:	device handle
1126d14abf15SRobert Mustacchi  * @o:		queue for which we want to configure this rule
1127d14abf15SRobert Mustacchi  * @add:	if TRUE the command is an ADD command, DEL otherwise
1128d14abf15SRobert Mustacchi  * @opcode:	CLASSIFY_RULE_OPCODE_XXX
1129d14abf15SRobert Mustacchi  * @hdr:	pointer to a header to setup
1130d14abf15SRobert Mustacchi  *
1131d14abf15SRobert Mustacchi  */
ecore_vlan_mac_set_cmd_hdr_e2(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,BOOL add,int opcode,struct eth_classify_cmd_header * hdr)1132d14abf15SRobert Mustacchi static INLINE void ecore_vlan_mac_set_cmd_hdr_e2(struct _lm_device_t *pdev,
1133d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *o, BOOL add, int opcode,
1134d14abf15SRobert Mustacchi 	struct eth_classify_cmd_header *hdr)
1135d14abf15SRobert Mustacchi {
1136d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &o->raw;
1137d14abf15SRobert Mustacchi 
1138d14abf15SRobert Mustacchi 	hdr->client_id = raw->cl_id;
1139d14abf15SRobert Mustacchi 	hdr->func_id = raw->func_id;
1140d14abf15SRobert Mustacchi 
1141d14abf15SRobert Mustacchi 	/* Rx or/and Tx (internal switching) configuration ? */
1142d14abf15SRobert Mustacchi 	hdr->cmd_general_data |=
1143d14abf15SRobert Mustacchi 		ecore_vlan_mac_get_rx_tx_flag(o);
1144d14abf15SRobert Mustacchi 
1145d14abf15SRobert Mustacchi 	if (add)
1146d14abf15SRobert Mustacchi 		hdr->cmd_general_data |= ETH_CLASSIFY_CMD_HEADER_IS_ADD;
1147d14abf15SRobert Mustacchi 
1148d14abf15SRobert Mustacchi 	hdr->cmd_general_data |=
1149d14abf15SRobert Mustacchi 		(opcode << ETH_CLASSIFY_CMD_HEADER_OPCODE_SHIFT);
1150d14abf15SRobert Mustacchi }
1151d14abf15SRobert Mustacchi 
1152d14abf15SRobert Mustacchi /**
1153d14abf15SRobert Mustacchi  * ecore_vlan_mac_set_rdata_hdr_e2 - set the classify ramrod data header
1154d14abf15SRobert Mustacchi  *
1155d14abf15SRobert Mustacchi  * @cid:	connection id
1156d14abf15SRobert Mustacchi  * @type:	ECORE_FILTER_XXX_PENDING
1157d14abf15SRobert Mustacchi  * @hdr:	pointer to header to setup
1158d14abf15SRobert Mustacchi  * @rule_cnt:
1159d14abf15SRobert Mustacchi  *
1160d14abf15SRobert Mustacchi  * currently we always configure one rule and echo field to contain a CID and an
1161d14abf15SRobert Mustacchi  * opcode type.
1162d14abf15SRobert Mustacchi  */
ecore_vlan_mac_set_rdata_hdr_e2(u32 cid,int type,struct eth_classify_header * hdr,int rule_cnt)1163d14abf15SRobert Mustacchi static INLINE void ecore_vlan_mac_set_rdata_hdr_e2(u32 cid, int type,
1164d14abf15SRobert Mustacchi 				struct eth_classify_header *hdr, int rule_cnt)
1165d14abf15SRobert Mustacchi {
1166d14abf15SRobert Mustacchi 	hdr->echo = mm_cpu_to_le32((cid & ECORE_SWCID_MASK) |
1167d14abf15SRobert Mustacchi 				(type << ECORE_SWCID_SHIFT));
1168d14abf15SRobert Mustacchi 	hdr->rule_cnt = (u8)rule_cnt;
1169d14abf15SRobert Mustacchi }
1170d14abf15SRobert Mustacchi 
1171d14abf15SRobert Mustacchi /* hw_config() callbacks */
ecore_set_one_mac_e2(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,struct ecore_exeq_elem * elem,int rule_idx,int cam_offset)1172d14abf15SRobert Mustacchi static void ecore_set_one_mac_e2(struct _lm_device_t *pdev,
1173d14abf15SRobert Mustacchi 				 struct ecore_vlan_mac_obj *o,
1174d14abf15SRobert Mustacchi 				 struct ecore_exeq_elem *elem, int rule_idx,
1175d14abf15SRobert Mustacchi 				 int cam_offset)
1176d14abf15SRobert Mustacchi {
1177d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &o->raw;
1178d14abf15SRobert Mustacchi 	struct eth_classify_rules_ramrod_data *data =
1179d14abf15SRobert Mustacchi 		(struct eth_classify_rules_ramrod_data *)(raw->rdata);
1180d14abf15SRobert Mustacchi 	int rule_cnt = rule_idx + 1, cmd = elem->cmd_data.vlan_mac.cmd;
1181d14abf15SRobert Mustacchi 	union eth_classify_rule_cmd *rule_entry = &data->rules[rule_idx];
1182d14abf15SRobert Mustacchi 	BOOL add = (cmd == ECORE_VLAN_MAC_ADD) ? TRUE : FALSE;
1183d14abf15SRobert Mustacchi 	unsigned long *vlan_mac_flags = &elem->cmd_data.vlan_mac.vlan_mac_flags;
1184d14abf15SRobert Mustacchi 	u8 *mac = elem->cmd_data.vlan_mac.u.mac.mac;
1185d14abf15SRobert Mustacchi 
1186d14abf15SRobert Mustacchi 	/* Set LLH CAM entry: currently only iSCSI and ETH macs are
1187d14abf15SRobert Mustacchi 	 * relevant. In addition, current implementation is tuned for a
1188d14abf15SRobert Mustacchi 	 * single ETH MAC.
1189d14abf15SRobert Mustacchi 	 *
1190d14abf15SRobert Mustacchi 	 * When multiple unicast ETH MACs PF configuration in switch
1191d14abf15SRobert Mustacchi 	 * independent mode is required (NetQ, multiple netdev MACs,
1192d14abf15SRobert Mustacchi 	 * etc.), consider better utilisation of 8 per function MAC
1193d14abf15SRobert Mustacchi 	 * entries in the LLH register. There is also
1194d14abf15SRobert Mustacchi 	 * NIG_REG_P[01]_LLH_FUNC_MEM2 registers that complete the
1195d14abf15SRobert Mustacchi 	 * total number of CAM entries to 16.
1196d14abf15SRobert Mustacchi 	 *
1197d14abf15SRobert Mustacchi 	 * Currently we won't configure NIG for MACs other than a primary ETH
1198d14abf15SRobert Mustacchi 	 * MAC and iSCSI L2 MAC.
1199d14abf15SRobert Mustacchi 	 *
1200d14abf15SRobert Mustacchi 	 * If this MAC is moving from one Queue to another, no need to change
1201d14abf15SRobert Mustacchi 	 * NIG configuration.
1202d14abf15SRobert Mustacchi 	 */
1203d14abf15SRobert Mustacchi 	if (cmd != ECORE_VLAN_MAC_MOVE) {
1204d14abf15SRobert Mustacchi 		if (ECORE_TEST_BIT(ECORE_ISCSI_ETH_MAC, vlan_mac_flags))
1205d14abf15SRobert Mustacchi 			ecore_set_mac_in_nig(pdev, add, mac,
1206d14abf15SRobert Mustacchi 					     ECORE_LLH_CAM_ISCSI_ETH_LINE);
1207d14abf15SRobert Mustacchi 		else if (ECORE_TEST_BIT(ECORE_ETH_MAC, vlan_mac_flags))
1208d14abf15SRobert Mustacchi 			ecore_set_mac_in_nig(pdev, add, mac,
1209d14abf15SRobert Mustacchi 					     ECORE_LLH_CAM_ETH_LINE);
1210d14abf15SRobert Mustacchi 	}
1211d14abf15SRobert Mustacchi 
1212d14abf15SRobert Mustacchi 	/* Reset the ramrod data buffer for the first rule */
1213d14abf15SRobert Mustacchi 	if (rule_idx == 0)
1214d14abf15SRobert Mustacchi 		mm_memset(data, 0, sizeof(*data));
1215d14abf15SRobert Mustacchi 
1216d14abf15SRobert Mustacchi 	/* Setup a command header */
1217d14abf15SRobert Mustacchi 	ecore_vlan_mac_set_cmd_hdr_e2(pdev, o, add, CLASSIFY_RULE_OPCODE_MAC,
1218d14abf15SRobert Mustacchi 				      &rule_entry->mac.header);
1219d14abf15SRobert Mustacchi 
1220d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "About to %s MAC %02x:%02x:%02x:%02x:%02x:%02x for Queue %d\n",
1221d14abf15SRobert Mustacchi 		  (add ? "add" : "delete"), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], raw->cl_id);
1222d14abf15SRobert Mustacchi 
1223d14abf15SRobert Mustacchi 	/* Set a MAC itself */
1224d14abf15SRobert Mustacchi 	ecore_set_fw_mac_addr(&rule_entry->mac.mac_msb,
1225d14abf15SRobert Mustacchi 			      &rule_entry->mac.mac_mid,
1226d14abf15SRobert Mustacchi 			      &rule_entry->mac.mac_lsb, mac);
1227d14abf15SRobert Mustacchi 	rule_entry->mac.inner_mac =
1228d14abf15SRobert Mustacchi 		mm_cpu_to_le16(elem->cmd_data.vlan_mac.u.mac.is_inner_mac);
1229d14abf15SRobert Mustacchi 
1230d14abf15SRobert Mustacchi 	/* MOVE: Add a rule that will add this MAC to the target Queue */
1231d14abf15SRobert Mustacchi 	if (cmd == ECORE_VLAN_MAC_MOVE) {
1232d14abf15SRobert Mustacchi 		rule_entry++;
1233d14abf15SRobert Mustacchi 		rule_cnt++;
1234d14abf15SRobert Mustacchi 
1235d14abf15SRobert Mustacchi 		/* Setup ramrod data */
1236d14abf15SRobert Mustacchi 		ecore_vlan_mac_set_cmd_hdr_e2(pdev,
1237d14abf15SRobert Mustacchi 					elem->cmd_data.vlan_mac.target_obj,
1238d14abf15SRobert Mustacchi 					      TRUE, CLASSIFY_RULE_OPCODE_MAC,
1239d14abf15SRobert Mustacchi 					      &rule_entry->mac.header);
1240d14abf15SRobert Mustacchi 
1241d14abf15SRobert Mustacchi 		/* Set a MAC itself */
1242d14abf15SRobert Mustacchi 		ecore_set_fw_mac_addr(&rule_entry->mac.mac_msb,
1243d14abf15SRobert Mustacchi 				      &rule_entry->mac.mac_mid,
1244d14abf15SRobert Mustacchi 				      &rule_entry->mac.mac_lsb, mac);
1245d14abf15SRobert Mustacchi 		rule_entry->mac.inner_mac =
1246d14abf15SRobert Mustacchi 			mm_cpu_to_le16(elem->cmd_data.vlan_mac.
1247d14abf15SRobert Mustacchi 				       u.mac.is_inner_mac);
1248d14abf15SRobert Mustacchi 	}
1249d14abf15SRobert Mustacchi 
1250d14abf15SRobert Mustacchi 	/* Set the ramrod data header */
1251d14abf15SRobert Mustacchi 	/* TODO: take this to the higher level in order to prevent multiple
1252d14abf15SRobert Mustacchi 		 writing */
1253d14abf15SRobert Mustacchi 	ecore_vlan_mac_set_rdata_hdr_e2(raw->cid, raw->state, &data->header,
1254d14abf15SRobert Mustacchi 					rule_cnt);
1255d14abf15SRobert Mustacchi }
1256d14abf15SRobert Mustacchi 
1257d14abf15SRobert Mustacchi /**
1258d14abf15SRobert Mustacchi  * ecore_vlan_mac_set_rdata_hdr_e1x - set a header in a single classify ramrod
1259d14abf15SRobert Mustacchi  *
1260d14abf15SRobert Mustacchi  * @pdev:	device handle
1261d14abf15SRobert Mustacchi  * @o:		queue
1262d14abf15SRobert Mustacchi  * @type:
1263d14abf15SRobert Mustacchi  * @cam_offset:	offset in cam memory
1264d14abf15SRobert Mustacchi  * @hdr:	pointer to a header to setup
1265d14abf15SRobert Mustacchi  *
1266d14abf15SRobert Mustacchi  * E1/E1H
1267d14abf15SRobert Mustacchi  */
ecore_vlan_mac_set_rdata_hdr_e1x(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,int type,int cam_offset,struct mac_configuration_hdr * hdr)1268d14abf15SRobert Mustacchi static INLINE void ecore_vlan_mac_set_rdata_hdr_e1x(struct _lm_device_t *pdev,
1269d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *o, int type, int cam_offset,
1270d14abf15SRobert Mustacchi 	struct mac_configuration_hdr *hdr)
1271d14abf15SRobert Mustacchi {
1272d14abf15SRobert Mustacchi 	struct ecore_raw_obj *r = &o->raw;
1273d14abf15SRobert Mustacchi 
1274d14abf15SRobert Mustacchi 	hdr->length = 1;
1275d14abf15SRobert Mustacchi 	hdr->offset = (u8)cam_offset;
1276d14abf15SRobert Mustacchi 	hdr->client_id = mm_cpu_to_le16(0xff);
1277d14abf15SRobert Mustacchi 	hdr->echo = mm_cpu_to_le32((r->cid & ECORE_SWCID_MASK) |
1278d14abf15SRobert Mustacchi 				(type << ECORE_SWCID_SHIFT));
1279d14abf15SRobert Mustacchi }
1280d14abf15SRobert Mustacchi 
ecore_vlan_mac_set_cfg_entry_e1x(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,BOOL add,int opcode,u8 * mac,u16 vlan_id,struct mac_configuration_entry * cfg_entry)1281d14abf15SRobert Mustacchi static INLINE void ecore_vlan_mac_set_cfg_entry_e1x(struct _lm_device_t *pdev,
1282d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *o, BOOL add, int opcode, u8 *mac,
1283d14abf15SRobert Mustacchi 	u16 vlan_id, struct mac_configuration_entry *cfg_entry)
1284d14abf15SRobert Mustacchi {
1285d14abf15SRobert Mustacchi 	struct ecore_raw_obj *r = &o->raw;
1286d14abf15SRobert Mustacchi 	u32 cl_bit_vec = (1 << r->cl_id);
1287d14abf15SRobert Mustacchi 
1288d14abf15SRobert Mustacchi 	cfg_entry->clients_bit_vector = mm_cpu_to_le32(cl_bit_vec);
1289d14abf15SRobert Mustacchi 	cfg_entry->pf_id = r->func_id;
1290d14abf15SRobert Mustacchi 	cfg_entry->vlan_id = mm_cpu_to_le16(vlan_id);
1291d14abf15SRobert Mustacchi 
1292d14abf15SRobert Mustacchi 	if (add) {
1293d14abf15SRobert Mustacchi 		ECORE_SET_FLAG(cfg_entry->flags,
1294d14abf15SRobert Mustacchi 			       MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
1295d14abf15SRobert Mustacchi 			       T_ETH_MAC_COMMAND_SET);
1296d14abf15SRobert Mustacchi 		ECORE_SET_FLAG(cfg_entry->flags,
1297d14abf15SRobert Mustacchi 			       MAC_CONFIGURATION_ENTRY_VLAN_FILTERING_MODE,
1298d14abf15SRobert Mustacchi 			       opcode);
1299d14abf15SRobert Mustacchi 
1300d14abf15SRobert Mustacchi 		/* Set a MAC in a ramrod data */
1301d14abf15SRobert Mustacchi 		ecore_set_fw_mac_addr(&cfg_entry->msb_mac_addr,
1302d14abf15SRobert Mustacchi 				      &cfg_entry->middle_mac_addr,
1303d14abf15SRobert Mustacchi 				      &cfg_entry->lsb_mac_addr, mac);
1304d14abf15SRobert Mustacchi 	} else
1305d14abf15SRobert Mustacchi 		ECORE_SET_FLAG(cfg_entry->flags,
1306d14abf15SRobert Mustacchi 			       MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
1307d14abf15SRobert Mustacchi 			       T_ETH_MAC_COMMAND_INVALIDATE);
1308d14abf15SRobert Mustacchi }
1309d14abf15SRobert Mustacchi 
ecore_vlan_mac_set_rdata_e1x(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,int type,int cam_offset,BOOL add,u8 * mac,u16 vlan_id,int opcode,struct mac_configuration_cmd * config)1310d14abf15SRobert Mustacchi static INLINE void ecore_vlan_mac_set_rdata_e1x(struct _lm_device_t *pdev,
1311d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *o, int type, int cam_offset, BOOL add,
1312d14abf15SRobert Mustacchi 	u8 *mac, u16 vlan_id, int opcode, struct mac_configuration_cmd *config)
1313d14abf15SRobert Mustacchi {
1314d14abf15SRobert Mustacchi 	struct mac_configuration_entry *cfg_entry = &config->config_table[0];
1315d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &o->raw;
1316d14abf15SRobert Mustacchi 
1317d14abf15SRobert Mustacchi 	ecore_vlan_mac_set_rdata_hdr_e1x(pdev, o, type, cam_offset,
1318d14abf15SRobert Mustacchi 					 &config->hdr);
1319d14abf15SRobert Mustacchi 	ecore_vlan_mac_set_cfg_entry_e1x(pdev, o, add, opcode, mac, vlan_id,
1320d14abf15SRobert Mustacchi 					 cfg_entry);
1321d14abf15SRobert Mustacchi 
1322d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "%s MAC %02x:%02x:%02x:%02x:%02x:%02x CLID %d CAM offset %d\n",
1323d14abf15SRobert Mustacchi 		  (add ? "setting" : "clearing"),
1324d14abf15SRobert Mustacchi 		  mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], raw->cl_id, cam_offset);
1325d14abf15SRobert Mustacchi }
1326d14abf15SRobert Mustacchi 
1327d14abf15SRobert Mustacchi /**
1328d14abf15SRobert Mustacchi  * ecore_set_one_mac_e1x - fill a single MAC rule ramrod data
1329d14abf15SRobert Mustacchi  *
1330d14abf15SRobert Mustacchi  * @pdev:	device handle
1331d14abf15SRobert Mustacchi  * @o:		ecore_vlan_mac_obj
1332d14abf15SRobert Mustacchi  * @elem:	ecore_exeq_elem
1333d14abf15SRobert Mustacchi  * @rule_idx:	rule_idx
1334d14abf15SRobert Mustacchi  * @cam_offset: cam_offset
1335d14abf15SRobert Mustacchi  */
ecore_set_one_mac_e1x(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,struct ecore_exeq_elem * elem,int rule_idx,int cam_offset)1336d14abf15SRobert Mustacchi static void ecore_set_one_mac_e1x(struct _lm_device_t *pdev,
1337d14abf15SRobert Mustacchi 				  struct ecore_vlan_mac_obj *o,
1338d14abf15SRobert Mustacchi 				  struct ecore_exeq_elem *elem, int rule_idx,
1339d14abf15SRobert Mustacchi 				  int cam_offset)
1340d14abf15SRobert Mustacchi {
1341d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &o->raw;
1342d14abf15SRobert Mustacchi 	struct mac_configuration_cmd *config =
1343d14abf15SRobert Mustacchi 		(struct mac_configuration_cmd *)(raw->rdata);
1344d14abf15SRobert Mustacchi 	/* 57710 and 57711 do not support MOVE command,
1345d14abf15SRobert Mustacchi 	 * so it's either ADD or DEL
1346d14abf15SRobert Mustacchi 	 */
1347d14abf15SRobert Mustacchi 	BOOL add = (elem->cmd_data.vlan_mac.cmd == ECORE_VLAN_MAC_ADD) ?
1348d14abf15SRobert Mustacchi 		TRUE : FALSE;
1349d14abf15SRobert Mustacchi 
1350d14abf15SRobert Mustacchi 	/* Reset the ramrod data buffer */
1351d14abf15SRobert Mustacchi 	mm_memset(config, 0, sizeof(*config));
1352d14abf15SRobert Mustacchi 
1353d14abf15SRobert Mustacchi 	ecore_vlan_mac_set_rdata_e1x(pdev, o, raw->state,
1354d14abf15SRobert Mustacchi 				     cam_offset, add,
1355d14abf15SRobert Mustacchi 				     elem->cmd_data.vlan_mac.u.mac.mac, 0,
1356d14abf15SRobert Mustacchi 				     ETH_VLAN_FILTER_ANY_VLAN, config);
1357d14abf15SRobert Mustacchi }
1358d14abf15SRobert Mustacchi 
ecore_set_one_vlan_e2(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,struct ecore_exeq_elem * elem,int rule_idx,int cam_offset)1359d14abf15SRobert Mustacchi static void ecore_set_one_vlan_e2(struct _lm_device_t *pdev,
1360d14abf15SRobert Mustacchi 				  struct ecore_vlan_mac_obj *o,
1361d14abf15SRobert Mustacchi 				  struct ecore_exeq_elem *elem, int rule_idx,
1362d14abf15SRobert Mustacchi 				  int cam_offset)
1363d14abf15SRobert Mustacchi {
1364d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &o->raw;
1365d14abf15SRobert Mustacchi 	struct eth_classify_rules_ramrod_data *data =
1366d14abf15SRobert Mustacchi 		(struct eth_classify_rules_ramrod_data *)(raw->rdata);
1367d14abf15SRobert Mustacchi 	int rule_cnt = rule_idx + 1;
1368d14abf15SRobert Mustacchi 	union eth_classify_rule_cmd *rule_entry = &data->rules[rule_idx];
1369d14abf15SRobert Mustacchi 	enum ecore_vlan_mac_cmd cmd = elem->cmd_data.vlan_mac.cmd;
1370d14abf15SRobert Mustacchi 	BOOL add = (cmd == ECORE_VLAN_MAC_ADD) ? TRUE : FALSE;
1371d14abf15SRobert Mustacchi 	u16 vlan = elem->cmd_data.vlan_mac.u.vlan.vlan;
1372d14abf15SRobert Mustacchi 
1373d14abf15SRobert Mustacchi 	/* Reset the ramrod data buffer for the first rule */
1374d14abf15SRobert Mustacchi 	if (rule_idx == 0)
1375d14abf15SRobert Mustacchi 		mm_memset(data, 0, sizeof(*data));
1376d14abf15SRobert Mustacchi 
1377d14abf15SRobert Mustacchi 	/* Set a rule header */
1378d14abf15SRobert Mustacchi 	ecore_vlan_mac_set_cmd_hdr_e2(pdev, o, add, CLASSIFY_RULE_OPCODE_VLAN,
1379d14abf15SRobert Mustacchi 				      &rule_entry->vlan.header);
1380d14abf15SRobert Mustacchi 
1381d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "About to %s VLAN %d\n", (add ? "add" : "delete"),
1382d14abf15SRobert Mustacchi 		  vlan);
1383d14abf15SRobert Mustacchi 
1384d14abf15SRobert Mustacchi 	/* Set a VLAN itself */
1385d14abf15SRobert Mustacchi 	rule_entry->vlan.vlan = mm_cpu_to_le16(vlan);
1386d14abf15SRobert Mustacchi 
1387d14abf15SRobert Mustacchi 	/* MOVE: Add a rule that will add this MAC to the target Queue */
1388d14abf15SRobert Mustacchi 	if (cmd == ECORE_VLAN_MAC_MOVE) {
1389d14abf15SRobert Mustacchi 		rule_entry++;
1390d14abf15SRobert Mustacchi 		rule_cnt++;
1391d14abf15SRobert Mustacchi 
1392d14abf15SRobert Mustacchi 		/* Setup ramrod data */
1393d14abf15SRobert Mustacchi 		ecore_vlan_mac_set_cmd_hdr_e2(pdev,
1394d14abf15SRobert Mustacchi 					elem->cmd_data.vlan_mac.target_obj,
1395d14abf15SRobert Mustacchi 					      TRUE, CLASSIFY_RULE_OPCODE_VLAN,
1396d14abf15SRobert Mustacchi 					      &rule_entry->vlan.header);
1397d14abf15SRobert Mustacchi 
1398d14abf15SRobert Mustacchi 		/* Set a VLAN itself */
1399d14abf15SRobert Mustacchi 		rule_entry->vlan.vlan = mm_cpu_to_le16(vlan);
1400d14abf15SRobert Mustacchi 	}
1401d14abf15SRobert Mustacchi 
1402d14abf15SRobert Mustacchi 	/* Set the ramrod data header */
1403d14abf15SRobert Mustacchi 	/* TODO: take this to the higher level in order to prevent multiple
1404d14abf15SRobert Mustacchi 		 writing */
1405d14abf15SRobert Mustacchi 	ecore_vlan_mac_set_rdata_hdr_e2(raw->cid, raw->state, &data->header,
1406d14abf15SRobert Mustacchi 					rule_cnt);
1407d14abf15SRobert Mustacchi }
1408d14abf15SRobert Mustacchi 
ecore_set_one_vlan_mac_e2(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,struct ecore_exeq_elem * elem,int rule_idx,int cam_offset)1409d14abf15SRobert Mustacchi static void ecore_set_one_vlan_mac_e2(struct _lm_device_t *pdev,
1410d14abf15SRobert Mustacchi 				      struct ecore_vlan_mac_obj *o,
1411d14abf15SRobert Mustacchi 				      struct ecore_exeq_elem *elem,
1412d14abf15SRobert Mustacchi 				      int rule_idx, int cam_offset)
1413d14abf15SRobert Mustacchi {
1414d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &o->raw;
1415d14abf15SRobert Mustacchi 	struct eth_classify_rules_ramrod_data *data =
1416d14abf15SRobert Mustacchi 		(struct eth_classify_rules_ramrod_data *)(raw->rdata);
1417d14abf15SRobert Mustacchi 	int rule_cnt = rule_idx + 1;
1418d14abf15SRobert Mustacchi 	union eth_classify_rule_cmd *rule_entry = &data->rules[rule_idx];
1419d14abf15SRobert Mustacchi 	enum ecore_vlan_mac_cmd cmd = elem->cmd_data.vlan_mac.cmd;
1420d14abf15SRobert Mustacchi 	BOOL add = (cmd == ECORE_VLAN_MAC_ADD) ? TRUE : FALSE;
1421d14abf15SRobert Mustacchi 	u16 vlan = elem->cmd_data.vlan_mac.u.vlan_mac.vlan;
1422d14abf15SRobert Mustacchi 	u8 *mac = elem->cmd_data.vlan_mac.u.vlan_mac.mac;
1423d14abf15SRobert Mustacchi 
1424d14abf15SRobert Mustacchi 	/* Reset the ramrod data buffer for the first rule */
1425d14abf15SRobert Mustacchi 	if (rule_idx == 0)
1426d14abf15SRobert Mustacchi 		mm_memset(data, 0, sizeof(*data));
1427d14abf15SRobert Mustacchi 
1428d14abf15SRobert Mustacchi 	/* Set a rule header */
1429d14abf15SRobert Mustacchi 	ecore_vlan_mac_set_cmd_hdr_e2(pdev, o, add, CLASSIFY_RULE_OPCODE_PAIR,
1430d14abf15SRobert Mustacchi 				      &rule_entry->pair.header);
1431d14abf15SRobert Mustacchi 
1432d14abf15SRobert Mustacchi 	/* Set VLAN and MAC themselves */
1433d14abf15SRobert Mustacchi 	rule_entry->pair.vlan = mm_cpu_to_le16(vlan);
1434d14abf15SRobert Mustacchi 	ecore_set_fw_mac_addr(&rule_entry->pair.mac_msb,
1435d14abf15SRobert Mustacchi 			      &rule_entry->pair.mac_mid,
1436d14abf15SRobert Mustacchi 			      &rule_entry->pair.mac_lsb, mac);
1437d14abf15SRobert Mustacchi 	rule_entry->pair.inner_mac =
1438d14abf15SRobert Mustacchi 			elem->cmd_data.vlan_mac.u.vlan_mac.is_inner_mac;
1439d14abf15SRobert Mustacchi 	/* MOVE: Add a rule that will add this MAC to the target Queue */
1440d14abf15SRobert Mustacchi 	if (cmd == ECORE_VLAN_MAC_MOVE) {
1441d14abf15SRobert Mustacchi 		rule_entry++;
1442d14abf15SRobert Mustacchi 		rule_cnt++;
1443d14abf15SRobert Mustacchi 
1444d14abf15SRobert Mustacchi 		/* Setup ramrod data */
1445d14abf15SRobert Mustacchi 		ecore_vlan_mac_set_cmd_hdr_e2(pdev,
1446d14abf15SRobert Mustacchi 					elem->cmd_data.vlan_mac.target_obj,
1447d14abf15SRobert Mustacchi 					      TRUE, CLASSIFY_RULE_OPCODE_PAIR,
1448d14abf15SRobert Mustacchi 					      &rule_entry->pair.header);
1449d14abf15SRobert Mustacchi 
1450d14abf15SRobert Mustacchi 		/* Set a VLAN itself */
1451d14abf15SRobert Mustacchi 		rule_entry->pair.vlan = mm_cpu_to_le16(vlan);
1452d14abf15SRobert Mustacchi 		ecore_set_fw_mac_addr(&rule_entry->pair.mac_msb,
1453d14abf15SRobert Mustacchi 				      &rule_entry->pair.mac_mid,
1454d14abf15SRobert Mustacchi 				      &rule_entry->pair.mac_lsb, mac);
1455d14abf15SRobert Mustacchi 		rule_entry->pair.inner_mac =
1456d14abf15SRobert Mustacchi 			elem->cmd_data.vlan_mac.u.vlan_mac.is_inner_mac;
1457d14abf15SRobert Mustacchi 	}
1458d14abf15SRobert Mustacchi 
1459d14abf15SRobert Mustacchi 	/* Set the ramrod data header */
1460d14abf15SRobert Mustacchi 	/* TODO: take this to the higher level in order to prevent multiple
1461d14abf15SRobert Mustacchi 		 writing */
1462d14abf15SRobert Mustacchi 	ecore_vlan_mac_set_rdata_hdr_e2(raw->cid, raw->state, &data->header,
1463d14abf15SRobert Mustacchi 					rule_cnt);
1464d14abf15SRobert Mustacchi }
1465d14abf15SRobert Mustacchi 
1466d14abf15SRobert Mustacchi /**
1467d14abf15SRobert Mustacchi  * ecore_set_one_vlan_mac_e1h -
1468d14abf15SRobert Mustacchi  *
1469d14abf15SRobert Mustacchi  * @pdev:	device handle
1470d14abf15SRobert Mustacchi  * @o:		ecore_vlan_mac_obj
1471d14abf15SRobert Mustacchi  * @elem:	ecore_exeq_elem
1472d14abf15SRobert Mustacchi  * @rule_idx:	rule_idx
1473d14abf15SRobert Mustacchi  * @cam_offset:	cam_offset
1474d14abf15SRobert Mustacchi  */
ecore_set_one_vlan_mac_e1h(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,struct ecore_exeq_elem * elem,int rule_idx,int cam_offset)1475d14abf15SRobert Mustacchi static void ecore_set_one_vlan_mac_e1h(struct _lm_device_t *pdev,
1476d14abf15SRobert Mustacchi 				       struct ecore_vlan_mac_obj *o,
1477d14abf15SRobert Mustacchi 				       struct ecore_exeq_elem *elem,
1478d14abf15SRobert Mustacchi 				       int rule_idx, int cam_offset)
1479d14abf15SRobert Mustacchi {
1480d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &o->raw;
1481d14abf15SRobert Mustacchi 	struct mac_configuration_cmd *config =
1482d14abf15SRobert Mustacchi 		(struct mac_configuration_cmd *)(raw->rdata);
1483d14abf15SRobert Mustacchi 	/* 57710 and 57711 do not support MOVE command,
1484d14abf15SRobert Mustacchi 	 * so it's either ADD or DEL
1485d14abf15SRobert Mustacchi 	 */
1486d14abf15SRobert Mustacchi 	BOOL add = (elem->cmd_data.vlan_mac.cmd == ECORE_VLAN_MAC_ADD) ?
1487d14abf15SRobert Mustacchi 		TRUE : FALSE;
1488d14abf15SRobert Mustacchi 
1489d14abf15SRobert Mustacchi 	/* Reset the ramrod data buffer */
1490d14abf15SRobert Mustacchi 	mm_memset(config, 0, sizeof(*config));
1491d14abf15SRobert Mustacchi 
1492d14abf15SRobert Mustacchi 	ecore_vlan_mac_set_rdata_e1x(pdev, o, ECORE_FILTER_VLAN_MAC_PENDING,
1493d14abf15SRobert Mustacchi 				     cam_offset, add,
1494d14abf15SRobert Mustacchi 				     elem->cmd_data.vlan_mac.u.vlan_mac.mac,
1495d14abf15SRobert Mustacchi 				     elem->cmd_data.vlan_mac.u.vlan_mac.vlan,
1496d14abf15SRobert Mustacchi 				     ETH_VLAN_FILTER_CLASSIFY, config);
1497d14abf15SRobert Mustacchi }
1498d14abf15SRobert Mustacchi 
1499d14abf15SRobert Mustacchi #define list_next_entry(pos, member) \
1500d14abf15SRobert Mustacchi 	list_entry((pos)->member.next, typeof(*(pos)), member)
1501d14abf15SRobert Mustacchi 
1502d14abf15SRobert Mustacchi /**
1503d14abf15SRobert Mustacchi  * ecore_vlan_mac_restore - reconfigure next MAC/VLAN/VLAN-MAC element
1504d14abf15SRobert Mustacchi  *
1505d14abf15SRobert Mustacchi  * @pdev:	device handle
1506d14abf15SRobert Mustacchi  * @p:		command parameters
1507d14abf15SRobert Mustacchi  * @ppos:	pointer to the cookie
1508d14abf15SRobert Mustacchi  *
1509d14abf15SRobert Mustacchi  * reconfigure next MAC/VLAN/VLAN-MAC element from the
1510d14abf15SRobert Mustacchi  * previously configured elements list.
1511d14abf15SRobert Mustacchi  *
1512d14abf15SRobert Mustacchi  * from command parameters only RAMROD_COMP_WAIT bit in ramrod_flags is	taken
1513d14abf15SRobert Mustacchi  * into an account
1514d14abf15SRobert Mustacchi  *
1515d14abf15SRobert Mustacchi  * pointer to the cookie  - that should be given back in the next call to make
1516d14abf15SRobert Mustacchi  * function handle the next element. If *ppos is set to NULL it will restart the
1517d14abf15SRobert Mustacchi  * iterator. If returned *ppos == NULL this means that the last element has been
1518d14abf15SRobert Mustacchi  * handled.
1519d14abf15SRobert Mustacchi  *
1520d14abf15SRobert Mustacchi  */
ecore_vlan_mac_restore(struct _lm_device_t * pdev,struct ecore_vlan_mac_ramrod_params * p,struct ecore_vlan_mac_registry_elem ** ppos)1521d14abf15SRobert Mustacchi static int ecore_vlan_mac_restore(struct _lm_device_t *pdev,
1522d14abf15SRobert Mustacchi 			   struct ecore_vlan_mac_ramrod_params *p,
1523d14abf15SRobert Mustacchi 			   struct ecore_vlan_mac_registry_elem **ppos)
1524d14abf15SRobert Mustacchi {
1525d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem *pos;
1526d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *o = p->vlan_mac_obj;
1527d14abf15SRobert Mustacchi 
1528d14abf15SRobert Mustacchi 	/* If list is empty - there is nothing to do here */
1529d14abf15SRobert Mustacchi 	if (ECORE_LIST_IS_EMPTY(&o->head)) {
1530d14abf15SRobert Mustacchi 		*ppos = NULL;
1531d14abf15SRobert Mustacchi 		return 0;
1532d14abf15SRobert Mustacchi 	}
1533d14abf15SRobert Mustacchi 
1534d14abf15SRobert Mustacchi 	/* make a step... */
1535d14abf15SRobert Mustacchi 	if (*ppos == NULL)
1536d14abf15SRobert Mustacchi 		*ppos = ECORE_LIST_FIRST_ENTRY(&o->head,
1537d14abf15SRobert Mustacchi 					    struct ecore_vlan_mac_registry_elem,
1538d14abf15SRobert Mustacchi 					       link);
1539d14abf15SRobert Mustacchi 	else
1540d14abf15SRobert Mustacchi 		*ppos = ECORE_LIST_NEXT(*ppos, link,
1541d14abf15SRobert Mustacchi 					struct ecore_vlan_mac_registry_elem);
1542d14abf15SRobert Mustacchi 
1543d14abf15SRobert Mustacchi 	pos = *ppos;
1544d14abf15SRobert Mustacchi 
1545d14abf15SRobert Mustacchi 	/* If it's the last step - return NULL */
1546d14abf15SRobert Mustacchi 	if (ECORE_LIST_IS_LAST(&pos->link, &o->head))
1547d14abf15SRobert Mustacchi 		*ppos = NULL;
1548d14abf15SRobert Mustacchi 
1549d14abf15SRobert Mustacchi 	/* Prepare a 'user_req' */
1550d14abf15SRobert Mustacchi 	mm_memcpy(&p->user_req.u, &pos->u, sizeof(pos->u));
1551d14abf15SRobert Mustacchi 
1552d14abf15SRobert Mustacchi 	/* Set the command */
1553d14abf15SRobert Mustacchi 	p->user_req.cmd = ECORE_VLAN_MAC_ADD;
1554d14abf15SRobert Mustacchi 
1555d14abf15SRobert Mustacchi 	/* Set vlan_mac_flags */
1556d14abf15SRobert Mustacchi 	p->user_req.vlan_mac_flags = pos->vlan_mac_flags;
1557d14abf15SRobert Mustacchi 
1558d14abf15SRobert Mustacchi 	/* Set a restore bit */
1559d14abf15SRobert Mustacchi 	ECORE_SET_BIT_NA(RAMROD_RESTORE, &p->ramrod_flags);
1560d14abf15SRobert Mustacchi 
1561d14abf15SRobert Mustacchi 	return ecore_config_vlan_mac(pdev, p);
1562d14abf15SRobert Mustacchi }
1563d14abf15SRobert Mustacchi 
1564d14abf15SRobert Mustacchi /* ecore_exeq_get_mac/ecore_exeq_get_vlan/ecore_exeq_get_vlan_mac return a
1565d14abf15SRobert Mustacchi  * pointer to an element with a specific criteria and NULL if such an element
1566d14abf15SRobert Mustacchi  * hasn't been found.
1567d14abf15SRobert Mustacchi  */
ecore_exeq_get_mac(struct ecore_exe_queue_obj * o,struct ecore_exeq_elem * elem)1568d14abf15SRobert Mustacchi static struct ecore_exeq_elem *ecore_exeq_get_mac(
1569d14abf15SRobert Mustacchi 	struct ecore_exe_queue_obj *o,
1570d14abf15SRobert Mustacchi 	struct ecore_exeq_elem *elem)
1571d14abf15SRobert Mustacchi {
1572d14abf15SRobert Mustacchi 	struct ecore_exeq_elem *pos;
1573d14abf15SRobert Mustacchi 	struct ecore_mac_ramrod_data *data = &elem->cmd_data.vlan_mac.u.mac;
1574d14abf15SRobert Mustacchi 
1575d14abf15SRobert Mustacchi 	/* Check pending for execution commands */
1576d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(pos, &o->exe_queue, link,
1577d14abf15SRobert Mustacchi 				  struct ecore_exeq_elem)
1578d14abf15SRobert Mustacchi 		if (mm_memcmp(&pos->cmd_data.vlan_mac.u.mac, data,
1579d14abf15SRobert Mustacchi 			      sizeof(*data)) &&
1580d14abf15SRobert Mustacchi 		    (pos->cmd_data.vlan_mac.cmd == elem->cmd_data.vlan_mac.cmd))
1581d14abf15SRobert Mustacchi 			return pos;
1582d14abf15SRobert Mustacchi 
1583d14abf15SRobert Mustacchi 	return NULL;
1584d14abf15SRobert Mustacchi }
1585d14abf15SRobert Mustacchi 
ecore_exeq_get_vlan(struct ecore_exe_queue_obj * o,struct ecore_exeq_elem * elem)1586d14abf15SRobert Mustacchi static struct ecore_exeq_elem *ecore_exeq_get_vlan(
1587d14abf15SRobert Mustacchi 	struct ecore_exe_queue_obj *o,
1588d14abf15SRobert Mustacchi 	struct ecore_exeq_elem *elem)
1589d14abf15SRobert Mustacchi {
1590d14abf15SRobert Mustacchi 	struct ecore_exeq_elem *pos;
1591d14abf15SRobert Mustacchi 	struct ecore_vlan_ramrod_data *data = &elem->cmd_data.vlan_mac.u.vlan;
1592d14abf15SRobert Mustacchi 
1593d14abf15SRobert Mustacchi 	/* Check pending for execution commands */
1594d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(pos, &o->exe_queue, link,
1595d14abf15SRobert Mustacchi 				  struct ecore_exeq_elem)
1596d14abf15SRobert Mustacchi 		if (mm_memcmp(&pos->cmd_data.vlan_mac.u.vlan, data,
1597d14abf15SRobert Mustacchi 			      sizeof(*data)) &&
1598d14abf15SRobert Mustacchi 		    (pos->cmd_data.vlan_mac.cmd == elem->cmd_data.vlan_mac.cmd))
1599d14abf15SRobert Mustacchi 			return pos;
1600d14abf15SRobert Mustacchi 
1601d14abf15SRobert Mustacchi 	return NULL;
1602d14abf15SRobert Mustacchi }
1603d14abf15SRobert Mustacchi 
ecore_exeq_get_vlan_mac(struct ecore_exe_queue_obj * o,struct ecore_exeq_elem * elem)1604d14abf15SRobert Mustacchi static struct ecore_exeq_elem *ecore_exeq_get_vlan_mac(
1605d14abf15SRobert Mustacchi 	struct ecore_exe_queue_obj *o,
1606d14abf15SRobert Mustacchi 	struct ecore_exeq_elem *elem)
1607d14abf15SRobert Mustacchi {
1608d14abf15SRobert Mustacchi 	struct ecore_exeq_elem *pos;
1609d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_ramrod_data *data =
1610d14abf15SRobert Mustacchi 		&elem->cmd_data.vlan_mac.u.vlan_mac;
1611d14abf15SRobert Mustacchi 
1612d14abf15SRobert Mustacchi 	/* Check pending for execution commands */
1613d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(pos, &o->exe_queue, link,
1614d14abf15SRobert Mustacchi 				  struct ecore_exeq_elem)
1615d14abf15SRobert Mustacchi 		if (mm_memcmp(&pos->cmd_data.vlan_mac.u.vlan_mac, data,
1616d14abf15SRobert Mustacchi 			      sizeof(*data)) &&
1617d14abf15SRobert Mustacchi 		    (pos->cmd_data.vlan_mac.cmd == elem->cmd_data.vlan_mac.cmd))
1618d14abf15SRobert Mustacchi 			return pos;
1619d14abf15SRobert Mustacchi 
1620d14abf15SRobert Mustacchi 	return NULL;
1621d14abf15SRobert Mustacchi }
1622d14abf15SRobert Mustacchi 
1623d14abf15SRobert Mustacchi /**
1624d14abf15SRobert Mustacchi  * ecore_validate_vlan_mac_add - check if an ADD command can be executed
1625d14abf15SRobert Mustacchi  *
1626d14abf15SRobert Mustacchi  * @pdev:	device handle
1627d14abf15SRobert Mustacchi  * @qo:		ecore_qable_obj
1628d14abf15SRobert Mustacchi  * @elem:	ecore_exeq_elem
1629d14abf15SRobert Mustacchi  *
1630d14abf15SRobert Mustacchi  * Checks that the requested configuration can be added. If yes and if
1631d14abf15SRobert Mustacchi  * requested, consume CAM credit.
1632d14abf15SRobert Mustacchi  *
1633d14abf15SRobert Mustacchi  * The 'validate' is run after the 'optimize'.
1634d14abf15SRobert Mustacchi  *
1635d14abf15SRobert Mustacchi  */
ecore_validate_vlan_mac_add(struct _lm_device_t * pdev,union ecore_qable_obj * qo,struct ecore_exeq_elem * elem)1636d14abf15SRobert Mustacchi static INLINE int ecore_validate_vlan_mac_add(struct _lm_device_t *pdev,
1637d14abf15SRobert Mustacchi 					      union ecore_qable_obj *qo,
1638d14abf15SRobert Mustacchi 					      struct ecore_exeq_elem *elem)
1639d14abf15SRobert Mustacchi {
1640d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *o = &qo->vlan_mac;
1641d14abf15SRobert Mustacchi 	struct ecore_exe_queue_obj *exeq = &o->exe_queue;
1642d14abf15SRobert Mustacchi 	int rc;
1643d14abf15SRobert Mustacchi 
1644d14abf15SRobert Mustacchi 	/* Check the registry */
1645d14abf15SRobert Mustacchi 	rc = o->check_add(pdev, o, &elem->cmd_data.vlan_mac.u);
1646d14abf15SRobert Mustacchi 	if (rc) {
1647d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "ADD command is not allowed considering current registry state.\n");
1648d14abf15SRobert Mustacchi 		return rc;
1649d14abf15SRobert Mustacchi 	}
1650d14abf15SRobert Mustacchi 
1651d14abf15SRobert Mustacchi 	/* Check if there is a pending ADD command for this
1652d14abf15SRobert Mustacchi 	 * MAC/VLAN/VLAN-MAC. Return an error if there is.
1653d14abf15SRobert Mustacchi 	 */
1654d14abf15SRobert Mustacchi 	if (exeq->get(exeq, elem)) {
1655d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "There is a pending ADD command already\n");
1656d14abf15SRobert Mustacchi 		return ECORE_EXISTS;
1657d14abf15SRobert Mustacchi 	}
1658d14abf15SRobert Mustacchi 
1659d14abf15SRobert Mustacchi 	/* TODO: Check the pending MOVE from other objects where this
1660d14abf15SRobert Mustacchi 	 * object is a destination object.
1661d14abf15SRobert Mustacchi 	 */
1662d14abf15SRobert Mustacchi 
1663d14abf15SRobert Mustacchi 	/* Consume the credit if not requested not to */
1664d14abf15SRobert Mustacchi 	if (!(ECORE_TEST_BIT(ECORE_DONT_CONSUME_CAM_CREDIT,
1665d14abf15SRobert Mustacchi 			     &elem->cmd_data.vlan_mac.vlan_mac_flags) ||
1666d14abf15SRobert Mustacchi 	    o->get_credit(o)))
1667d14abf15SRobert Mustacchi 		return ECORE_INVAL;
1668d14abf15SRobert Mustacchi 
1669d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
1670d14abf15SRobert Mustacchi }
1671d14abf15SRobert Mustacchi 
1672d14abf15SRobert Mustacchi /**
1673d14abf15SRobert Mustacchi  * ecore_validate_vlan_mac_del - check if the DEL command can be executed
1674d14abf15SRobert Mustacchi  *
1675d14abf15SRobert Mustacchi  * @pdev:	device handle
1676d14abf15SRobert Mustacchi  * @qo:		quable object to check
1677d14abf15SRobert Mustacchi  * @elem:	element that needs to be deleted
1678d14abf15SRobert Mustacchi  *
1679d14abf15SRobert Mustacchi  * Checks that the requested configuration can be deleted. If yes and if
1680d14abf15SRobert Mustacchi  * requested, returns a CAM credit.
1681d14abf15SRobert Mustacchi  *
1682d14abf15SRobert Mustacchi  * The 'validate' is run after the 'optimize'.
1683d14abf15SRobert Mustacchi  */
ecore_validate_vlan_mac_del(struct _lm_device_t * pdev,union ecore_qable_obj * qo,struct ecore_exeq_elem * elem)1684d14abf15SRobert Mustacchi static INLINE int ecore_validate_vlan_mac_del(struct _lm_device_t *pdev,
1685d14abf15SRobert Mustacchi 					      union ecore_qable_obj *qo,
1686d14abf15SRobert Mustacchi 					      struct ecore_exeq_elem *elem)
1687d14abf15SRobert Mustacchi {
1688d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *o = &qo->vlan_mac;
1689d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem *pos;
1690d14abf15SRobert Mustacchi 	struct ecore_exe_queue_obj *exeq = &o->exe_queue;
1691d14abf15SRobert Mustacchi 	struct ecore_exeq_elem query_elem;
1692d14abf15SRobert Mustacchi 
1693d14abf15SRobert Mustacchi 	/* If this classification can not be deleted (doesn't exist)
1694d14abf15SRobert Mustacchi 	 * - return a ECORE_EXIST.
1695d14abf15SRobert Mustacchi 	 */
1696d14abf15SRobert Mustacchi 	pos = o->check_del(pdev, o, &elem->cmd_data.vlan_mac.u);
1697d14abf15SRobert Mustacchi 	if (!pos) {
1698d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "DEL command is not allowed considering current registry state\n");
1699d14abf15SRobert Mustacchi 		return ECORE_EXISTS;
1700d14abf15SRobert Mustacchi 	}
1701d14abf15SRobert Mustacchi 
1702d14abf15SRobert Mustacchi 	/* Check if there are pending DEL or MOVE commands for this
1703d14abf15SRobert Mustacchi 	 * MAC/VLAN/VLAN-MAC. Return an error if so.
1704d14abf15SRobert Mustacchi 	 */
1705d14abf15SRobert Mustacchi 	mm_memcpy(&query_elem, elem, sizeof(query_elem));
1706d14abf15SRobert Mustacchi 
1707d14abf15SRobert Mustacchi 	/* Check for MOVE commands */
1708d14abf15SRobert Mustacchi 	query_elem.cmd_data.vlan_mac.cmd = ECORE_VLAN_MAC_MOVE;
1709d14abf15SRobert Mustacchi 	if (exeq->get(exeq, &query_elem)) {
1710d14abf15SRobert Mustacchi 		ECORE_ERR("There is a pending MOVE command already\n");
1711d14abf15SRobert Mustacchi 		return ECORE_INVAL;
1712d14abf15SRobert Mustacchi 	}
1713d14abf15SRobert Mustacchi 
1714d14abf15SRobert Mustacchi 	/* Check for DEL commands */
1715d14abf15SRobert Mustacchi 	if (exeq->get(exeq, elem)) {
1716d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "There is a pending DEL command already\n");
1717d14abf15SRobert Mustacchi 		return ECORE_EXISTS;
1718d14abf15SRobert Mustacchi 	}
1719d14abf15SRobert Mustacchi 
1720d14abf15SRobert Mustacchi 	/* Return the credit to the credit pool if not requested not to */
1721d14abf15SRobert Mustacchi 	if (!(ECORE_TEST_BIT(ECORE_DONT_CONSUME_CAM_CREDIT,
1722d14abf15SRobert Mustacchi 			     &elem->cmd_data.vlan_mac.vlan_mac_flags) ||
1723d14abf15SRobert Mustacchi 	    o->put_credit(o))) {
1724d14abf15SRobert Mustacchi 		ECORE_ERR("Failed to return a credit\n");
1725d14abf15SRobert Mustacchi 		return ECORE_INVAL;
1726d14abf15SRobert Mustacchi 	}
1727d14abf15SRobert Mustacchi 
1728d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
1729d14abf15SRobert Mustacchi }
1730d14abf15SRobert Mustacchi 
1731d14abf15SRobert Mustacchi /**
1732d14abf15SRobert Mustacchi  * ecore_validate_vlan_mac_move - check if the MOVE command can be executed
1733d14abf15SRobert Mustacchi  *
1734d14abf15SRobert Mustacchi  * @pdev:	device handle
1735d14abf15SRobert Mustacchi  * @qo:		quable object to check (source)
1736d14abf15SRobert Mustacchi  * @elem:	element that needs to be moved
1737d14abf15SRobert Mustacchi  *
1738d14abf15SRobert Mustacchi  * Checks that the requested configuration can be moved. If yes and if
1739d14abf15SRobert Mustacchi  * requested, returns a CAM credit.
1740d14abf15SRobert Mustacchi  *
1741d14abf15SRobert Mustacchi  * The 'validate' is run after the 'optimize'.
1742d14abf15SRobert Mustacchi  */
ecore_validate_vlan_mac_move(struct _lm_device_t * pdev,union ecore_qable_obj * qo,struct ecore_exeq_elem * elem)1743d14abf15SRobert Mustacchi static INLINE int ecore_validate_vlan_mac_move(struct _lm_device_t *pdev,
1744d14abf15SRobert Mustacchi 					       union ecore_qable_obj *qo,
1745d14abf15SRobert Mustacchi 					       struct ecore_exeq_elem *elem)
1746d14abf15SRobert Mustacchi {
1747d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *src_o = &qo->vlan_mac;
1748d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *dest_o = elem->cmd_data.vlan_mac.target_obj;
1749d14abf15SRobert Mustacchi 	struct ecore_exeq_elem query_elem;
1750d14abf15SRobert Mustacchi 	struct ecore_exe_queue_obj *src_exeq = &src_o->exe_queue;
1751d14abf15SRobert Mustacchi 	struct ecore_exe_queue_obj *dest_exeq = &dest_o->exe_queue;
1752d14abf15SRobert Mustacchi 
1753d14abf15SRobert Mustacchi 	/* Check if we can perform this operation based on the current registry
1754d14abf15SRobert Mustacchi 	 * state.
1755d14abf15SRobert Mustacchi 	 */
1756d14abf15SRobert Mustacchi 	if (!src_o->check_move(pdev, src_o, dest_o,
1757d14abf15SRobert Mustacchi 			       &elem->cmd_data.vlan_mac.u)) {
1758d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "MOVE command is not allowed considering current registry state\n");
1759d14abf15SRobert Mustacchi 		return ECORE_INVAL;
1760d14abf15SRobert Mustacchi 	}
1761d14abf15SRobert Mustacchi 
1762d14abf15SRobert Mustacchi 	/* Check if there is an already pending DEL or MOVE command for the
1763d14abf15SRobert Mustacchi 	 * source object or ADD command for a destination object. Return an
1764d14abf15SRobert Mustacchi 	 * error if so.
1765d14abf15SRobert Mustacchi 	 */
1766d14abf15SRobert Mustacchi 	mm_memcpy(&query_elem, elem, sizeof(query_elem));
1767d14abf15SRobert Mustacchi 
1768d14abf15SRobert Mustacchi 	/* Check DEL on source */
1769d14abf15SRobert Mustacchi 	query_elem.cmd_data.vlan_mac.cmd = ECORE_VLAN_MAC_DEL;
1770d14abf15SRobert Mustacchi 	if (src_exeq->get(src_exeq, &query_elem)) {
1771d14abf15SRobert Mustacchi 		ECORE_ERR("There is a pending DEL command on the source queue already\n");
1772d14abf15SRobert Mustacchi 		return ECORE_INVAL;
1773d14abf15SRobert Mustacchi 	}
1774d14abf15SRobert Mustacchi 
1775d14abf15SRobert Mustacchi 	/* Check MOVE on source */
1776d14abf15SRobert Mustacchi 	if (src_exeq->get(src_exeq, elem)) {
1777d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "There is a pending MOVE command already\n");
1778d14abf15SRobert Mustacchi 		return ECORE_EXISTS;
1779d14abf15SRobert Mustacchi 	}
1780d14abf15SRobert Mustacchi 
1781d14abf15SRobert Mustacchi 	/* Check ADD on destination */
1782d14abf15SRobert Mustacchi 	query_elem.cmd_data.vlan_mac.cmd = ECORE_VLAN_MAC_ADD;
1783d14abf15SRobert Mustacchi 	if (dest_exeq->get(dest_exeq, &query_elem)) {
1784d14abf15SRobert Mustacchi 		ECORE_ERR("There is a pending ADD command on the destination queue already\n");
1785d14abf15SRobert Mustacchi 		return ECORE_INVAL;
1786d14abf15SRobert Mustacchi 	}
1787d14abf15SRobert Mustacchi 
1788d14abf15SRobert Mustacchi 	/* Consume the credit if not requested not to */
1789d14abf15SRobert Mustacchi 	if (!(ECORE_TEST_BIT(ECORE_DONT_CONSUME_CAM_CREDIT_DEST,
1790d14abf15SRobert Mustacchi 			     &elem->cmd_data.vlan_mac.vlan_mac_flags) ||
1791d14abf15SRobert Mustacchi 	    dest_o->get_credit(dest_o)))
1792d14abf15SRobert Mustacchi 		return ECORE_INVAL;
1793d14abf15SRobert Mustacchi 
1794d14abf15SRobert Mustacchi 	if (!(ECORE_TEST_BIT(ECORE_DONT_CONSUME_CAM_CREDIT,
1795d14abf15SRobert Mustacchi 			     &elem->cmd_data.vlan_mac.vlan_mac_flags) ||
1796d14abf15SRobert Mustacchi 	    src_o->put_credit(src_o))) {
1797d14abf15SRobert Mustacchi 		/* return the credit taken from dest... */
1798d14abf15SRobert Mustacchi 		dest_o->put_credit(dest_o);
1799d14abf15SRobert Mustacchi 		return ECORE_INVAL;
1800d14abf15SRobert Mustacchi 	}
1801d14abf15SRobert Mustacchi 
1802d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
1803d14abf15SRobert Mustacchi }
1804d14abf15SRobert Mustacchi 
ecore_validate_vlan_mac(struct _lm_device_t * pdev,union ecore_qable_obj * qo,struct ecore_exeq_elem * elem)1805d14abf15SRobert Mustacchi static int ecore_validate_vlan_mac(struct _lm_device_t *pdev,
1806d14abf15SRobert Mustacchi 				   union ecore_qable_obj *qo,
1807d14abf15SRobert Mustacchi 				   struct ecore_exeq_elem *elem)
1808d14abf15SRobert Mustacchi {
1809d14abf15SRobert Mustacchi 	switch (elem->cmd_data.vlan_mac.cmd) {
1810d14abf15SRobert Mustacchi 	case ECORE_VLAN_MAC_ADD:
1811d14abf15SRobert Mustacchi 		return ecore_validate_vlan_mac_add(pdev, qo, elem);
1812d14abf15SRobert Mustacchi 	case ECORE_VLAN_MAC_DEL:
1813d14abf15SRobert Mustacchi 		return ecore_validate_vlan_mac_del(pdev, qo, elem);
1814d14abf15SRobert Mustacchi 	case ECORE_VLAN_MAC_MOVE:
1815d14abf15SRobert Mustacchi 		return ecore_validate_vlan_mac_move(pdev, qo, elem);
1816d14abf15SRobert Mustacchi 	default:
1817d14abf15SRobert Mustacchi 		return ECORE_INVAL;
1818d14abf15SRobert Mustacchi 	}
1819d14abf15SRobert Mustacchi }
1820d14abf15SRobert Mustacchi 
ecore_remove_vlan_mac(struct _lm_device_t * pdev,union ecore_qable_obj * qo,struct ecore_exeq_elem * elem)1821d14abf15SRobert Mustacchi static int ecore_remove_vlan_mac(struct _lm_device_t *pdev,
1822d14abf15SRobert Mustacchi 				  union ecore_qable_obj *qo,
1823d14abf15SRobert Mustacchi 				  struct ecore_exeq_elem *elem)
1824d14abf15SRobert Mustacchi {
1825d14abf15SRobert Mustacchi 	int rc = 0;
1826d14abf15SRobert Mustacchi 
1827d14abf15SRobert Mustacchi 	/* If consumption wasn't required, nothing to do */
1828d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_DONT_CONSUME_CAM_CREDIT,
1829d14abf15SRobert Mustacchi 			   &elem->cmd_data.vlan_mac.vlan_mac_flags))
1830d14abf15SRobert Mustacchi 		return ECORE_SUCCESS;
1831d14abf15SRobert Mustacchi 
1832d14abf15SRobert Mustacchi 	switch (elem->cmd_data.vlan_mac.cmd) {
1833d14abf15SRobert Mustacchi 	case ECORE_VLAN_MAC_ADD:
1834d14abf15SRobert Mustacchi 	case ECORE_VLAN_MAC_MOVE:
1835d14abf15SRobert Mustacchi 		rc = qo->vlan_mac.put_credit(&qo->vlan_mac);
1836d14abf15SRobert Mustacchi 		break;
1837d14abf15SRobert Mustacchi 	case ECORE_VLAN_MAC_DEL:
1838d14abf15SRobert Mustacchi 		rc = qo->vlan_mac.get_credit(&qo->vlan_mac);
1839d14abf15SRobert Mustacchi 		break;
1840d14abf15SRobert Mustacchi 	default:
1841d14abf15SRobert Mustacchi 		return ECORE_INVAL;
1842d14abf15SRobert Mustacchi 	}
1843d14abf15SRobert Mustacchi 
1844d14abf15SRobert Mustacchi 	if (rc != TRUE)
1845d14abf15SRobert Mustacchi 		return ECORE_INVAL;
1846d14abf15SRobert Mustacchi 
1847d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
1848d14abf15SRobert Mustacchi }
1849d14abf15SRobert Mustacchi 
1850d14abf15SRobert Mustacchi /**
1851d14abf15SRobert Mustacchi  * ecore_wait_vlan_mac - passively wait for 5 seconds until all work completes.
1852d14abf15SRobert Mustacchi  *
1853d14abf15SRobert Mustacchi  * @pdev:	device handle
1854d14abf15SRobert Mustacchi  * @o:		ecore_vlan_mac_obj
1855d14abf15SRobert Mustacchi  *
1856d14abf15SRobert Mustacchi  */
ecore_wait_vlan_mac(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o)1857d14abf15SRobert Mustacchi static int ecore_wait_vlan_mac(struct _lm_device_t *pdev,
1858d14abf15SRobert Mustacchi 			       struct ecore_vlan_mac_obj *o)
1859d14abf15SRobert Mustacchi {
1860d14abf15SRobert Mustacchi 	int cnt = 5000, rc;
1861d14abf15SRobert Mustacchi 	struct ecore_exe_queue_obj *exeq = &o->exe_queue;
1862d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &o->raw;
1863d14abf15SRobert Mustacchi 
1864d14abf15SRobert Mustacchi 	while (cnt--) {
1865d14abf15SRobert Mustacchi 		/* Wait for the current command to complete */
1866d14abf15SRobert Mustacchi 		rc = raw->wait_comp(pdev, raw);
1867d14abf15SRobert Mustacchi 		if (rc)
1868d14abf15SRobert Mustacchi 			return rc;
1869d14abf15SRobert Mustacchi 
1870d14abf15SRobert Mustacchi 		/* Wait until there are no pending commands */
1871d14abf15SRobert Mustacchi 		if (!ecore_exe_queue_empty(exeq))
1872d14abf15SRobert Mustacchi 			mm_wait(pdev, 1000);
1873d14abf15SRobert Mustacchi 		else
1874d14abf15SRobert Mustacchi 			return ECORE_SUCCESS;
1875d14abf15SRobert Mustacchi 	}
1876d14abf15SRobert Mustacchi 
1877d14abf15SRobert Mustacchi 	return ECORE_TIMEOUT;
1878d14abf15SRobert Mustacchi }
1879d14abf15SRobert Mustacchi 
__ecore_vlan_mac_execute_step(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,unsigned long * ramrod_flags)1880d14abf15SRobert Mustacchi static int __ecore_vlan_mac_execute_step(struct _lm_device_t *pdev,
1881d14abf15SRobert Mustacchi 					 struct ecore_vlan_mac_obj *o,
1882d14abf15SRobert Mustacchi 					 unsigned long *ramrod_flags)
1883d14abf15SRobert Mustacchi {
1884d14abf15SRobert Mustacchi 	int rc = ECORE_SUCCESS;
1885d14abf15SRobert Mustacchi 
1886d14abf15SRobert Mustacchi 	ECORE_SPIN_LOCK_BH(&o->exe_queue.lock);
1887d14abf15SRobert Mustacchi 
1888d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "vlan_mac_execute_step - trying to take writer lock\n");
1889d14abf15SRobert Mustacchi 	rc = __ecore_vlan_mac_h_write_trylock(pdev, o);
1890d14abf15SRobert Mustacchi 
1891d14abf15SRobert Mustacchi 	if (rc != ECORE_SUCCESS) {
1892d14abf15SRobert Mustacchi 		__ecore_vlan_mac_h_pend(pdev, o, *ramrod_flags);
1893d14abf15SRobert Mustacchi 
1894d14abf15SRobert Mustacchi 		/** Calling function should not diffrentiate between this case
1895d14abf15SRobert Mustacchi 		 *  and the case in which there is already a pending ramrod
1896d14abf15SRobert Mustacchi 		 */
1897d14abf15SRobert Mustacchi 		rc = ECORE_PENDING;
1898d14abf15SRobert Mustacchi 	} else {
1899d14abf15SRobert Mustacchi 		rc = ecore_exe_queue_step(pdev, &o->exe_queue, ramrod_flags);
1900d14abf15SRobert Mustacchi 	}
1901d14abf15SRobert Mustacchi 	ECORE_SPIN_UNLOCK_BH(&o->exe_queue.lock);
1902d14abf15SRobert Mustacchi 
1903d14abf15SRobert Mustacchi 	return rc;
1904d14abf15SRobert Mustacchi }
1905d14abf15SRobert Mustacchi 
1906d14abf15SRobert Mustacchi /**
1907d14abf15SRobert Mustacchi  * ecore_complete_vlan_mac - complete one VLAN-MAC ramrod
1908d14abf15SRobert Mustacchi  *
1909d14abf15SRobert Mustacchi  * @pdev:	device handle
1910d14abf15SRobert Mustacchi  * @o:		ecore_vlan_mac_obj
1911d14abf15SRobert Mustacchi  * @cqe:
1912d14abf15SRobert Mustacchi  * @cont:	if TRUE schedule next execution chunk
1913d14abf15SRobert Mustacchi  *
1914d14abf15SRobert Mustacchi  */
ecore_complete_vlan_mac(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,union event_ring_elem * cqe,unsigned long * ramrod_flags)1915d14abf15SRobert Mustacchi static int ecore_complete_vlan_mac(struct _lm_device_t *pdev,
1916d14abf15SRobert Mustacchi 				   struct ecore_vlan_mac_obj *o,
1917d14abf15SRobert Mustacchi 				   union event_ring_elem *cqe,
1918d14abf15SRobert Mustacchi 				   unsigned long *ramrod_flags)
1919d14abf15SRobert Mustacchi {
1920d14abf15SRobert Mustacchi 	struct ecore_raw_obj *r = &o->raw;
1921d14abf15SRobert Mustacchi 	int rc;
1922d14abf15SRobert Mustacchi 
1923d14abf15SRobert Mustacchi 	/* Clearing the pending list & raw state should be made
1924d14abf15SRobert Mustacchi 	 * atomically (as execution flow assumes they represent the same)
1925d14abf15SRobert Mustacchi 	 */
1926d14abf15SRobert Mustacchi 	ECORE_SPIN_LOCK_BH(&o->exe_queue.lock);
1927d14abf15SRobert Mustacchi 
1928d14abf15SRobert Mustacchi 	/* Reset pending list */
1929d14abf15SRobert Mustacchi 	__ecore_exe_queue_reset_pending(pdev, &o->exe_queue);
1930d14abf15SRobert Mustacchi 
1931d14abf15SRobert Mustacchi 	/* Clear pending */
1932d14abf15SRobert Mustacchi 	r->clear_pending(r);
1933d14abf15SRobert Mustacchi 
1934d14abf15SRobert Mustacchi 	ECORE_SPIN_UNLOCK_BH(&o->exe_queue.lock);
1935d14abf15SRobert Mustacchi 
1936d14abf15SRobert Mustacchi 	/* If ramrod failed this is most likely a SW bug */
1937d14abf15SRobert Mustacchi 	if (cqe->message.error)
1938d14abf15SRobert Mustacchi 		return ECORE_INVAL;
1939d14abf15SRobert Mustacchi 
1940d14abf15SRobert Mustacchi 	/* Run the next bulk of pending commands if requested */
1941d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_CONT, ramrod_flags)) {
1942d14abf15SRobert Mustacchi 		rc = __ecore_vlan_mac_execute_step(pdev, o, ramrod_flags);
1943d14abf15SRobert Mustacchi 		if (rc < 0)
1944d14abf15SRobert Mustacchi 			return rc;
1945d14abf15SRobert Mustacchi 	}
1946d14abf15SRobert Mustacchi 
1947d14abf15SRobert Mustacchi 	/* If there is more work to do return PENDING */
1948d14abf15SRobert Mustacchi 	if (!ecore_exe_queue_empty(&o->exe_queue))
1949d14abf15SRobert Mustacchi 		return ECORE_PENDING;
1950d14abf15SRobert Mustacchi 
1951d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
1952d14abf15SRobert Mustacchi }
1953d14abf15SRobert Mustacchi 
1954d14abf15SRobert Mustacchi /**
1955d14abf15SRobert Mustacchi  * ecore_optimize_vlan_mac - optimize ADD and DEL commands.
1956d14abf15SRobert Mustacchi  *
1957d14abf15SRobert Mustacchi  * @pdev:	device handle
1958d14abf15SRobert Mustacchi  * @o:		ecore_qable_obj
1959d14abf15SRobert Mustacchi  * @elem:	ecore_exeq_elem
1960d14abf15SRobert Mustacchi  */
ecore_optimize_vlan_mac(struct _lm_device_t * pdev,union ecore_qable_obj * qo,struct ecore_exeq_elem * elem)1961d14abf15SRobert Mustacchi static int ecore_optimize_vlan_mac(struct _lm_device_t *pdev,
1962d14abf15SRobert Mustacchi 				   union ecore_qable_obj *qo,
1963d14abf15SRobert Mustacchi 				   struct ecore_exeq_elem *elem)
1964d14abf15SRobert Mustacchi {
1965d14abf15SRobert Mustacchi 	struct ecore_exeq_elem query, *pos;
1966d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *o = &qo->vlan_mac;
1967d14abf15SRobert Mustacchi 	struct ecore_exe_queue_obj *exeq = &o->exe_queue;
1968d14abf15SRobert Mustacchi 
1969d14abf15SRobert Mustacchi 	mm_memcpy(&query, elem, sizeof(query));
1970d14abf15SRobert Mustacchi 
1971d14abf15SRobert Mustacchi 	switch (elem->cmd_data.vlan_mac.cmd) {
1972d14abf15SRobert Mustacchi 	case ECORE_VLAN_MAC_ADD:
1973d14abf15SRobert Mustacchi 		query.cmd_data.vlan_mac.cmd = ECORE_VLAN_MAC_DEL;
1974d14abf15SRobert Mustacchi 		break;
1975d14abf15SRobert Mustacchi 	case ECORE_VLAN_MAC_DEL:
1976d14abf15SRobert Mustacchi 		query.cmd_data.vlan_mac.cmd = ECORE_VLAN_MAC_ADD;
1977d14abf15SRobert Mustacchi 		break;
1978d14abf15SRobert Mustacchi 	default:
1979d14abf15SRobert Mustacchi 		/* Don't handle anything other than ADD or DEL */
1980d14abf15SRobert Mustacchi 		return 0;
1981d14abf15SRobert Mustacchi 	}
1982d14abf15SRobert Mustacchi 
1983d14abf15SRobert Mustacchi 	/* If we found the appropriate element - delete it */
1984d14abf15SRobert Mustacchi 	pos = exeq->get(exeq, &query);
1985d14abf15SRobert Mustacchi 	if (pos) {
1986d14abf15SRobert Mustacchi 
1987d14abf15SRobert Mustacchi 		/* Return the credit of the optimized command */
1988d14abf15SRobert Mustacchi 		if (!ECORE_TEST_BIT(ECORE_DONT_CONSUME_CAM_CREDIT,
1989d14abf15SRobert Mustacchi 				     &pos->cmd_data.vlan_mac.vlan_mac_flags)) {
1990d14abf15SRobert Mustacchi 			if ((query.cmd_data.vlan_mac.cmd ==
1991d14abf15SRobert Mustacchi 			     ECORE_VLAN_MAC_ADD) && !o->put_credit(o)) {
1992d14abf15SRobert Mustacchi 				ECORE_ERR("Failed to return the credit for the optimized ADD command\n");
1993d14abf15SRobert Mustacchi 				return ECORE_INVAL;
1994d14abf15SRobert Mustacchi 			} else if (!o->get_credit(o)) { /* VLAN_MAC_DEL */
1995d14abf15SRobert Mustacchi 				ECORE_ERR("Failed to recover the credit from the optimized DEL command\n");
1996d14abf15SRobert Mustacchi 				return ECORE_INVAL;
1997d14abf15SRobert Mustacchi 			}
1998d14abf15SRobert Mustacchi 		}
1999d14abf15SRobert Mustacchi 
2000d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "Optimizing %s command\n",
2001d14abf15SRobert Mustacchi 			  (elem->cmd_data.vlan_mac.cmd == ECORE_VLAN_MAC_ADD) ?
2002d14abf15SRobert Mustacchi 			  "ADD" : "DEL");
2003d14abf15SRobert Mustacchi 
2004d14abf15SRobert Mustacchi 		ECORE_LIST_REMOVE_ENTRY(&pos->link, &exeq->exe_queue);
2005d14abf15SRobert Mustacchi 		ecore_exe_queue_free_elem(pdev, pos);
2006d14abf15SRobert Mustacchi 		return 1;
2007d14abf15SRobert Mustacchi 	}
2008d14abf15SRobert Mustacchi 
2009d14abf15SRobert Mustacchi 	return 0;
2010d14abf15SRobert Mustacchi }
2011d14abf15SRobert Mustacchi 
2012d14abf15SRobert Mustacchi /**
2013d14abf15SRobert Mustacchi  * ecore_vlan_mac_get_registry_elem - prepare a registry element
2014d14abf15SRobert Mustacchi  *
2015d14abf15SRobert Mustacchi  * @pdev:  device handle
2016d14abf15SRobert Mustacchi  * @o:
2017d14abf15SRobert Mustacchi  * @elem:
2018d14abf15SRobert Mustacchi  * @restore:
2019d14abf15SRobert Mustacchi  * @re:
2020d14abf15SRobert Mustacchi  *
2021d14abf15SRobert Mustacchi  * prepare a registry element according to the current command request.
2022d14abf15SRobert Mustacchi  */
ecore_vlan_mac_get_registry_elem(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,struct ecore_exeq_elem * elem,BOOL restore,struct ecore_vlan_mac_registry_elem ** re)2023d14abf15SRobert Mustacchi static INLINE int ecore_vlan_mac_get_registry_elem(
2024d14abf15SRobert Mustacchi 	struct _lm_device_t *pdev,
2025d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *o,
2026d14abf15SRobert Mustacchi 	struct ecore_exeq_elem *elem,
2027d14abf15SRobert Mustacchi 	BOOL restore,
2028d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem **re)
2029d14abf15SRobert Mustacchi {
2030d14abf15SRobert Mustacchi 	enum ecore_vlan_mac_cmd cmd = elem->cmd_data.vlan_mac.cmd;
2031d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem *reg_elem;
2032d14abf15SRobert Mustacchi 
2033d14abf15SRobert Mustacchi 	/* Allocate a new registry element if needed. */
2034d14abf15SRobert Mustacchi 	if (!restore &&
2035d14abf15SRobert Mustacchi 	    ((cmd == ECORE_VLAN_MAC_ADD) || (cmd == ECORE_VLAN_MAC_MOVE))) {
2036d14abf15SRobert Mustacchi 		reg_elem = ECORE_ZALLOC(sizeof(*reg_elem), GFP_ATOMIC, pdev);
2037d14abf15SRobert Mustacchi 		if (!reg_elem)
2038d14abf15SRobert Mustacchi 			return ECORE_NOMEM;
2039d14abf15SRobert Mustacchi 
2040d14abf15SRobert Mustacchi 		/* Get a new CAM offset */
2041d14abf15SRobert Mustacchi 		if (!o->get_cam_offset(o, &reg_elem->cam_offset)) {
2042d14abf15SRobert Mustacchi 			/* This shall never happen, because we have checked the
2043d14abf15SRobert Mustacchi 			 * CAM availability in the 'validate'.
2044d14abf15SRobert Mustacchi 			 */
2045d14abf15SRobert Mustacchi 			DbgBreakIf(1);
2046d14abf15SRobert Mustacchi 			ECORE_FREE(pdev, reg_elem, sizeof(*reg_elem));
2047d14abf15SRobert Mustacchi 			return ECORE_INVAL;
2048d14abf15SRobert Mustacchi 		}
2049d14abf15SRobert Mustacchi 
2050d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "Got cam offset %d\n", reg_elem->cam_offset);
2051d14abf15SRobert Mustacchi 
2052d14abf15SRobert Mustacchi 		/* Set a VLAN-MAC data */
2053d14abf15SRobert Mustacchi 		mm_memcpy(&reg_elem->u, &elem->cmd_data.vlan_mac.u,
2054d14abf15SRobert Mustacchi 			  sizeof(reg_elem->u));
2055d14abf15SRobert Mustacchi 
2056d14abf15SRobert Mustacchi 		/* Copy the flags (needed for DEL and RESTORE flows) */
2057d14abf15SRobert Mustacchi 		reg_elem->vlan_mac_flags =
2058d14abf15SRobert Mustacchi 			elem->cmd_data.vlan_mac.vlan_mac_flags;
2059d14abf15SRobert Mustacchi 	} else /* DEL, RESTORE */
2060d14abf15SRobert Mustacchi 		reg_elem = o->check_del(pdev, o, &elem->cmd_data.vlan_mac.u);
2061d14abf15SRobert Mustacchi 
2062d14abf15SRobert Mustacchi 	*re = reg_elem;
2063d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
2064d14abf15SRobert Mustacchi }
2065d14abf15SRobert Mustacchi 
2066d14abf15SRobert Mustacchi /**
2067d14abf15SRobert Mustacchi  * ecore_execute_vlan_mac - execute vlan mac command
2068d14abf15SRobert Mustacchi  *
2069d14abf15SRobert Mustacchi  * @pdev:		device handle
2070d14abf15SRobert Mustacchi  * @qo:
2071d14abf15SRobert Mustacchi  * @exe_chunk:
2072d14abf15SRobert Mustacchi  * @ramrod_flags:
2073d14abf15SRobert Mustacchi  *
2074d14abf15SRobert Mustacchi  * go and send a ramrod!
2075d14abf15SRobert Mustacchi  */
ecore_execute_vlan_mac(struct _lm_device_t * pdev,union ecore_qable_obj * qo,d_list_t * exe_chunk,unsigned long * ramrod_flags)2076d14abf15SRobert Mustacchi static int ecore_execute_vlan_mac(struct _lm_device_t *pdev,
2077d14abf15SRobert Mustacchi 				  union ecore_qable_obj *qo,
2078d14abf15SRobert Mustacchi 				  d_list_t *exe_chunk,
2079d14abf15SRobert Mustacchi 				  unsigned long *ramrod_flags)
2080d14abf15SRobert Mustacchi {
2081d14abf15SRobert Mustacchi 	struct ecore_exeq_elem *elem;
2082d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *o = &qo->vlan_mac, *cam_obj;
2083d14abf15SRobert Mustacchi 	struct ecore_raw_obj *r = &o->raw;
2084d14abf15SRobert Mustacchi 	int rc, idx = 0;
2085d14abf15SRobert Mustacchi 	BOOL restore = ECORE_TEST_BIT(RAMROD_RESTORE, ramrod_flags);
2086d14abf15SRobert Mustacchi 	BOOL drv_only = ECORE_TEST_BIT(RAMROD_DRV_CLR_ONLY, ramrod_flags);
2087d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem *reg_elem;
2088d14abf15SRobert Mustacchi 	enum ecore_vlan_mac_cmd cmd;
2089d14abf15SRobert Mustacchi 
2090d14abf15SRobert Mustacchi 	/* If DRIVER_ONLY execution is requested, cleanup a registry
2091d14abf15SRobert Mustacchi 	 * and exit. Otherwise send a ramrod to FW.
2092d14abf15SRobert Mustacchi 	 */
2093d14abf15SRobert Mustacchi 	if (!drv_only) {
2094d14abf15SRobert Mustacchi 		DbgBreakIf(r->check_pending(r));
2095d14abf15SRobert Mustacchi 
2096d14abf15SRobert Mustacchi 		/* Set pending */
2097d14abf15SRobert Mustacchi 		r->set_pending(r);
2098d14abf15SRobert Mustacchi 
2099d14abf15SRobert Mustacchi 		/* Fill the ramrod data */
2100d14abf15SRobert Mustacchi 		ECORE_LIST_FOR_EACH_ENTRY(elem, exe_chunk, link,
2101d14abf15SRobert Mustacchi 					  struct ecore_exeq_elem) {
2102d14abf15SRobert Mustacchi 			cmd = elem->cmd_data.vlan_mac.cmd;
2103d14abf15SRobert Mustacchi 			/* We will add to the target object in MOVE command, so
2104d14abf15SRobert Mustacchi 			 * change the object for a CAM search.
2105d14abf15SRobert Mustacchi 			 */
2106d14abf15SRobert Mustacchi 			if (cmd == ECORE_VLAN_MAC_MOVE)
2107d14abf15SRobert Mustacchi 				cam_obj = elem->cmd_data.vlan_mac.target_obj;
2108d14abf15SRobert Mustacchi 			else
2109d14abf15SRobert Mustacchi 				cam_obj = o;
2110d14abf15SRobert Mustacchi 
2111d14abf15SRobert Mustacchi 			rc = ecore_vlan_mac_get_registry_elem(pdev, cam_obj,
2112d14abf15SRobert Mustacchi 							      elem, restore,
2113d14abf15SRobert Mustacchi 							      &reg_elem);
2114d14abf15SRobert Mustacchi 			if (rc)
2115d14abf15SRobert Mustacchi 				goto error_exit;
2116d14abf15SRobert Mustacchi 
2117d14abf15SRobert Mustacchi 			DbgBreakIf(!reg_elem);
2118d14abf15SRobert Mustacchi 
2119d14abf15SRobert Mustacchi 			/* Push a new entry into the registry */
2120d14abf15SRobert Mustacchi 			if (!restore &&
2121d14abf15SRobert Mustacchi 			    ((cmd == ECORE_VLAN_MAC_ADD) ||
2122d14abf15SRobert Mustacchi 			    (cmd == ECORE_VLAN_MAC_MOVE)))
2123d14abf15SRobert Mustacchi 				ECORE_LIST_PUSH_HEAD(&reg_elem->link,
2124d14abf15SRobert Mustacchi 						     &cam_obj->head);
2125d14abf15SRobert Mustacchi 
2126d14abf15SRobert Mustacchi 			/* Configure a single command in a ramrod data buffer */
2127d14abf15SRobert Mustacchi 			o->set_one_rule(pdev, o, elem, idx,
2128d14abf15SRobert Mustacchi 					reg_elem->cam_offset);
2129d14abf15SRobert Mustacchi 
2130d14abf15SRobert Mustacchi 			/* MOVE command consumes 2 entries in the ramrod data */
2131d14abf15SRobert Mustacchi 			if (cmd == ECORE_VLAN_MAC_MOVE)
2132d14abf15SRobert Mustacchi 				idx += 2;
2133d14abf15SRobert Mustacchi 			else
2134d14abf15SRobert Mustacchi 				idx++;
2135d14abf15SRobert Mustacchi 		}
2136d14abf15SRobert Mustacchi 
2137d14abf15SRobert Mustacchi 		/* No need for an explicit memory barrier here as long as we
2138d14abf15SRobert Mustacchi 		 * ensure the ordering of writing to the SPQ element
2139d14abf15SRobert Mustacchi 		 * and updating of the SPQ producer which involves a memory
2140d14abf15SRobert Mustacchi 		 * read. If the memory read is removed we will have to put a
2141d14abf15SRobert Mustacchi 		 * full memory barrier there (inside ecore_sp_post()).
2142d14abf15SRobert Mustacchi 		 */
2143d14abf15SRobert Mustacchi 		rc = ecore_sp_post(pdev, o->ramrod_cmd, r->cid,
2144d14abf15SRobert Mustacchi 				   r->rdata_mapping.as_u64,
2145d14abf15SRobert Mustacchi 				   ETH_CONNECTION_TYPE);
2146d14abf15SRobert Mustacchi 		if (rc)
2147d14abf15SRobert Mustacchi 			goto error_exit;
2148d14abf15SRobert Mustacchi 	}
2149d14abf15SRobert Mustacchi 
2150d14abf15SRobert Mustacchi 	/* Now, when we are done with the ramrod - clean up the registry */
2151d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(elem, exe_chunk, link,
2152d14abf15SRobert Mustacchi 				  struct ecore_exeq_elem) {
2153d14abf15SRobert Mustacchi 		cmd = elem->cmd_data.vlan_mac.cmd;
2154d14abf15SRobert Mustacchi 		if ((cmd == ECORE_VLAN_MAC_DEL) ||
2155d14abf15SRobert Mustacchi 		    (cmd == ECORE_VLAN_MAC_MOVE)) {
2156d14abf15SRobert Mustacchi 			reg_elem = o->check_del(pdev, o,
2157d14abf15SRobert Mustacchi 						&elem->cmd_data.vlan_mac.u);
2158d14abf15SRobert Mustacchi 
2159d14abf15SRobert Mustacchi 			DbgBreakIf(!reg_elem);
2160d14abf15SRobert Mustacchi 
2161d14abf15SRobert Mustacchi 			o->put_cam_offset(o, reg_elem->cam_offset);
2162d14abf15SRobert Mustacchi 			ECORE_LIST_REMOVE_ENTRY(&reg_elem->link, &o->head);
2163d14abf15SRobert Mustacchi 			ECORE_FREE(pdev, reg_elem, sizeof(*reg_elem));
2164d14abf15SRobert Mustacchi 		}
2165d14abf15SRobert Mustacchi 	}
2166d14abf15SRobert Mustacchi 
2167d14abf15SRobert Mustacchi 	if (!drv_only)
2168d14abf15SRobert Mustacchi 		return ECORE_PENDING;
2169d14abf15SRobert Mustacchi 	else
2170d14abf15SRobert Mustacchi 		return ECORE_SUCCESS;
2171d14abf15SRobert Mustacchi 
2172d14abf15SRobert Mustacchi error_exit:
2173d14abf15SRobert Mustacchi 	r->clear_pending(r);
2174d14abf15SRobert Mustacchi 
2175d14abf15SRobert Mustacchi 	/* Cleanup a registry in case of a failure */
2176d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(elem, exe_chunk, link,
2177d14abf15SRobert Mustacchi 				  struct ecore_exeq_elem) {
2178d14abf15SRobert Mustacchi 		cmd = elem->cmd_data.vlan_mac.cmd;
2179d14abf15SRobert Mustacchi 
2180d14abf15SRobert Mustacchi 		if (cmd == ECORE_VLAN_MAC_MOVE)
2181d14abf15SRobert Mustacchi 			cam_obj = elem->cmd_data.vlan_mac.target_obj;
2182d14abf15SRobert Mustacchi 		else
2183d14abf15SRobert Mustacchi 			cam_obj = o;
2184d14abf15SRobert Mustacchi 
2185d14abf15SRobert Mustacchi 		/* Delete all newly added above entries */
2186d14abf15SRobert Mustacchi 		if (!restore &&
2187d14abf15SRobert Mustacchi 		    ((cmd == ECORE_VLAN_MAC_ADD) ||
2188d14abf15SRobert Mustacchi 		    (cmd == ECORE_VLAN_MAC_MOVE))) {
2189d14abf15SRobert Mustacchi 			reg_elem = o->check_del(pdev, cam_obj,
2190d14abf15SRobert Mustacchi 						&elem->cmd_data.vlan_mac.u);
2191d14abf15SRobert Mustacchi 			if (reg_elem) {
2192d14abf15SRobert Mustacchi 				ECORE_LIST_REMOVE_ENTRY(&reg_elem->link,
2193d14abf15SRobert Mustacchi 							&cam_obj->head);
2194d14abf15SRobert Mustacchi 				ECORE_FREE(pdev, reg_elem, sizeof(*reg_elem));
2195d14abf15SRobert Mustacchi 			}
2196d14abf15SRobert Mustacchi 		}
2197d14abf15SRobert Mustacchi 	}
2198d14abf15SRobert Mustacchi 
2199d14abf15SRobert Mustacchi 	return rc;
2200d14abf15SRobert Mustacchi }
2201d14abf15SRobert Mustacchi 
ecore_vlan_mac_push_new_cmd(struct _lm_device_t * pdev,struct ecore_vlan_mac_ramrod_params * p)2202d14abf15SRobert Mustacchi static INLINE int ecore_vlan_mac_push_new_cmd(
2203d14abf15SRobert Mustacchi 	struct _lm_device_t *pdev,
2204d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_ramrod_params *p)
2205d14abf15SRobert Mustacchi {
2206d14abf15SRobert Mustacchi 	struct ecore_exeq_elem *elem;
2207d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *o = p->vlan_mac_obj;
2208d14abf15SRobert Mustacchi 	BOOL restore = ECORE_TEST_BIT(RAMROD_RESTORE, &p->ramrod_flags);
2209d14abf15SRobert Mustacchi 
2210d14abf15SRobert Mustacchi 	/* Allocate the execution queue element */
2211d14abf15SRobert Mustacchi 	elem = ecore_exe_queue_alloc_elem(pdev);
2212d14abf15SRobert Mustacchi 	if (!elem)
2213d14abf15SRobert Mustacchi 		return ECORE_NOMEM;
2214d14abf15SRobert Mustacchi 
2215d14abf15SRobert Mustacchi 	/* Set the command 'length' */
2216d14abf15SRobert Mustacchi 	switch (p->user_req.cmd) {
2217d14abf15SRobert Mustacchi 	case ECORE_VLAN_MAC_MOVE:
2218d14abf15SRobert Mustacchi 		elem->cmd_len = 2;
2219d14abf15SRobert Mustacchi 		break;
2220d14abf15SRobert Mustacchi 	default:
2221d14abf15SRobert Mustacchi 		elem->cmd_len = 1;
2222d14abf15SRobert Mustacchi 	}
2223d14abf15SRobert Mustacchi 
2224d14abf15SRobert Mustacchi 	/* Fill the object specific info */
2225d14abf15SRobert Mustacchi 	mm_memcpy(&elem->cmd_data.vlan_mac, &p->user_req, sizeof(p->user_req));
2226d14abf15SRobert Mustacchi 
2227d14abf15SRobert Mustacchi 	/* Try to add a new command to the pending list */
2228d14abf15SRobert Mustacchi 	return ecore_exe_queue_add(pdev, &o->exe_queue, elem, restore);
2229d14abf15SRobert Mustacchi }
2230d14abf15SRobert Mustacchi 
2231d14abf15SRobert Mustacchi /**
2232d14abf15SRobert Mustacchi  * ecore_config_vlan_mac - configure VLAN/MAC/VLAN_MAC filtering rules.
2233d14abf15SRobert Mustacchi  *
2234d14abf15SRobert Mustacchi  * @pdev:  device handle
2235d14abf15SRobert Mustacchi  * @p:
2236d14abf15SRobert Mustacchi  *
2237d14abf15SRobert Mustacchi  */
ecore_config_vlan_mac(struct _lm_device_t * pdev,struct ecore_vlan_mac_ramrod_params * p)2238d14abf15SRobert Mustacchi int ecore_config_vlan_mac(struct _lm_device_t *pdev,
2239d14abf15SRobert Mustacchi 			   struct ecore_vlan_mac_ramrod_params *p)
2240d14abf15SRobert Mustacchi {
2241d14abf15SRobert Mustacchi 	int rc = ECORE_SUCCESS;
2242d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj *o = p->vlan_mac_obj;
2243d14abf15SRobert Mustacchi 	unsigned long *ramrod_flags = &p->ramrod_flags;
2244d14abf15SRobert Mustacchi 	BOOL cont = ECORE_TEST_BIT(RAMROD_CONT, ramrod_flags);
2245d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &o->raw;
2246d14abf15SRobert Mustacchi 
2247d14abf15SRobert Mustacchi 	/*
2248d14abf15SRobert Mustacchi 	 * Add new elements to the execution list for commands that require it.
2249d14abf15SRobert Mustacchi 	 */
2250d14abf15SRobert Mustacchi 	if (!cont) {
2251d14abf15SRobert Mustacchi 		rc = ecore_vlan_mac_push_new_cmd(pdev, p);
2252d14abf15SRobert Mustacchi 		if (rc)
2253d14abf15SRobert Mustacchi 			return rc;
2254d14abf15SRobert Mustacchi 	}
2255d14abf15SRobert Mustacchi 
2256d14abf15SRobert Mustacchi 	/* If nothing will be executed further in this iteration we want to
2257d14abf15SRobert Mustacchi 	 * return PENDING if there are pending commands
2258d14abf15SRobert Mustacchi 	 */
2259d14abf15SRobert Mustacchi 	if (!ecore_exe_queue_empty(&o->exe_queue))
2260d14abf15SRobert Mustacchi 		rc = ECORE_PENDING;
2261d14abf15SRobert Mustacchi 
2262d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_DRV_CLR_ONLY, ramrod_flags))  {
2263d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "RAMROD_DRV_CLR_ONLY requested: clearing a pending bit.\n");
2264d14abf15SRobert Mustacchi 		raw->clear_pending(raw);
2265d14abf15SRobert Mustacchi 	}
2266d14abf15SRobert Mustacchi 
2267d14abf15SRobert Mustacchi 	/* Execute commands if required */
2268d14abf15SRobert Mustacchi 	if (cont || ECORE_TEST_BIT(RAMROD_EXEC, ramrod_flags) ||
2269d14abf15SRobert Mustacchi 	    ECORE_TEST_BIT(RAMROD_COMP_WAIT, ramrod_flags)) {
2270d14abf15SRobert Mustacchi 		rc = __ecore_vlan_mac_execute_step(pdev, p->vlan_mac_obj,
2271d14abf15SRobert Mustacchi 						   &p->ramrod_flags);
2272d14abf15SRobert Mustacchi 		if (rc < 0)
2273d14abf15SRobert Mustacchi 			return rc;
2274d14abf15SRobert Mustacchi 	}
2275d14abf15SRobert Mustacchi 
2276d14abf15SRobert Mustacchi 	/* RAMROD_COMP_WAIT is a superset of RAMROD_EXEC. If it was set
2277d14abf15SRobert Mustacchi 	 * then user want to wait until the last command is done.
2278d14abf15SRobert Mustacchi 	 */
2279d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_COMP_WAIT, &p->ramrod_flags)) {
2280d14abf15SRobert Mustacchi 		/* Wait maximum for the current exe_queue length iterations plus
2281d14abf15SRobert Mustacchi 		 * one (for the current pending command).
2282d14abf15SRobert Mustacchi 		 */
2283d14abf15SRobert Mustacchi 		int max_iterations = ecore_exe_queue_length(&o->exe_queue) + 1;
2284d14abf15SRobert Mustacchi 
2285d14abf15SRobert Mustacchi 		while (!ecore_exe_queue_empty(&o->exe_queue) &&
2286d14abf15SRobert Mustacchi 		       max_iterations--) {
2287d14abf15SRobert Mustacchi 
2288d14abf15SRobert Mustacchi 			/* Wait for the current command to complete */
2289d14abf15SRobert Mustacchi 			rc = raw->wait_comp(pdev, raw);
2290d14abf15SRobert Mustacchi 			if (rc)
2291d14abf15SRobert Mustacchi 				return rc;
2292d14abf15SRobert Mustacchi 
2293d14abf15SRobert Mustacchi 			/* Make a next step */
2294d14abf15SRobert Mustacchi 			rc = __ecore_vlan_mac_execute_step(pdev,
2295d14abf15SRobert Mustacchi 							   p->vlan_mac_obj,
2296d14abf15SRobert Mustacchi 							   &p->ramrod_flags);
2297d14abf15SRobert Mustacchi 			if (rc < 0)
2298d14abf15SRobert Mustacchi 				return rc;
2299d14abf15SRobert Mustacchi 		}
2300d14abf15SRobert Mustacchi 
2301d14abf15SRobert Mustacchi 		return ECORE_SUCCESS;
2302d14abf15SRobert Mustacchi 	}
2303d14abf15SRobert Mustacchi 
2304d14abf15SRobert Mustacchi 	return rc;
2305d14abf15SRobert Mustacchi }
2306d14abf15SRobert Mustacchi 
2307d14abf15SRobert Mustacchi /**
2308d14abf15SRobert Mustacchi  * ecore_vlan_mac_del_all - delete elements with given vlan_mac_flags spec
2309d14abf15SRobert Mustacchi  *
2310d14abf15SRobert Mustacchi  * @pdev:		device handle
2311d14abf15SRobert Mustacchi  * @o:
2312d14abf15SRobert Mustacchi  * @vlan_mac_flags:
2313d14abf15SRobert Mustacchi  * @ramrod_flags:	execution flags to be used for this deletion
2314d14abf15SRobert Mustacchi  *
2315d14abf15SRobert Mustacchi  * if the last operation has completed successfully and there are no
2316d14abf15SRobert Mustacchi  * more elements left, positive value if the last operation has completed
2317d14abf15SRobert Mustacchi  * successfully and there are more previously configured elements, negative
2318d14abf15SRobert Mustacchi  * value is current operation has failed.
2319d14abf15SRobert Mustacchi  */
ecore_vlan_mac_del_all(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * o,unsigned long * vlan_mac_flags,unsigned long * ramrod_flags)2320d14abf15SRobert Mustacchi static int ecore_vlan_mac_del_all(struct _lm_device_t *pdev,
2321d14abf15SRobert Mustacchi 				  struct ecore_vlan_mac_obj *o,
2322d14abf15SRobert Mustacchi 				  unsigned long *vlan_mac_flags,
2323d14abf15SRobert Mustacchi 				  unsigned long *ramrod_flags)
2324d14abf15SRobert Mustacchi {
2325d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_registry_elem *pos = NULL;
2326d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_ramrod_params p;
2327d14abf15SRobert Mustacchi 	struct ecore_exe_queue_obj *exeq = &o->exe_queue;
2328d14abf15SRobert Mustacchi 	struct ecore_exeq_elem *exeq_pos, *exeq_pos_n;
2329d14abf15SRobert Mustacchi 	unsigned long flags;
2330d14abf15SRobert Mustacchi 	int read_lock;
2331d14abf15SRobert Mustacchi 	int rc = 0;
2332d14abf15SRobert Mustacchi 
2333d14abf15SRobert Mustacchi 	/* Clear pending commands first */
2334d14abf15SRobert Mustacchi 
2335d14abf15SRobert Mustacchi 	ECORE_SPIN_LOCK_BH(&exeq->lock);
2336d14abf15SRobert Mustacchi 
2337d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY_SAFE(exeq_pos, exeq_pos_n,
2338d14abf15SRobert Mustacchi 				       &exeq->exe_queue, link,
2339d14abf15SRobert Mustacchi 				       struct ecore_exeq_elem) {
2340d14abf15SRobert Mustacchi 		flags = exeq_pos->cmd_data.vlan_mac.vlan_mac_flags;
2341d14abf15SRobert Mustacchi 		if (ECORE_VLAN_MAC_CMP_FLAGS(flags) ==
2342d14abf15SRobert Mustacchi 		    ECORE_VLAN_MAC_CMP_FLAGS(*vlan_mac_flags)) {
2343d14abf15SRobert Mustacchi 			rc = exeq->remove(pdev, exeq->owner, exeq_pos);
2344d14abf15SRobert Mustacchi 			if (rc) {
2345d14abf15SRobert Mustacchi 				ECORE_ERR("Failed to remove command\n");
2346d14abf15SRobert Mustacchi 				ECORE_SPIN_UNLOCK_BH(&exeq->lock);
2347d14abf15SRobert Mustacchi 				return rc;
2348d14abf15SRobert Mustacchi 			}
2349d14abf15SRobert Mustacchi 			ECORE_LIST_REMOVE_ENTRY(&exeq_pos->link,
2350d14abf15SRobert Mustacchi 						&exeq->exe_queue);
2351d14abf15SRobert Mustacchi 			ecore_exe_queue_free_elem(pdev, exeq_pos);
2352d14abf15SRobert Mustacchi 		}
2353d14abf15SRobert Mustacchi 	}
2354d14abf15SRobert Mustacchi 
2355d14abf15SRobert Mustacchi 	ECORE_SPIN_UNLOCK_BH(&exeq->lock);
2356d14abf15SRobert Mustacchi 
2357d14abf15SRobert Mustacchi 	/* Prepare a command request */
2358d14abf15SRobert Mustacchi 	mm_memset(&p, 0, sizeof(p));
2359d14abf15SRobert Mustacchi 	p.vlan_mac_obj = o;
2360d14abf15SRobert Mustacchi 	p.ramrod_flags = *ramrod_flags;
2361d14abf15SRobert Mustacchi 	p.user_req.cmd = ECORE_VLAN_MAC_DEL;
2362d14abf15SRobert Mustacchi 
2363d14abf15SRobert Mustacchi 	/* Add all but the last VLAN-MAC to the execution queue without actually
2364d14abf15SRobert Mustacchi 	 * execution anything.
2365d14abf15SRobert Mustacchi 	 */
2366d14abf15SRobert Mustacchi 	ECORE_CLEAR_BIT_NA(RAMROD_COMP_WAIT, &p.ramrod_flags);
2367d14abf15SRobert Mustacchi 	ECORE_CLEAR_BIT_NA(RAMROD_EXEC, &p.ramrod_flags);
2368d14abf15SRobert Mustacchi 	ECORE_CLEAR_BIT_NA(RAMROD_CONT, &p.ramrod_flags);
2369d14abf15SRobert Mustacchi 
2370d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "vlan_mac_del_all -- taking vlan_mac_lock (reader)\n");
2371d14abf15SRobert Mustacchi 	read_lock = ecore_vlan_mac_h_read_lock(pdev, o);
2372d14abf15SRobert Mustacchi 	if (read_lock != ECORE_SUCCESS)
2373d14abf15SRobert Mustacchi 		return read_lock;
2374d14abf15SRobert Mustacchi 
2375d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(pos, &o->head, link,
2376d14abf15SRobert Mustacchi 				  struct ecore_vlan_mac_registry_elem) {
2377d14abf15SRobert Mustacchi 		flags = pos->vlan_mac_flags;
2378d14abf15SRobert Mustacchi 		if (ECORE_VLAN_MAC_CMP_FLAGS(flags) ==
2379d14abf15SRobert Mustacchi 		    ECORE_VLAN_MAC_CMP_FLAGS(*vlan_mac_flags)) {
2380d14abf15SRobert Mustacchi 			p.user_req.vlan_mac_flags = pos->vlan_mac_flags;
2381d14abf15SRobert Mustacchi 			mm_memcpy(&p.user_req.u, &pos->u, sizeof(pos->u));
2382d14abf15SRobert Mustacchi 			rc = ecore_config_vlan_mac(pdev, &p);
2383d14abf15SRobert Mustacchi 			if (rc < 0) {
2384d14abf15SRobert Mustacchi 				ECORE_ERR("Failed to add a new DEL command\n");
2385d14abf15SRobert Mustacchi 				ecore_vlan_mac_h_read_unlock(pdev, o);
2386d14abf15SRobert Mustacchi 				return rc;
2387d14abf15SRobert Mustacchi 			}
2388d14abf15SRobert Mustacchi 		}
2389d14abf15SRobert Mustacchi 	}
2390d14abf15SRobert Mustacchi 
2391d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "vlan_mac_del_all -- releasing vlan_mac_lock (reader)\n");
2392d14abf15SRobert Mustacchi 	ecore_vlan_mac_h_read_unlock(pdev, o);
2393d14abf15SRobert Mustacchi 
2394d14abf15SRobert Mustacchi 	p.ramrod_flags = *ramrod_flags;
2395d14abf15SRobert Mustacchi 	ECORE_SET_BIT_NA(RAMROD_CONT, &p.ramrod_flags);
2396d14abf15SRobert Mustacchi 
2397d14abf15SRobert Mustacchi 	return ecore_config_vlan_mac(pdev, &p);
2398d14abf15SRobert Mustacchi }
2399d14abf15SRobert Mustacchi 
ecore_init_raw_obj(struct ecore_raw_obj * raw,u8 cl_id,u32 cid,u8 func_id,void * rdata,lm_address_t rdata_mapping,int state,unsigned long * pstate,ecore_obj_type type)2400d14abf15SRobert Mustacchi static INLINE void ecore_init_raw_obj(struct ecore_raw_obj *raw, u8 cl_id,
2401d14abf15SRobert Mustacchi 	u32 cid, u8 func_id, void *rdata, lm_address_t rdata_mapping, int state,
2402d14abf15SRobert Mustacchi 	unsigned long *pstate, ecore_obj_type type)
2403d14abf15SRobert Mustacchi {
2404d14abf15SRobert Mustacchi 	raw->func_id = func_id;
2405d14abf15SRobert Mustacchi 	raw->cid = cid;
2406d14abf15SRobert Mustacchi 	raw->cl_id = cl_id;
2407d14abf15SRobert Mustacchi 	raw->rdata = rdata;
2408d14abf15SRobert Mustacchi 	raw->rdata_mapping = rdata_mapping;
2409d14abf15SRobert Mustacchi 	raw->state = state;
2410d14abf15SRobert Mustacchi 	raw->pstate = pstate;
2411d14abf15SRobert Mustacchi 	raw->obj_type = type;
2412d14abf15SRobert Mustacchi 	raw->check_pending = ecore_raw_check_pending;
2413d14abf15SRobert Mustacchi 	raw->clear_pending = ecore_raw_clear_pending;
2414d14abf15SRobert Mustacchi 	raw->set_pending = ecore_raw_set_pending;
2415d14abf15SRobert Mustacchi 	raw->wait_comp = ecore_raw_wait;
2416d14abf15SRobert Mustacchi }
2417d14abf15SRobert Mustacchi 
ecore_init_vlan_mac_common(struct ecore_vlan_mac_obj * o,u8 cl_id,u32 cid,u8 func_id,void * rdata,lm_address_t rdata_mapping,int state,unsigned long * pstate,ecore_obj_type type,struct ecore_credit_pool_obj * macs_pool,struct ecore_credit_pool_obj * vlans_pool)2418d14abf15SRobert Mustacchi static INLINE void ecore_init_vlan_mac_common(struct ecore_vlan_mac_obj *o,
2419d14abf15SRobert Mustacchi 	u8 cl_id, u32 cid, u8 func_id, void *rdata, lm_address_t rdata_mapping,
2420d14abf15SRobert Mustacchi 	int state, unsigned long *pstate, ecore_obj_type type,
2421d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *macs_pool,
2422d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *vlans_pool)
2423d14abf15SRobert Mustacchi {
2424d14abf15SRobert Mustacchi 	ECORE_LIST_INIT(&o->head);
2425d14abf15SRobert Mustacchi 	o->head_reader = 0;
2426d14abf15SRobert Mustacchi 	o->head_exe_request = FALSE;
2427d14abf15SRobert Mustacchi 	o->saved_ramrod_flags = 0;
2428d14abf15SRobert Mustacchi 
2429d14abf15SRobert Mustacchi 	o->macs_pool = macs_pool;
2430d14abf15SRobert Mustacchi 	o->vlans_pool = vlans_pool;
2431d14abf15SRobert Mustacchi 
2432d14abf15SRobert Mustacchi 	o->delete_all = ecore_vlan_mac_del_all;
2433d14abf15SRobert Mustacchi 	o->restore = ecore_vlan_mac_restore;
2434d14abf15SRobert Mustacchi 	o->complete = ecore_complete_vlan_mac;
2435d14abf15SRobert Mustacchi 	o->wait = ecore_wait_vlan_mac;
2436d14abf15SRobert Mustacchi 
2437d14abf15SRobert Mustacchi 	ecore_init_raw_obj(&o->raw, cl_id, cid, func_id, rdata, rdata_mapping,
2438d14abf15SRobert Mustacchi 			   state, pstate, type);
2439d14abf15SRobert Mustacchi }
2440d14abf15SRobert Mustacchi 
ecore_init_mac_obj(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * mac_obj,u8 cl_id,u32 cid,u8 func_id,void * rdata,lm_address_t rdata_mapping,int state,unsigned long * pstate,ecore_obj_type type,struct ecore_credit_pool_obj * macs_pool)2441d14abf15SRobert Mustacchi void ecore_init_mac_obj(struct _lm_device_t *pdev,
2442d14abf15SRobert Mustacchi 			struct ecore_vlan_mac_obj *mac_obj,
2443d14abf15SRobert Mustacchi 			u8 cl_id, u32 cid, u8 func_id, void *rdata,
2444d14abf15SRobert Mustacchi 			lm_address_t rdata_mapping, int state,
2445d14abf15SRobert Mustacchi 			unsigned long *pstate, ecore_obj_type type,
2446d14abf15SRobert Mustacchi 			struct ecore_credit_pool_obj *macs_pool)
2447d14abf15SRobert Mustacchi {
2448d14abf15SRobert Mustacchi 	union ecore_qable_obj *qable_obj = (union ecore_qable_obj *)mac_obj;
2449d14abf15SRobert Mustacchi 
2450d14abf15SRobert Mustacchi 	ecore_init_vlan_mac_common(mac_obj, cl_id, cid, func_id, rdata,
2451d14abf15SRobert Mustacchi 				   rdata_mapping, state, pstate, type,
2452d14abf15SRobert Mustacchi 				   macs_pool, NULL);
2453d14abf15SRobert Mustacchi 
2454d14abf15SRobert Mustacchi 	/* CAM credit pool handling */
2455d14abf15SRobert Mustacchi 	mac_obj->get_credit = ecore_get_credit_mac;
2456d14abf15SRobert Mustacchi 	mac_obj->put_credit = ecore_put_credit_mac;
2457d14abf15SRobert Mustacchi 	mac_obj->get_cam_offset = ecore_get_cam_offset_mac;
2458d14abf15SRobert Mustacchi 	mac_obj->put_cam_offset = ecore_put_cam_offset_mac;
2459d14abf15SRobert Mustacchi 
2460d14abf15SRobert Mustacchi 	if (CHIP_IS_E1x(pdev)) {
2461d14abf15SRobert Mustacchi 		mac_obj->set_one_rule      = ecore_set_one_mac_e1x;
2462d14abf15SRobert Mustacchi 		mac_obj->check_del         = ecore_check_mac_del;
2463d14abf15SRobert Mustacchi 		mac_obj->check_add         = ecore_check_mac_add;
2464d14abf15SRobert Mustacchi 		mac_obj->check_move        = ecore_check_move_always_err;
2465d14abf15SRobert Mustacchi 		mac_obj->ramrod_cmd        = RAMROD_CMD_ID_ETH_SET_MAC;
2466d14abf15SRobert Mustacchi 
2467d14abf15SRobert Mustacchi 		/* Exe Queue */
2468d14abf15SRobert Mustacchi 		ecore_exe_queue_init(pdev,
2469d14abf15SRobert Mustacchi 				     &mac_obj->exe_queue, 1, qable_obj,
2470d14abf15SRobert Mustacchi 				     ecore_validate_vlan_mac,
2471d14abf15SRobert Mustacchi 				     ecore_remove_vlan_mac,
2472d14abf15SRobert Mustacchi 				     ecore_optimize_vlan_mac,
2473d14abf15SRobert Mustacchi 				     ecore_execute_vlan_mac,
2474d14abf15SRobert Mustacchi 				     ecore_exeq_get_mac);
2475d14abf15SRobert Mustacchi 	} else {
2476d14abf15SRobert Mustacchi 		mac_obj->set_one_rule      = ecore_set_one_mac_e2;
2477d14abf15SRobert Mustacchi 		mac_obj->check_del         = ecore_check_mac_del;
2478d14abf15SRobert Mustacchi 		mac_obj->check_add         = ecore_check_mac_add;
2479d14abf15SRobert Mustacchi 		mac_obj->check_move        = ecore_check_move;
2480d14abf15SRobert Mustacchi 		mac_obj->ramrod_cmd        =
2481d14abf15SRobert Mustacchi 			RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES;
2482d14abf15SRobert Mustacchi 		mac_obj->get_n_elements    = ecore_get_n_elements;
2483d14abf15SRobert Mustacchi 
2484d14abf15SRobert Mustacchi 		/* Exe Queue */
2485d14abf15SRobert Mustacchi 		ecore_exe_queue_init(pdev,
2486d14abf15SRobert Mustacchi 				     &mac_obj->exe_queue, CLASSIFY_RULES_COUNT,
2487d14abf15SRobert Mustacchi 				     qable_obj, ecore_validate_vlan_mac,
2488d14abf15SRobert Mustacchi 				     ecore_remove_vlan_mac,
2489d14abf15SRobert Mustacchi 				     ecore_optimize_vlan_mac,
2490d14abf15SRobert Mustacchi 				     ecore_execute_vlan_mac,
2491d14abf15SRobert Mustacchi 				     ecore_exeq_get_mac);
2492d14abf15SRobert Mustacchi 	}
2493d14abf15SRobert Mustacchi }
2494d14abf15SRobert Mustacchi 
ecore_init_vlan_obj(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * vlan_obj,u8 cl_id,u32 cid,u8 func_id,void * rdata,lm_address_t rdata_mapping,int state,unsigned long * pstate,ecore_obj_type type,struct ecore_credit_pool_obj * vlans_pool)2495d14abf15SRobert Mustacchi void ecore_init_vlan_obj(struct _lm_device_t *pdev,
2496d14abf15SRobert Mustacchi 			 struct ecore_vlan_mac_obj *vlan_obj,
2497d14abf15SRobert Mustacchi 			 u8 cl_id, u32 cid, u8 func_id, void *rdata,
2498d14abf15SRobert Mustacchi 			 lm_address_t rdata_mapping, int state,
2499d14abf15SRobert Mustacchi 			 unsigned long *pstate, ecore_obj_type type,
2500d14abf15SRobert Mustacchi 			 struct ecore_credit_pool_obj *vlans_pool)
2501d14abf15SRobert Mustacchi {
2502d14abf15SRobert Mustacchi 	union ecore_qable_obj *qable_obj = (union ecore_qable_obj *)vlan_obj;
2503d14abf15SRobert Mustacchi 
2504d14abf15SRobert Mustacchi 	ecore_init_vlan_mac_common(vlan_obj, cl_id, cid, func_id, rdata,
2505d14abf15SRobert Mustacchi 				   rdata_mapping, state, pstate, type, NULL,
2506d14abf15SRobert Mustacchi 				   vlans_pool);
2507d14abf15SRobert Mustacchi 
2508d14abf15SRobert Mustacchi 	vlan_obj->get_credit = ecore_get_credit_vlan;
2509d14abf15SRobert Mustacchi 	vlan_obj->put_credit = ecore_put_credit_vlan;
2510d14abf15SRobert Mustacchi 	vlan_obj->get_cam_offset = ecore_get_cam_offset_vlan;
2511d14abf15SRobert Mustacchi 	vlan_obj->put_cam_offset = ecore_put_cam_offset_vlan;
2512d14abf15SRobert Mustacchi 
2513d14abf15SRobert Mustacchi 	if (CHIP_IS_E1x(pdev)) {
2514d14abf15SRobert Mustacchi 		ECORE_ERR("Do not support chips others than E2 and newer\n");
2515d14abf15SRobert Mustacchi 		BUG();
2516d14abf15SRobert Mustacchi 	} else {
2517d14abf15SRobert Mustacchi 		vlan_obj->set_one_rule      = ecore_set_one_vlan_e2;
2518d14abf15SRobert Mustacchi 		vlan_obj->check_del         = ecore_check_vlan_del;
2519d14abf15SRobert Mustacchi 		vlan_obj->check_add         = ecore_check_vlan_add;
2520d14abf15SRobert Mustacchi 		vlan_obj->check_move        = ecore_check_move;
2521d14abf15SRobert Mustacchi 		vlan_obj->ramrod_cmd        =
2522d14abf15SRobert Mustacchi 			RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES;
2523d14abf15SRobert Mustacchi 		vlan_obj->get_n_elements    = ecore_get_n_elements;
2524d14abf15SRobert Mustacchi 
2525d14abf15SRobert Mustacchi 		/* Exe Queue */
2526d14abf15SRobert Mustacchi 		ecore_exe_queue_init(pdev,
2527d14abf15SRobert Mustacchi 				     &vlan_obj->exe_queue, CLASSIFY_RULES_COUNT,
2528d14abf15SRobert Mustacchi 				     qable_obj, ecore_validate_vlan_mac,
2529d14abf15SRobert Mustacchi 				     ecore_remove_vlan_mac,
2530d14abf15SRobert Mustacchi 				     ecore_optimize_vlan_mac,
2531d14abf15SRobert Mustacchi 				     ecore_execute_vlan_mac,
2532d14abf15SRobert Mustacchi 				     ecore_exeq_get_vlan);
2533d14abf15SRobert Mustacchi 	}
2534d14abf15SRobert Mustacchi }
2535d14abf15SRobert Mustacchi 
ecore_init_vlan_mac_obj(struct _lm_device_t * pdev,struct ecore_vlan_mac_obj * vlan_mac_obj,u8 cl_id,u32 cid,u8 func_id,void * rdata,lm_address_t rdata_mapping,int state,unsigned long * pstate,ecore_obj_type type,struct ecore_credit_pool_obj * macs_pool,struct ecore_credit_pool_obj * vlans_pool)2536d14abf15SRobert Mustacchi void ecore_init_vlan_mac_obj(struct _lm_device_t *pdev,
2537d14abf15SRobert Mustacchi 			     struct ecore_vlan_mac_obj *vlan_mac_obj,
2538d14abf15SRobert Mustacchi 			     u8 cl_id, u32 cid, u8 func_id, void *rdata,
2539d14abf15SRobert Mustacchi 			     lm_address_t rdata_mapping, int state,
2540d14abf15SRobert Mustacchi 			     unsigned long *pstate, ecore_obj_type type,
2541d14abf15SRobert Mustacchi 			     struct ecore_credit_pool_obj *macs_pool,
2542d14abf15SRobert Mustacchi 			     struct ecore_credit_pool_obj *vlans_pool)
2543d14abf15SRobert Mustacchi {
2544d14abf15SRobert Mustacchi 	union ecore_qable_obj *qable_obj =
2545d14abf15SRobert Mustacchi 		(union ecore_qable_obj *)vlan_mac_obj;
2546d14abf15SRobert Mustacchi 
2547d14abf15SRobert Mustacchi 	ecore_init_vlan_mac_common(vlan_mac_obj, cl_id, cid, func_id, rdata,
2548d14abf15SRobert Mustacchi 				   rdata_mapping, state, pstate, type,
2549d14abf15SRobert Mustacchi 				   macs_pool, vlans_pool);
2550d14abf15SRobert Mustacchi 
2551d14abf15SRobert Mustacchi 	/* CAM pool handling */
2552d14abf15SRobert Mustacchi 	vlan_mac_obj->get_credit = ecore_get_credit_vlan_mac;
2553d14abf15SRobert Mustacchi 	vlan_mac_obj->put_credit = ecore_put_credit_vlan_mac;
2554d14abf15SRobert Mustacchi 	/* CAM offset is relevant for 57710 and 57711 chips only which have a
2555d14abf15SRobert Mustacchi 	 * single CAM for both MACs and VLAN-MAC pairs. So the offset
2556d14abf15SRobert Mustacchi 	 * will be taken from MACs' pool object only.
2557d14abf15SRobert Mustacchi 	 */
2558d14abf15SRobert Mustacchi 	vlan_mac_obj->get_cam_offset = ecore_get_cam_offset_mac;
2559d14abf15SRobert Mustacchi 	vlan_mac_obj->put_cam_offset = ecore_put_cam_offset_mac;
2560d14abf15SRobert Mustacchi 
2561d14abf15SRobert Mustacchi 	if (CHIP_IS_E1(pdev)) {
2562d14abf15SRobert Mustacchi 		ECORE_ERR("Do not support chips others than E2\n");
2563d14abf15SRobert Mustacchi 		BUG();
2564d14abf15SRobert Mustacchi 	} else if (CHIP_IS_E1H(pdev)) {
2565d14abf15SRobert Mustacchi 		vlan_mac_obj->set_one_rule      = ecore_set_one_vlan_mac_e1h;
2566d14abf15SRobert Mustacchi 		vlan_mac_obj->check_del         = ecore_check_vlan_mac_del;
2567d14abf15SRobert Mustacchi 		vlan_mac_obj->check_add         = ecore_check_vlan_mac_add;
2568d14abf15SRobert Mustacchi 		vlan_mac_obj->check_move        = ecore_check_move_always_err;
2569d14abf15SRobert Mustacchi 		vlan_mac_obj->ramrod_cmd        = RAMROD_CMD_ID_ETH_SET_MAC;
2570d14abf15SRobert Mustacchi 
2571d14abf15SRobert Mustacchi 		/* Exe Queue */
2572d14abf15SRobert Mustacchi 		ecore_exe_queue_init(pdev,
2573d14abf15SRobert Mustacchi 				     &vlan_mac_obj->exe_queue, 1, qable_obj,
2574d14abf15SRobert Mustacchi 				     ecore_validate_vlan_mac,
2575d14abf15SRobert Mustacchi 				     ecore_remove_vlan_mac,
2576d14abf15SRobert Mustacchi 				     ecore_optimize_vlan_mac,
2577d14abf15SRobert Mustacchi 				     ecore_execute_vlan_mac,
2578d14abf15SRobert Mustacchi 				     ecore_exeq_get_vlan_mac);
2579d14abf15SRobert Mustacchi 	} else {
2580d14abf15SRobert Mustacchi 		vlan_mac_obj->set_one_rule      = ecore_set_one_vlan_mac_e2;
2581d14abf15SRobert Mustacchi 		vlan_mac_obj->check_del         = ecore_check_vlan_mac_del;
2582d14abf15SRobert Mustacchi 		vlan_mac_obj->check_add         = ecore_check_vlan_mac_add;
2583d14abf15SRobert Mustacchi 		vlan_mac_obj->check_move        = ecore_check_move;
2584d14abf15SRobert Mustacchi 		vlan_mac_obj->ramrod_cmd        =
2585d14abf15SRobert Mustacchi 			RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES;
2586d14abf15SRobert Mustacchi 
2587d14abf15SRobert Mustacchi 		/* Exe Queue */
2588d14abf15SRobert Mustacchi 		ecore_exe_queue_init(pdev,
2589d14abf15SRobert Mustacchi 				     &vlan_mac_obj->exe_queue,
2590d14abf15SRobert Mustacchi 				     CLASSIFY_RULES_COUNT,
2591d14abf15SRobert Mustacchi 				     qable_obj, ecore_validate_vlan_mac,
2592d14abf15SRobert Mustacchi 				     ecore_remove_vlan_mac,
2593d14abf15SRobert Mustacchi 				     ecore_optimize_vlan_mac,
2594d14abf15SRobert Mustacchi 				     ecore_execute_vlan_mac,
2595d14abf15SRobert Mustacchi 				     ecore_exeq_get_vlan_mac);
2596d14abf15SRobert Mustacchi 	}
2597d14abf15SRobert Mustacchi }
2598d14abf15SRobert Mustacchi 
2599d14abf15SRobert Mustacchi /* RX_MODE verbs: DROP_ALL/ACCEPT_ALL/ACCEPT_ALL_MULTI/ACCEPT_ALL_VLAN/NORMAL */
__storm_memset_mac_filters(struct _lm_device_t * pdev,struct tstorm_eth_mac_filter_config * mac_filters,u16 pf_id)2600d14abf15SRobert Mustacchi static INLINE void __storm_memset_mac_filters(struct _lm_device_t *pdev,
2601d14abf15SRobert Mustacchi 			struct tstorm_eth_mac_filter_config *mac_filters,
2602d14abf15SRobert Mustacchi 			u16 pf_id)
2603d14abf15SRobert Mustacchi {
2604d14abf15SRobert Mustacchi 	size_t size = sizeof(struct tstorm_eth_mac_filter_config);
2605d14abf15SRobert Mustacchi 
2606d14abf15SRobert Mustacchi 	u32 addr = BAR_TSTRORM_INTMEM +
2607d14abf15SRobert Mustacchi 			TSTORM_MAC_FILTER_CONFIG_OFFSET(pf_id);
2608d14abf15SRobert Mustacchi 
2609d14abf15SRobert Mustacchi 	__storm_memset_struct(pdev, addr, size, (u32 *)mac_filters);
2610d14abf15SRobert Mustacchi }
2611d14abf15SRobert Mustacchi 
ecore_set_rx_mode_e1x(struct _lm_device_t * pdev,struct ecore_rx_mode_ramrod_params * p)2612d14abf15SRobert Mustacchi static int ecore_set_rx_mode_e1x(struct _lm_device_t *pdev,
2613d14abf15SRobert Mustacchi 				 struct ecore_rx_mode_ramrod_params *p)
2614d14abf15SRobert Mustacchi {
2615d14abf15SRobert Mustacchi 	/* update the pdev MAC filter structure */
2616d14abf15SRobert Mustacchi 	u32 mask = (1 << p->cl_id);
2617d14abf15SRobert Mustacchi 
2618d14abf15SRobert Mustacchi 	struct tstorm_eth_mac_filter_config *mac_filters =
2619d14abf15SRobert Mustacchi 		(struct tstorm_eth_mac_filter_config *)p->rdata;
2620d14abf15SRobert Mustacchi 
2621d14abf15SRobert Mustacchi 	/* initial setting is drop-all */
2622d14abf15SRobert Mustacchi 	u8 drop_all_ucast = 1, drop_all_mcast = 1;
2623d14abf15SRobert Mustacchi 	u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0;
2624d14abf15SRobert Mustacchi 	u8 unmatched_unicast = 0;
2625d14abf15SRobert Mustacchi 
2626d14abf15SRobert Mustacchi     /* In e1x there we only take into account rx accept flag since tx switching
2627d14abf15SRobert Mustacchi      * isn't enabled. */
2628d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_ACCEPT_UNICAST, &p->rx_accept_flags))
2629d14abf15SRobert Mustacchi 		/* accept matched ucast */
2630d14abf15SRobert Mustacchi 		drop_all_ucast = 0;
2631d14abf15SRobert Mustacchi 
2632d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_ACCEPT_MULTICAST, &p->rx_accept_flags))
2633d14abf15SRobert Mustacchi 		/* accept matched mcast */
2634d14abf15SRobert Mustacchi 		drop_all_mcast = 0;
2635d14abf15SRobert Mustacchi 
2636d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_ACCEPT_ALL_UNICAST, &p->rx_accept_flags)) {
2637d14abf15SRobert Mustacchi 		/* accept all mcast */
2638d14abf15SRobert Mustacchi 		drop_all_ucast = 0;
2639d14abf15SRobert Mustacchi 		accp_all_ucast = 1;
2640d14abf15SRobert Mustacchi 	}
2641d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_ACCEPT_ALL_MULTICAST, &p->rx_accept_flags)) {
2642d14abf15SRobert Mustacchi 		/* accept all mcast */
2643d14abf15SRobert Mustacchi 		drop_all_mcast = 0;
2644d14abf15SRobert Mustacchi 		accp_all_mcast = 1;
2645d14abf15SRobert Mustacchi 	}
2646d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_ACCEPT_BROADCAST, &p->rx_accept_flags))
2647d14abf15SRobert Mustacchi 		/* accept (all) bcast */
2648d14abf15SRobert Mustacchi 		accp_all_bcast = 1;
2649d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_ACCEPT_UNMATCHED, &p->rx_accept_flags))
2650d14abf15SRobert Mustacchi 		/* accept unmatched unicasts */
2651d14abf15SRobert Mustacchi 		unmatched_unicast = 1;
2652d14abf15SRobert Mustacchi 
2653d14abf15SRobert Mustacchi 	mac_filters->ucast_drop_all = drop_all_ucast ?
2654d14abf15SRobert Mustacchi 		mac_filters->ucast_drop_all | mask :
2655d14abf15SRobert Mustacchi 		mac_filters->ucast_drop_all & ~mask;
2656d14abf15SRobert Mustacchi 
2657d14abf15SRobert Mustacchi 	mac_filters->mcast_drop_all = drop_all_mcast ?
2658d14abf15SRobert Mustacchi 		mac_filters->mcast_drop_all | mask :
2659d14abf15SRobert Mustacchi 		mac_filters->mcast_drop_all & ~mask;
2660d14abf15SRobert Mustacchi 
2661d14abf15SRobert Mustacchi 	mac_filters->ucast_accept_all = accp_all_ucast ?
2662d14abf15SRobert Mustacchi 		mac_filters->ucast_accept_all | mask :
2663d14abf15SRobert Mustacchi 		mac_filters->ucast_accept_all & ~mask;
2664d14abf15SRobert Mustacchi 
2665d14abf15SRobert Mustacchi 	mac_filters->mcast_accept_all = accp_all_mcast ?
2666d14abf15SRobert Mustacchi 		mac_filters->mcast_accept_all | mask :
2667d14abf15SRobert Mustacchi 		mac_filters->mcast_accept_all & ~mask;
2668d14abf15SRobert Mustacchi 
2669d14abf15SRobert Mustacchi 	mac_filters->bcast_accept_all = accp_all_bcast ?
2670d14abf15SRobert Mustacchi 		mac_filters->bcast_accept_all | mask :
2671d14abf15SRobert Mustacchi 		mac_filters->bcast_accept_all & ~mask;
2672d14abf15SRobert Mustacchi 
2673d14abf15SRobert Mustacchi 	mac_filters->unmatched_unicast = unmatched_unicast ?
2674d14abf15SRobert Mustacchi 		mac_filters->unmatched_unicast | mask :
2675d14abf15SRobert Mustacchi 		mac_filters->unmatched_unicast & ~mask;
2676d14abf15SRobert Mustacchi 
2677d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "drop_ucast 0x%x\ndrop_mcast 0x%x\n accp_ucast 0x%x\n"
2678d14abf15SRobert Mustacchi 			 "accp_mcast 0x%x\naccp_bcast 0x%x\n",
2679d14abf15SRobert Mustacchi 	   mac_filters->ucast_drop_all, mac_filters->mcast_drop_all,
2680d14abf15SRobert Mustacchi 	   mac_filters->ucast_accept_all, mac_filters->mcast_accept_all,
2681d14abf15SRobert Mustacchi 	   mac_filters->bcast_accept_all);
2682d14abf15SRobert Mustacchi 
2683d14abf15SRobert Mustacchi 	/* write the MAC filter structure*/
2684d14abf15SRobert Mustacchi 	__storm_memset_mac_filters(pdev, mac_filters, p->func_id);
2685d14abf15SRobert Mustacchi 
2686d14abf15SRobert Mustacchi 	/* The operation is completed */
2687d14abf15SRobert Mustacchi 	ECORE_CLEAR_BIT(p->state, p->pstate);
2688d14abf15SRobert Mustacchi 	smp_mb__after_atomic();
2689d14abf15SRobert Mustacchi 
2690d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
2691d14abf15SRobert Mustacchi }
2692d14abf15SRobert Mustacchi 
2693d14abf15SRobert Mustacchi /* Setup ramrod data */
ecore_rx_mode_set_rdata_hdr_e2(u32 cid,struct eth_classify_header * hdr,u8 rule_cnt)2694d14abf15SRobert Mustacchi static INLINE void ecore_rx_mode_set_rdata_hdr_e2(u32 cid,
2695d14abf15SRobert Mustacchi 				struct eth_classify_header *hdr,
2696d14abf15SRobert Mustacchi 				u8 rule_cnt)
2697d14abf15SRobert Mustacchi {
2698d14abf15SRobert Mustacchi 	hdr->echo = mm_cpu_to_le32(cid);
2699d14abf15SRobert Mustacchi 	hdr->rule_cnt = rule_cnt;
2700d14abf15SRobert Mustacchi }
2701d14abf15SRobert Mustacchi 
ecore_rx_mode_set_cmd_state_e2(struct _lm_device_t * pdev,unsigned long * accept_flags,struct eth_filter_rules_cmd * cmd,BOOL clear_accept_all)2702d14abf15SRobert Mustacchi static INLINE void ecore_rx_mode_set_cmd_state_e2(struct _lm_device_t *pdev,
2703d14abf15SRobert Mustacchi 				unsigned long *accept_flags,
2704d14abf15SRobert Mustacchi 				struct eth_filter_rules_cmd *cmd,
2705d14abf15SRobert Mustacchi 				BOOL clear_accept_all)
2706d14abf15SRobert Mustacchi {
2707d14abf15SRobert Mustacchi 	u16 state;
2708d14abf15SRobert Mustacchi 
2709d14abf15SRobert Mustacchi 	/* start with 'drop-all' */
2710d14abf15SRobert Mustacchi 	state = ETH_FILTER_RULES_CMD_UCAST_DROP_ALL |
2711d14abf15SRobert Mustacchi 		ETH_FILTER_RULES_CMD_MCAST_DROP_ALL;
2712d14abf15SRobert Mustacchi 
2713d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_ACCEPT_UNICAST, accept_flags))
2714d14abf15SRobert Mustacchi 		state &= ~ETH_FILTER_RULES_CMD_UCAST_DROP_ALL;
2715d14abf15SRobert Mustacchi 
2716d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_ACCEPT_MULTICAST, accept_flags))
2717d14abf15SRobert Mustacchi 		state &= ~ETH_FILTER_RULES_CMD_MCAST_DROP_ALL;
2718d14abf15SRobert Mustacchi 
2719d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_ACCEPT_ALL_UNICAST, accept_flags)) {
2720d14abf15SRobert Mustacchi 		state &= ~ETH_FILTER_RULES_CMD_UCAST_DROP_ALL;
2721d14abf15SRobert Mustacchi 		state |= ETH_FILTER_RULES_CMD_UCAST_ACCEPT_ALL;
2722d14abf15SRobert Mustacchi 	}
2723d14abf15SRobert Mustacchi 
2724d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_ACCEPT_ALL_MULTICAST, accept_flags)) {
2725d14abf15SRobert Mustacchi 		state |= ETH_FILTER_RULES_CMD_MCAST_ACCEPT_ALL;
2726d14abf15SRobert Mustacchi 		state &= ~ETH_FILTER_RULES_CMD_MCAST_DROP_ALL;
2727d14abf15SRobert Mustacchi 	}
2728d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_ACCEPT_BROADCAST, accept_flags))
2729d14abf15SRobert Mustacchi 		state |= ETH_FILTER_RULES_CMD_BCAST_ACCEPT_ALL;
2730d14abf15SRobert Mustacchi 
2731d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_ACCEPT_UNMATCHED, accept_flags)) {
2732d14abf15SRobert Mustacchi 		state &= ~ETH_FILTER_RULES_CMD_UCAST_DROP_ALL;
2733d14abf15SRobert Mustacchi 		state |= ETH_FILTER_RULES_CMD_UCAST_ACCEPT_UNMATCHED;
2734d14abf15SRobert Mustacchi 	}
2735d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_ACCEPT_ANY_VLAN, accept_flags))
2736d14abf15SRobert Mustacchi 		state |= ETH_FILTER_RULES_CMD_ACCEPT_ANY_VLAN;
2737d14abf15SRobert Mustacchi 
2738d14abf15SRobert Mustacchi 	/* Clear ACCEPT_ALL_XXX flags for FCoE L2 Queue */
2739d14abf15SRobert Mustacchi 	if (clear_accept_all) {
2740d14abf15SRobert Mustacchi 		state &= ~ETH_FILTER_RULES_CMD_MCAST_ACCEPT_ALL;
2741d14abf15SRobert Mustacchi 		state &= ~ETH_FILTER_RULES_CMD_BCAST_ACCEPT_ALL;
2742d14abf15SRobert Mustacchi 		state &= ~ETH_FILTER_RULES_CMD_UCAST_ACCEPT_ALL;
2743d14abf15SRobert Mustacchi 		state &= ~ETH_FILTER_RULES_CMD_UCAST_ACCEPT_UNMATCHED;
2744d14abf15SRobert Mustacchi 	}
2745d14abf15SRobert Mustacchi 
2746d14abf15SRobert Mustacchi 	cmd->state = mm_cpu_to_le16(state);
2747d14abf15SRobert Mustacchi }
2748d14abf15SRobert Mustacchi 
ecore_set_rx_mode_e2(struct _lm_device_t * pdev,struct ecore_rx_mode_ramrod_params * p)2749d14abf15SRobert Mustacchi static int ecore_set_rx_mode_e2(struct _lm_device_t *pdev,
2750d14abf15SRobert Mustacchi 				struct ecore_rx_mode_ramrod_params *p)
2751d14abf15SRobert Mustacchi {
2752d14abf15SRobert Mustacchi 	struct eth_filter_rules_ramrod_data *data = p->rdata;
2753d14abf15SRobert Mustacchi 	int rc;
2754d14abf15SRobert Mustacchi 	u8 rule_idx = 0;
2755d14abf15SRobert Mustacchi 
2756d14abf15SRobert Mustacchi 	/* Reset the ramrod data buffer */
2757d14abf15SRobert Mustacchi 	mm_memset(data, 0, sizeof(*data));
2758d14abf15SRobert Mustacchi 
2759d14abf15SRobert Mustacchi 	/* Setup ramrod data */
2760d14abf15SRobert Mustacchi 
2761d14abf15SRobert Mustacchi 	/* Tx (internal switching) */
2762d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_TX, &p->ramrod_flags)) {
2763d14abf15SRobert Mustacchi 		data->rules[rule_idx].client_id = p->cl_id;
2764d14abf15SRobert Mustacchi 		data->rules[rule_idx].func_id = p->func_id;
2765d14abf15SRobert Mustacchi 
2766d14abf15SRobert Mustacchi 		data->rules[rule_idx].cmd_general_data =
2767d14abf15SRobert Mustacchi 			ETH_FILTER_RULES_CMD_TX_CMD;
2768d14abf15SRobert Mustacchi 
2769d14abf15SRobert Mustacchi 		ecore_rx_mode_set_cmd_state_e2(pdev, &p->tx_accept_flags,
2770d14abf15SRobert Mustacchi 					       &(data->rules[rule_idx++]),
2771d14abf15SRobert Mustacchi 					       FALSE);
2772d14abf15SRobert Mustacchi 	}
2773d14abf15SRobert Mustacchi 
2774d14abf15SRobert Mustacchi 	/* Rx */
2775d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_RX, &p->ramrod_flags)) {
2776d14abf15SRobert Mustacchi 		data->rules[rule_idx].client_id = p->cl_id;
2777d14abf15SRobert Mustacchi 		data->rules[rule_idx].func_id = p->func_id;
2778d14abf15SRobert Mustacchi 
2779d14abf15SRobert Mustacchi 		data->rules[rule_idx].cmd_general_data =
2780d14abf15SRobert Mustacchi 			ETH_FILTER_RULES_CMD_RX_CMD;
2781d14abf15SRobert Mustacchi 
2782d14abf15SRobert Mustacchi 		ecore_rx_mode_set_cmd_state_e2(pdev, &p->rx_accept_flags,
2783d14abf15SRobert Mustacchi 					       &(data->rules[rule_idx++]),
2784d14abf15SRobert Mustacchi 					       FALSE);
2785d14abf15SRobert Mustacchi 	}
2786d14abf15SRobert Mustacchi 
2787d14abf15SRobert Mustacchi 	/* If FCoE Queue configuration has been requested configure the Rx and
2788d14abf15SRobert Mustacchi 	 * internal switching modes for this queue in separate rules.
2789d14abf15SRobert Mustacchi 	 *
2790d14abf15SRobert Mustacchi 	 * FCoE queue shell never be set to ACCEPT_ALL packets of any sort:
2791d14abf15SRobert Mustacchi 	 * MCAST_ALL, UCAST_ALL, BCAST_ALL and UNMATCHED.
2792d14abf15SRobert Mustacchi 	 */
2793d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_RX_MODE_FCOE_ETH, &p->rx_mode_flags)) {
2794d14abf15SRobert Mustacchi 		/*  Tx (internal switching) */
2795d14abf15SRobert Mustacchi 		if (ECORE_TEST_BIT(RAMROD_TX, &p->ramrod_flags)) {
2796d14abf15SRobert Mustacchi 			data->rules[rule_idx].client_id = FCOE_CID(pdev);
2797d14abf15SRobert Mustacchi 			data->rules[rule_idx].func_id = p->func_id;
2798d14abf15SRobert Mustacchi 
2799d14abf15SRobert Mustacchi 			data->rules[rule_idx].cmd_general_data =
2800d14abf15SRobert Mustacchi 						ETH_FILTER_RULES_CMD_TX_CMD;
2801d14abf15SRobert Mustacchi 
2802d14abf15SRobert Mustacchi 			ecore_rx_mode_set_cmd_state_e2(pdev, &p->tx_accept_flags,
2803d14abf15SRobert Mustacchi 						       &(data->rules[rule_idx]),
2804d14abf15SRobert Mustacchi 						       TRUE);
2805d14abf15SRobert Mustacchi 			rule_idx++;
2806d14abf15SRobert Mustacchi 		}
2807d14abf15SRobert Mustacchi 
2808d14abf15SRobert Mustacchi 		/* Rx */
2809d14abf15SRobert Mustacchi 		if (ECORE_TEST_BIT(RAMROD_RX, &p->ramrod_flags)) {
2810d14abf15SRobert Mustacchi 			data->rules[rule_idx].client_id = FCOE_CID(pdev);
2811d14abf15SRobert Mustacchi 			data->rules[rule_idx].func_id = p->func_id;
2812d14abf15SRobert Mustacchi 
2813d14abf15SRobert Mustacchi 			data->rules[rule_idx].cmd_general_data =
2814d14abf15SRobert Mustacchi 						ETH_FILTER_RULES_CMD_RX_CMD;
2815d14abf15SRobert Mustacchi 
2816d14abf15SRobert Mustacchi 			ecore_rx_mode_set_cmd_state_e2(pdev, &p->rx_accept_flags,
2817d14abf15SRobert Mustacchi 						       &(data->rules[rule_idx]),
2818d14abf15SRobert Mustacchi 						       TRUE);
2819d14abf15SRobert Mustacchi 			rule_idx++;
2820d14abf15SRobert Mustacchi 		}
2821d14abf15SRobert Mustacchi 	}
2822d14abf15SRobert Mustacchi 
2823d14abf15SRobert Mustacchi 	/* Set the ramrod header (most importantly - number of rules to
2824d14abf15SRobert Mustacchi 	 * configure).
2825d14abf15SRobert Mustacchi 	 */
2826d14abf15SRobert Mustacchi 	ecore_rx_mode_set_rdata_hdr_e2(p->cid, &data->header, rule_idx);
2827d14abf15SRobert Mustacchi 
2828d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "About to configure %d rules, rx_accept_flags 0x%lx, tx_accept_flags 0x%lx\n",
2829d14abf15SRobert Mustacchi 		  data->header.rule_cnt, p->rx_accept_flags,
2830d14abf15SRobert Mustacchi 		  p->tx_accept_flags);
2831d14abf15SRobert Mustacchi 
2832d14abf15SRobert Mustacchi 	/* No need for an explicit memory barrier here as long as we
2833d14abf15SRobert Mustacchi 	 * ensure the ordering of writing to the SPQ element
2834d14abf15SRobert Mustacchi 	 * and updating of the SPQ producer which involves a memory
2835d14abf15SRobert Mustacchi 	 * read. If the memory read is removed we will have to put a
2836d14abf15SRobert Mustacchi 	 * full memory barrier there (inside ecore_sp_post()).
2837d14abf15SRobert Mustacchi 	 */
2838d14abf15SRobert Mustacchi 
2839d14abf15SRobert Mustacchi 	/* Send a ramrod */
2840d14abf15SRobert Mustacchi 	rc = ecore_sp_post(pdev,
2841d14abf15SRobert Mustacchi 			   RAMROD_CMD_ID_ETH_FILTER_RULES,
2842d14abf15SRobert Mustacchi 			   p->cid,
2843d14abf15SRobert Mustacchi 			   p->rdata_mapping.as_u64,
2844d14abf15SRobert Mustacchi 			   ETH_CONNECTION_TYPE);
2845d14abf15SRobert Mustacchi 	if (rc)
2846d14abf15SRobert Mustacchi 		return rc;
2847d14abf15SRobert Mustacchi 
2848d14abf15SRobert Mustacchi 	/* Ramrod completion is pending */
2849d14abf15SRobert Mustacchi 	return ECORE_PENDING;
2850d14abf15SRobert Mustacchi }
2851d14abf15SRobert Mustacchi 
ecore_wait_rx_mode_comp_e2(struct _lm_device_t * pdev,struct ecore_rx_mode_ramrod_params * p)2852d14abf15SRobert Mustacchi static int ecore_wait_rx_mode_comp_e2(struct _lm_device_t *pdev,
2853d14abf15SRobert Mustacchi 				      struct ecore_rx_mode_ramrod_params *p)
2854d14abf15SRobert Mustacchi {
2855d14abf15SRobert Mustacchi 	return ecore_state_wait(pdev, p->state, p->pstate);
2856d14abf15SRobert Mustacchi }
2857d14abf15SRobert Mustacchi 
ecore_empty_rx_mode_wait(struct _lm_device_t * pdev,struct ecore_rx_mode_ramrod_params * p)2858d14abf15SRobert Mustacchi static int ecore_empty_rx_mode_wait(struct _lm_device_t *pdev,
2859d14abf15SRobert Mustacchi 				    struct ecore_rx_mode_ramrod_params *p)
2860d14abf15SRobert Mustacchi {
2861d14abf15SRobert Mustacchi 	/* Do nothing */
2862d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
2863d14abf15SRobert Mustacchi }
2864d14abf15SRobert Mustacchi 
ecore_config_rx_mode(struct _lm_device_t * pdev,struct ecore_rx_mode_ramrod_params * p)2865d14abf15SRobert Mustacchi int ecore_config_rx_mode(struct _lm_device_t *pdev,
2866d14abf15SRobert Mustacchi 			 struct ecore_rx_mode_ramrod_params *p)
2867d14abf15SRobert Mustacchi {
2868d14abf15SRobert Mustacchi 	int rc;
2869d14abf15SRobert Mustacchi 
2870d14abf15SRobert Mustacchi 	/* Configure the new classification in the chip */
2871d14abf15SRobert Mustacchi 	rc = p->rx_mode_obj->config_rx_mode(pdev, p);
2872d14abf15SRobert Mustacchi 	if (rc < 0)
2873d14abf15SRobert Mustacchi 		return rc;
2874d14abf15SRobert Mustacchi 
2875d14abf15SRobert Mustacchi 	/* Wait for a ramrod completion if was requested */
2876d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_COMP_WAIT, &p->ramrod_flags)) {
2877d14abf15SRobert Mustacchi 		rc = p->rx_mode_obj->wait_comp(pdev, p);
2878d14abf15SRobert Mustacchi 		if (rc)
2879d14abf15SRobert Mustacchi 			return rc;
2880d14abf15SRobert Mustacchi 	}
2881d14abf15SRobert Mustacchi 
2882d14abf15SRobert Mustacchi 	return rc;
2883d14abf15SRobert Mustacchi }
2884d14abf15SRobert Mustacchi 
ecore_init_rx_mode_obj(struct _lm_device_t * pdev,struct ecore_rx_mode_obj * o)2885d14abf15SRobert Mustacchi void ecore_init_rx_mode_obj(struct _lm_device_t *pdev,
2886d14abf15SRobert Mustacchi 			    struct ecore_rx_mode_obj *o)
2887d14abf15SRobert Mustacchi {
2888d14abf15SRobert Mustacchi 	if (CHIP_IS_E1x(pdev)) {
2889d14abf15SRobert Mustacchi 		o->wait_comp      = ecore_empty_rx_mode_wait;
2890d14abf15SRobert Mustacchi 		o->config_rx_mode = ecore_set_rx_mode_e1x;
2891d14abf15SRobert Mustacchi 	} else {
2892d14abf15SRobert Mustacchi 		o->wait_comp      = ecore_wait_rx_mode_comp_e2;
2893d14abf15SRobert Mustacchi 		o->config_rx_mode = ecore_set_rx_mode_e2;
2894d14abf15SRobert Mustacchi 	}
2895d14abf15SRobert Mustacchi }
2896d14abf15SRobert Mustacchi 
2897d14abf15SRobert Mustacchi /********************* Multicast verbs: SET, CLEAR ****************************/
ecore_mcast_bin_from_mac(u8 * mac)2898d14abf15SRobert Mustacchi static INLINE u8 ecore_mcast_bin_from_mac(u8 *mac)
2899d14abf15SRobert Mustacchi {
2900d14abf15SRobert Mustacchi 	return (ecore_crc32_le(0, mac, ETH_ALEN) >> 24) & 0xff;
2901d14abf15SRobert Mustacchi }
2902d14abf15SRobert Mustacchi 
2903d14abf15SRobert Mustacchi struct ecore_mcast_mac_elem {
2904d14abf15SRobert Mustacchi 	d_list_entry_t link;
2905d14abf15SRobert Mustacchi 	u8 mac[ETH_ALEN];
2906d14abf15SRobert Mustacchi 	u8 pad[2]; /* For a natural alignment of the following buffer */
2907d14abf15SRobert Mustacchi };
2908d14abf15SRobert Mustacchi 
2909d14abf15SRobert Mustacchi struct ecore_pending_mcast_cmd {
2910d14abf15SRobert Mustacchi 	d_list_entry_t link;
2911d14abf15SRobert Mustacchi 	int type; /* ECORE_MCAST_CMD_X */
2912d14abf15SRobert Mustacchi 	union {
2913d14abf15SRobert Mustacchi 		d_list_t macs_head;
2914d14abf15SRobert Mustacchi 		u32 macs_num; /* Needed for DEL command */
2915d14abf15SRobert Mustacchi 		int next_bin; /* Needed for RESTORE flow with aprox match */
2916d14abf15SRobert Mustacchi 	} data;
2917d14abf15SRobert Mustacchi 
2918d14abf15SRobert Mustacchi 	BOOL done; /* set to TRUE, when the command has been handled,
2919d14abf15SRobert Mustacchi 		    * practically used in 57712 handling only, where one pending
2920d14abf15SRobert Mustacchi 		    * command may be handled in a few operations. As long as for
2921d14abf15SRobert Mustacchi 		    * other chips every operation handling is completed in a
2922d14abf15SRobert Mustacchi 		    * single ramrod, there is no need to utilize this field.
2923d14abf15SRobert Mustacchi 		    */
2924d14abf15SRobert Mustacchi #ifndef ECORE_ERASE
2925d14abf15SRobert Mustacchi 	u32 alloc_len; /* passed to ECORE_FREE */
2926d14abf15SRobert Mustacchi #endif
2927d14abf15SRobert Mustacchi };
2928d14abf15SRobert Mustacchi 
ecore_mcast_wait(struct _lm_device_t * pdev,struct ecore_mcast_obj * o)2929d14abf15SRobert Mustacchi static int ecore_mcast_wait(struct _lm_device_t *pdev,
2930d14abf15SRobert Mustacchi 			    struct ecore_mcast_obj *o)
2931d14abf15SRobert Mustacchi {
2932d14abf15SRobert Mustacchi 	if (ecore_state_wait(pdev, o->sched_state, o->raw.pstate) ||
2933d14abf15SRobert Mustacchi 			o->raw.wait_comp(pdev, &o->raw))
2934d14abf15SRobert Mustacchi 		return ECORE_TIMEOUT;
2935d14abf15SRobert Mustacchi 
2936d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
2937d14abf15SRobert Mustacchi }
2938d14abf15SRobert Mustacchi 
ecore_mcast_enqueue_cmd(struct _lm_device_t * pdev,struct ecore_mcast_obj * o,struct ecore_mcast_ramrod_params * p,enum ecore_mcast_cmd cmd)2939d14abf15SRobert Mustacchi static int ecore_mcast_enqueue_cmd(struct _lm_device_t *pdev,
2940d14abf15SRobert Mustacchi 				   struct ecore_mcast_obj *o,
2941d14abf15SRobert Mustacchi 				   struct ecore_mcast_ramrod_params *p,
2942d14abf15SRobert Mustacchi 				   enum ecore_mcast_cmd cmd)
2943d14abf15SRobert Mustacchi {
2944d14abf15SRobert Mustacchi 	int total_sz;
2945d14abf15SRobert Mustacchi 	struct ecore_pending_mcast_cmd *new_cmd;
2946d14abf15SRobert Mustacchi 	struct ecore_mcast_mac_elem *cur_mac = NULL;
2947d14abf15SRobert Mustacchi 	struct ecore_mcast_list_elem *pos;
2948d14abf15SRobert Mustacchi 	int macs_list_len = ((cmd == ECORE_MCAST_CMD_ADD) ?
2949d14abf15SRobert Mustacchi 			     p->mcast_list_len : 0);
2950d14abf15SRobert Mustacchi 
2951d14abf15SRobert Mustacchi 	/* If the command is empty ("handle pending commands only"), break */
2952d14abf15SRobert Mustacchi 	if (!p->mcast_list_len)
2953d14abf15SRobert Mustacchi 		return ECORE_SUCCESS;
2954d14abf15SRobert Mustacchi 
2955d14abf15SRobert Mustacchi 	total_sz = sizeof(*new_cmd) +
2956d14abf15SRobert Mustacchi 		macs_list_len * sizeof(struct ecore_mcast_mac_elem);
2957d14abf15SRobert Mustacchi 
2958d14abf15SRobert Mustacchi 	/* Add mcast is called under spin_lock, thus calling with GFP_ATOMIC */
2959d14abf15SRobert Mustacchi 	new_cmd = ECORE_ZALLOC(total_sz, GFP_ATOMIC, pdev);
2960d14abf15SRobert Mustacchi 
2961d14abf15SRobert Mustacchi 	if (!new_cmd)
2962d14abf15SRobert Mustacchi 		return ECORE_NOMEM;
2963d14abf15SRobert Mustacchi 
2964d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "About to enqueue a new %d command. macs_list_len=%d\n",
2965d14abf15SRobert Mustacchi 		  cmd, macs_list_len);
2966d14abf15SRobert Mustacchi 
2967d14abf15SRobert Mustacchi 	ECORE_LIST_INIT(&new_cmd->data.macs_head);
2968d14abf15SRobert Mustacchi 
2969d14abf15SRobert Mustacchi 	new_cmd->type = cmd;
2970d14abf15SRobert Mustacchi 	new_cmd->done = FALSE;
2971d14abf15SRobert Mustacchi #ifndef ECORE_ERASE
2972d14abf15SRobert Mustacchi 	new_cmd->alloc_len = total_sz;
2973d14abf15SRobert Mustacchi #endif
2974d14abf15SRobert Mustacchi 
2975d14abf15SRobert Mustacchi 	switch (cmd) {
2976d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_ADD:
2977d14abf15SRobert Mustacchi 		cur_mac = (struct ecore_mcast_mac_elem *)
2978d14abf15SRobert Mustacchi 			  ((u8 *)new_cmd + sizeof(*new_cmd));
2979d14abf15SRobert Mustacchi 
2980d14abf15SRobert Mustacchi 		/* Push the MACs of the current command into the pending command
2981d14abf15SRobert Mustacchi 		 * MACs list: FIFO
2982d14abf15SRobert Mustacchi 		 */
2983d14abf15SRobert Mustacchi 		ECORE_LIST_FOR_EACH_ENTRY(pos, &p->mcast_list, link,
2984d14abf15SRobert Mustacchi 					  struct ecore_mcast_list_elem) {
2985d14abf15SRobert Mustacchi 			mm_memcpy(cur_mac->mac, pos->mac, ETH_ALEN);
2986d14abf15SRobert Mustacchi 			ECORE_LIST_PUSH_TAIL(&cur_mac->link,
2987d14abf15SRobert Mustacchi 					     &new_cmd->data.macs_head);
2988d14abf15SRobert Mustacchi 			cur_mac++;
2989d14abf15SRobert Mustacchi 		}
2990d14abf15SRobert Mustacchi 
2991d14abf15SRobert Mustacchi 		break;
2992d14abf15SRobert Mustacchi 
2993d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_DEL:
2994d14abf15SRobert Mustacchi 		new_cmd->data.macs_num = p->mcast_list_len;
2995d14abf15SRobert Mustacchi 		break;
2996d14abf15SRobert Mustacchi 
2997d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_RESTORE:
2998d14abf15SRobert Mustacchi 		new_cmd->data.next_bin = 0;
2999d14abf15SRobert Mustacchi 		break;
3000d14abf15SRobert Mustacchi 
3001d14abf15SRobert Mustacchi 	default:
3002d14abf15SRobert Mustacchi 		ECORE_FREE(pdev, new_cmd, total_sz);
3003d14abf15SRobert Mustacchi 		ECORE_ERR("Unknown command: %d\n", cmd);
3004d14abf15SRobert Mustacchi 		return ECORE_INVAL;
3005d14abf15SRobert Mustacchi 	}
3006d14abf15SRobert Mustacchi 
3007d14abf15SRobert Mustacchi 	/* Push the new pending command to the tail of the pending list: FIFO */
3008d14abf15SRobert Mustacchi 	ECORE_LIST_PUSH_TAIL(&new_cmd->link, &o->pending_cmds_head);
3009d14abf15SRobert Mustacchi 
3010d14abf15SRobert Mustacchi 	o->set_sched(o);
3011d14abf15SRobert Mustacchi 
3012d14abf15SRobert Mustacchi 	return ECORE_PENDING;
3013d14abf15SRobert Mustacchi }
3014d14abf15SRobert Mustacchi 
3015d14abf15SRobert Mustacchi /**
3016d14abf15SRobert Mustacchi  * ecore_mcast_get_next_bin - get the next set bin (index)
3017d14abf15SRobert Mustacchi  *
3018d14abf15SRobert Mustacchi  * @o:
3019d14abf15SRobert Mustacchi  * @last:	index to start looking from (including)
3020d14abf15SRobert Mustacchi  *
3021d14abf15SRobert Mustacchi  * returns the next found (set) bin or a negative value if none is found.
3022d14abf15SRobert Mustacchi  */
ecore_mcast_get_next_bin(struct ecore_mcast_obj * o,int last)3023d14abf15SRobert Mustacchi static INLINE int ecore_mcast_get_next_bin(struct ecore_mcast_obj *o, int last)
3024d14abf15SRobert Mustacchi {
3025d14abf15SRobert Mustacchi 	int i, j, inner_start = last % BIT_VEC64_ELEM_SZ;
3026d14abf15SRobert Mustacchi 
3027d14abf15SRobert Mustacchi 	for (i = last / BIT_VEC64_ELEM_SZ; i < ECORE_MCAST_VEC_SZ; i++) {
3028d14abf15SRobert Mustacchi 		if (o->registry.aprox_match.vec[i])
3029d14abf15SRobert Mustacchi 			for (j = inner_start; j < BIT_VEC64_ELEM_SZ; j++) {
3030d14abf15SRobert Mustacchi 				int cur_bit = j + BIT_VEC64_ELEM_SZ * i;
3031d14abf15SRobert Mustacchi 				if (BIT_VEC64_TEST_BIT(o->registry.aprox_match.
3032d14abf15SRobert Mustacchi 						       vec, cur_bit)) {
3033d14abf15SRobert Mustacchi 					return cur_bit;
3034d14abf15SRobert Mustacchi 				}
3035d14abf15SRobert Mustacchi 			}
3036d14abf15SRobert Mustacchi 		inner_start = 0;
3037d14abf15SRobert Mustacchi 	}
3038d14abf15SRobert Mustacchi 
3039d14abf15SRobert Mustacchi 	/* None found */
3040d14abf15SRobert Mustacchi 	return -1;
3041d14abf15SRobert Mustacchi }
3042d14abf15SRobert Mustacchi 
3043d14abf15SRobert Mustacchi /**
3044d14abf15SRobert Mustacchi  * ecore_mcast_clear_first_bin - find the first set bin and clear it
3045d14abf15SRobert Mustacchi  *
3046d14abf15SRobert Mustacchi  * @o:
3047d14abf15SRobert Mustacchi  *
3048d14abf15SRobert Mustacchi  * returns the index of the found bin or -1 if none is found
3049d14abf15SRobert Mustacchi  */
ecore_mcast_clear_first_bin(struct ecore_mcast_obj * o)3050d14abf15SRobert Mustacchi static INLINE int ecore_mcast_clear_first_bin(struct ecore_mcast_obj *o)
3051d14abf15SRobert Mustacchi {
3052d14abf15SRobert Mustacchi 	int cur_bit = ecore_mcast_get_next_bin(o, 0);
3053d14abf15SRobert Mustacchi 
3054d14abf15SRobert Mustacchi 	if (cur_bit >= 0)
3055d14abf15SRobert Mustacchi 		BIT_VEC64_CLEAR_BIT(o->registry.aprox_match.vec, cur_bit);
3056d14abf15SRobert Mustacchi 
3057d14abf15SRobert Mustacchi 	return cur_bit;
3058d14abf15SRobert Mustacchi }
3059d14abf15SRobert Mustacchi 
ecore_mcast_get_rx_tx_flag(struct ecore_mcast_obj * o)3060d14abf15SRobert Mustacchi static INLINE u8 ecore_mcast_get_rx_tx_flag(struct ecore_mcast_obj *o)
3061d14abf15SRobert Mustacchi {
3062d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &o->raw;
3063d14abf15SRobert Mustacchi 	u8 rx_tx_flag = 0;
3064d14abf15SRobert Mustacchi 
3065d14abf15SRobert Mustacchi 	if ((raw->obj_type == ECORE_OBJ_TYPE_TX) ||
3066d14abf15SRobert Mustacchi 	    (raw->obj_type == ECORE_OBJ_TYPE_RX_TX))
3067d14abf15SRobert Mustacchi 		rx_tx_flag |= ETH_MULTICAST_RULES_CMD_TX_CMD;
3068d14abf15SRobert Mustacchi 
3069d14abf15SRobert Mustacchi 	if ((raw->obj_type == ECORE_OBJ_TYPE_RX) ||
3070d14abf15SRobert Mustacchi 	    (raw->obj_type == ECORE_OBJ_TYPE_RX_TX))
3071d14abf15SRobert Mustacchi 		rx_tx_flag |= ETH_MULTICAST_RULES_CMD_RX_CMD;
3072d14abf15SRobert Mustacchi 
3073d14abf15SRobert Mustacchi 	return rx_tx_flag;
3074d14abf15SRobert Mustacchi }
3075d14abf15SRobert Mustacchi 
ecore_mcast_set_one_rule_e2(struct _lm_device_t * pdev,struct ecore_mcast_obj * o,int idx,union ecore_mcast_config_data * cfg_data,enum ecore_mcast_cmd cmd)3076d14abf15SRobert Mustacchi static void ecore_mcast_set_one_rule_e2(struct _lm_device_t *pdev,
3077d14abf15SRobert Mustacchi 					struct ecore_mcast_obj *o, int idx,
3078d14abf15SRobert Mustacchi 					union ecore_mcast_config_data *cfg_data,
3079d14abf15SRobert Mustacchi 					enum ecore_mcast_cmd cmd)
3080d14abf15SRobert Mustacchi {
3081d14abf15SRobert Mustacchi 	struct ecore_raw_obj *r = &o->raw;
3082d14abf15SRobert Mustacchi 	struct eth_multicast_rules_ramrod_data *data =
3083d14abf15SRobert Mustacchi 		(struct eth_multicast_rules_ramrod_data *)(r->rdata);
3084d14abf15SRobert Mustacchi 	u8 func_id = r->func_id;
3085d14abf15SRobert Mustacchi 	u8 rx_tx_add_flag = ecore_mcast_get_rx_tx_flag(o);
3086d14abf15SRobert Mustacchi 	int bin;
3087d14abf15SRobert Mustacchi 
3088d14abf15SRobert Mustacchi 	if ((cmd == ECORE_MCAST_CMD_ADD) || (cmd == ECORE_MCAST_CMD_RESTORE))
3089d14abf15SRobert Mustacchi 		rx_tx_add_flag |= ETH_MULTICAST_RULES_CMD_IS_ADD;
3090d14abf15SRobert Mustacchi 
3091d14abf15SRobert Mustacchi 	data->rules[idx].cmd_general_data |= rx_tx_add_flag;
3092d14abf15SRobert Mustacchi 
3093d14abf15SRobert Mustacchi 	/* Get a bin and update a bins' vector */
3094d14abf15SRobert Mustacchi 	switch (cmd) {
3095d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_ADD:
3096d14abf15SRobert Mustacchi 		bin = ecore_mcast_bin_from_mac(cfg_data->mac);
3097d14abf15SRobert Mustacchi 		BIT_VEC64_SET_BIT(o->registry.aprox_match.vec, bin);
3098d14abf15SRobert Mustacchi 		break;
3099d14abf15SRobert Mustacchi 
3100d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_DEL:
3101d14abf15SRobert Mustacchi 		/* If there were no more bins to clear
3102d14abf15SRobert Mustacchi 		 * (ecore_mcast_clear_first_bin() returns -1) then we would
3103d14abf15SRobert Mustacchi 		 * clear any (0xff) bin.
3104d14abf15SRobert Mustacchi 		 * See ecore_mcast_validate_e2() for explanation when it may
3105d14abf15SRobert Mustacchi 		 * happen.
3106d14abf15SRobert Mustacchi 		 */
3107d14abf15SRobert Mustacchi 		bin = ecore_mcast_clear_first_bin(o);
3108d14abf15SRobert Mustacchi 		break;
3109d14abf15SRobert Mustacchi 
3110d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_RESTORE:
3111d14abf15SRobert Mustacchi 		bin = cfg_data->bin;
3112d14abf15SRobert Mustacchi 		break;
3113d14abf15SRobert Mustacchi 
3114d14abf15SRobert Mustacchi 	default:
3115d14abf15SRobert Mustacchi 		ECORE_ERR("Unknown command: %d\n", cmd);
3116d14abf15SRobert Mustacchi 		return;
3117d14abf15SRobert Mustacchi 	}
3118d14abf15SRobert Mustacchi 
3119d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "%s bin %d\n",
3120d14abf15SRobert Mustacchi 		  ((rx_tx_add_flag & ETH_MULTICAST_RULES_CMD_IS_ADD) ?
3121d14abf15SRobert Mustacchi 		   "Setting"  : "Clearing"), bin);
3122d14abf15SRobert Mustacchi 
3123d14abf15SRobert Mustacchi 	data->rules[idx].bin_id    = (u8)bin;
3124d14abf15SRobert Mustacchi 	data->rules[idx].func_id   = func_id;
3125d14abf15SRobert Mustacchi 	data->rules[idx].engine_id = o->engine_id;
3126d14abf15SRobert Mustacchi }
3127d14abf15SRobert Mustacchi 
3128d14abf15SRobert Mustacchi /**
3129d14abf15SRobert Mustacchi  * ecore_mcast_handle_restore_cmd_e2 - restore configuration from the registry
3130d14abf15SRobert Mustacchi  *
3131d14abf15SRobert Mustacchi  * @pdev:	device handle
3132d14abf15SRobert Mustacchi  * @o:
3133d14abf15SRobert Mustacchi  * @start_bin:	index in the registry to start from (including)
3134d14abf15SRobert Mustacchi  * @rdata_idx:	index in the ramrod data to start from
3135d14abf15SRobert Mustacchi  *
3136d14abf15SRobert Mustacchi  * returns last handled bin index or -1 if all bins have been handled
3137d14abf15SRobert Mustacchi  */
ecore_mcast_handle_restore_cmd_e2(struct _lm_device_t * pdev,struct ecore_mcast_obj * o,int start_bin,int * rdata_idx)3138d14abf15SRobert Mustacchi static INLINE int ecore_mcast_handle_restore_cmd_e2(
3139d14abf15SRobert Mustacchi 	struct _lm_device_t *pdev, struct ecore_mcast_obj *o , int start_bin,
3140d14abf15SRobert Mustacchi 	int *rdata_idx)
3141d14abf15SRobert Mustacchi {
3142d14abf15SRobert Mustacchi 	int cur_bin, cnt = *rdata_idx;
3143d14abf15SRobert Mustacchi 	union ecore_mcast_config_data cfg_data = {NULL};
3144d14abf15SRobert Mustacchi 
3145d14abf15SRobert Mustacchi 	/* go through the registry and configure the bins from it */
3146d14abf15SRobert Mustacchi 	for (cur_bin = ecore_mcast_get_next_bin(o, start_bin); cur_bin >= 0;
3147d14abf15SRobert Mustacchi 	    cur_bin = ecore_mcast_get_next_bin(o, cur_bin + 1)) {
3148d14abf15SRobert Mustacchi 
3149d14abf15SRobert Mustacchi 		cfg_data.bin = (u8)cur_bin;
3150d14abf15SRobert Mustacchi 		o->set_one_rule(pdev, o, cnt, &cfg_data,
3151d14abf15SRobert Mustacchi 				ECORE_MCAST_CMD_RESTORE);
3152d14abf15SRobert Mustacchi 
3153d14abf15SRobert Mustacchi 		cnt++;
3154d14abf15SRobert Mustacchi 
3155d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "About to configure a bin %d\n", cur_bin);
3156d14abf15SRobert Mustacchi 
3157d14abf15SRobert Mustacchi 		/* Break if we reached the maximum number
3158d14abf15SRobert Mustacchi 		 * of rules.
3159d14abf15SRobert Mustacchi 		 */
3160d14abf15SRobert Mustacchi 		if (cnt >= o->max_cmd_len)
3161d14abf15SRobert Mustacchi 			break;
3162d14abf15SRobert Mustacchi 	}
3163d14abf15SRobert Mustacchi 
3164d14abf15SRobert Mustacchi 	*rdata_idx = cnt;
3165d14abf15SRobert Mustacchi 
3166d14abf15SRobert Mustacchi 	return cur_bin;
3167d14abf15SRobert Mustacchi }
3168d14abf15SRobert Mustacchi 
ecore_mcast_hdl_pending_add_e2(struct _lm_device_t * pdev,struct ecore_mcast_obj * o,struct ecore_pending_mcast_cmd * cmd_pos,int * line_idx)3169d14abf15SRobert Mustacchi static INLINE void ecore_mcast_hdl_pending_add_e2(struct _lm_device_t *pdev,
3170d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o, struct ecore_pending_mcast_cmd *cmd_pos,
3171d14abf15SRobert Mustacchi 	int *line_idx)
3172d14abf15SRobert Mustacchi {
3173d14abf15SRobert Mustacchi 	struct ecore_mcast_mac_elem *pmac_pos, *pmac_pos_n;
3174d14abf15SRobert Mustacchi 	int cnt = *line_idx;
3175d14abf15SRobert Mustacchi 	union ecore_mcast_config_data cfg_data = {NULL};
3176d14abf15SRobert Mustacchi 
3177d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY_SAFE(pmac_pos, pmac_pos_n,
3178d14abf15SRobert Mustacchi 		&cmd_pos->data.macs_head, link, struct ecore_mcast_mac_elem) {
3179d14abf15SRobert Mustacchi 
3180d14abf15SRobert Mustacchi 		cfg_data.mac = &pmac_pos->mac[0];
3181d14abf15SRobert Mustacchi 		o->set_one_rule(pdev, o, cnt, &cfg_data, cmd_pos->type);
3182d14abf15SRobert Mustacchi 
3183d14abf15SRobert Mustacchi 		cnt++;
3184d14abf15SRobert Mustacchi 
3185d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "About to configure %02x:%02x:%02x:%02x:%02x:%02x mcast MAC\n",
3186d14abf15SRobert Mustacchi 			  pmac_pos->mac[0], pmac_pos->mac[1], pmac_pos->mac[2], pmac_pos->mac[3], pmac_pos->mac[4], pmac_pos->mac[5]);
3187d14abf15SRobert Mustacchi 
3188d14abf15SRobert Mustacchi 		ECORE_LIST_REMOVE_ENTRY(&pmac_pos->link,
3189d14abf15SRobert Mustacchi 					&cmd_pos->data.macs_head);
3190d14abf15SRobert Mustacchi 
3191d14abf15SRobert Mustacchi 		/* Break if we reached the maximum number
3192d14abf15SRobert Mustacchi 		 * of rules.
3193d14abf15SRobert Mustacchi 		 */
3194d14abf15SRobert Mustacchi 		if (cnt >= o->max_cmd_len)
3195d14abf15SRobert Mustacchi 			break;
3196d14abf15SRobert Mustacchi 	}
3197d14abf15SRobert Mustacchi 
3198d14abf15SRobert Mustacchi 	*line_idx = cnt;
3199d14abf15SRobert Mustacchi 
3200d14abf15SRobert Mustacchi 	/* if no more MACs to configure - we are done */
3201d14abf15SRobert Mustacchi 	if (ECORE_LIST_IS_EMPTY(&cmd_pos->data.macs_head))
3202d14abf15SRobert Mustacchi 		cmd_pos->done = TRUE;
3203d14abf15SRobert Mustacchi }
3204d14abf15SRobert Mustacchi 
ecore_mcast_hdl_pending_del_e2(struct _lm_device_t * pdev,struct ecore_mcast_obj * o,struct ecore_pending_mcast_cmd * cmd_pos,int * line_idx)3205d14abf15SRobert Mustacchi static INLINE void ecore_mcast_hdl_pending_del_e2(struct _lm_device_t *pdev,
3206d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o, struct ecore_pending_mcast_cmd *cmd_pos,
3207d14abf15SRobert Mustacchi 	int *line_idx)
3208d14abf15SRobert Mustacchi {
3209d14abf15SRobert Mustacchi 	int cnt = *line_idx;
3210d14abf15SRobert Mustacchi 
3211d14abf15SRobert Mustacchi 	while (cmd_pos->data.macs_num) {
3212d14abf15SRobert Mustacchi 		o->set_one_rule(pdev, o, cnt, NULL, cmd_pos->type);
3213d14abf15SRobert Mustacchi 
3214d14abf15SRobert Mustacchi 		cnt++;
3215d14abf15SRobert Mustacchi 
3216d14abf15SRobert Mustacchi 		cmd_pos->data.macs_num--;
3217d14abf15SRobert Mustacchi 
3218d14abf15SRobert Mustacchi 		  ECORE_MSG(pdev, "Deleting MAC. %d left,cnt is %d\n",
3219d14abf15SRobert Mustacchi 				  cmd_pos->data.macs_num, cnt);
3220d14abf15SRobert Mustacchi 
3221d14abf15SRobert Mustacchi 		/* Break if we reached the maximum
3222d14abf15SRobert Mustacchi 		 * number of rules.
3223d14abf15SRobert Mustacchi 		 */
3224d14abf15SRobert Mustacchi 		if (cnt >= o->max_cmd_len)
3225d14abf15SRobert Mustacchi 			break;
3226d14abf15SRobert Mustacchi 	}
3227d14abf15SRobert Mustacchi 
3228d14abf15SRobert Mustacchi 	*line_idx = cnt;
3229d14abf15SRobert Mustacchi 
3230d14abf15SRobert Mustacchi 	/* If we cleared all bins - we are done */
3231d14abf15SRobert Mustacchi 	if (!cmd_pos->data.macs_num)
3232d14abf15SRobert Mustacchi 		cmd_pos->done = TRUE;
3233d14abf15SRobert Mustacchi }
3234d14abf15SRobert Mustacchi 
ecore_mcast_hdl_pending_restore_e2(struct _lm_device_t * pdev,struct ecore_mcast_obj * o,struct ecore_pending_mcast_cmd * cmd_pos,int * line_idx)3235d14abf15SRobert Mustacchi static INLINE void ecore_mcast_hdl_pending_restore_e2(struct _lm_device_t *pdev,
3236d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o, struct ecore_pending_mcast_cmd *cmd_pos,
3237d14abf15SRobert Mustacchi 	int *line_idx)
3238d14abf15SRobert Mustacchi {
3239d14abf15SRobert Mustacchi 	cmd_pos->data.next_bin = o->hdl_restore(pdev, o, cmd_pos->data.next_bin,
3240d14abf15SRobert Mustacchi 						line_idx);
3241d14abf15SRobert Mustacchi 
3242d14abf15SRobert Mustacchi 	if (cmd_pos->data.next_bin < 0)
3243d14abf15SRobert Mustacchi 		/* If o->set_restore returned -1 we are done */
3244d14abf15SRobert Mustacchi 		cmd_pos->done = TRUE;
3245d14abf15SRobert Mustacchi 	else
3246d14abf15SRobert Mustacchi 		/* Start from the next bin next time */
3247d14abf15SRobert Mustacchi 		cmd_pos->data.next_bin++;
3248d14abf15SRobert Mustacchi }
3249d14abf15SRobert Mustacchi 
ecore_mcast_handle_pending_cmds_e2(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p)3250d14abf15SRobert Mustacchi static INLINE int ecore_mcast_handle_pending_cmds_e2(struct _lm_device_t *pdev,
3251d14abf15SRobert Mustacchi 				struct ecore_mcast_ramrod_params *p)
3252d14abf15SRobert Mustacchi {
3253d14abf15SRobert Mustacchi 	struct ecore_pending_mcast_cmd *cmd_pos, *cmd_pos_n;
3254d14abf15SRobert Mustacchi 	int cnt = 0;
3255d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o = p->mcast_obj;
3256d14abf15SRobert Mustacchi 
3257d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY_SAFE(cmd_pos, cmd_pos_n,
3258d14abf15SRobert Mustacchi 		&o->pending_cmds_head, link, struct ecore_pending_mcast_cmd) {
3259d14abf15SRobert Mustacchi 		switch (cmd_pos->type) {
3260d14abf15SRobert Mustacchi 		case ECORE_MCAST_CMD_ADD:
3261d14abf15SRobert Mustacchi 			ecore_mcast_hdl_pending_add_e2(pdev, o, cmd_pos, &cnt);
3262d14abf15SRobert Mustacchi 			break;
3263d14abf15SRobert Mustacchi 
3264d14abf15SRobert Mustacchi 		case ECORE_MCAST_CMD_DEL:
3265d14abf15SRobert Mustacchi 			ecore_mcast_hdl_pending_del_e2(pdev, o, cmd_pos, &cnt);
3266d14abf15SRobert Mustacchi 			break;
3267d14abf15SRobert Mustacchi 
3268d14abf15SRobert Mustacchi 		case ECORE_MCAST_CMD_RESTORE:
3269d14abf15SRobert Mustacchi 			ecore_mcast_hdl_pending_restore_e2(pdev, o, cmd_pos,
3270d14abf15SRobert Mustacchi 							   &cnt);
3271d14abf15SRobert Mustacchi 			break;
3272d14abf15SRobert Mustacchi 
3273d14abf15SRobert Mustacchi 		default:
3274d14abf15SRobert Mustacchi 			ECORE_ERR("Unknown command: %d\n", cmd_pos->type);
3275d14abf15SRobert Mustacchi 			return ECORE_INVAL;
3276d14abf15SRobert Mustacchi 		}
3277d14abf15SRobert Mustacchi 
3278d14abf15SRobert Mustacchi 		/* If the command has been completed - remove it from the list
3279d14abf15SRobert Mustacchi 		 * and free the memory
3280d14abf15SRobert Mustacchi 		 */
3281d14abf15SRobert Mustacchi 		if (cmd_pos->done) {
3282d14abf15SRobert Mustacchi 			ECORE_LIST_REMOVE_ENTRY(&cmd_pos->link,
3283d14abf15SRobert Mustacchi 						&o->pending_cmds_head);
3284d14abf15SRobert Mustacchi 			ECORE_FREE(pdev, cmd_pos, cmd_pos->alloc_len);
3285d14abf15SRobert Mustacchi 		}
3286d14abf15SRobert Mustacchi 
3287d14abf15SRobert Mustacchi 		/* Break if we reached the maximum number of rules */
3288d14abf15SRobert Mustacchi 		if (cnt >= o->max_cmd_len)
3289d14abf15SRobert Mustacchi 			break;
3290d14abf15SRobert Mustacchi 	}
3291d14abf15SRobert Mustacchi 
3292d14abf15SRobert Mustacchi 	return cnt;
3293d14abf15SRobert Mustacchi }
3294d14abf15SRobert Mustacchi 
ecore_mcast_hdl_add(struct _lm_device_t * pdev,struct ecore_mcast_obj * o,struct ecore_mcast_ramrod_params * p,int * line_idx)3295d14abf15SRobert Mustacchi static INLINE void ecore_mcast_hdl_add(struct _lm_device_t *pdev,
3296d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o, struct ecore_mcast_ramrod_params *p,
3297d14abf15SRobert Mustacchi 	int *line_idx)
3298d14abf15SRobert Mustacchi {
3299d14abf15SRobert Mustacchi 	struct ecore_mcast_list_elem *mlist_pos;
3300d14abf15SRobert Mustacchi 	union ecore_mcast_config_data cfg_data = {NULL};
3301d14abf15SRobert Mustacchi 	int cnt = *line_idx;
3302d14abf15SRobert Mustacchi 
3303d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(mlist_pos, &p->mcast_list, link,
3304d14abf15SRobert Mustacchi 				  struct ecore_mcast_list_elem) {
3305d14abf15SRobert Mustacchi 		cfg_data.mac = mlist_pos->mac;
3306d14abf15SRobert Mustacchi 		o->set_one_rule(pdev, o, cnt, &cfg_data, ECORE_MCAST_CMD_ADD);
3307d14abf15SRobert Mustacchi 
3308d14abf15SRobert Mustacchi 		cnt++;
3309d14abf15SRobert Mustacchi 
3310d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "About to configure %02x:%02x:%02x:%02x:%02x:%02x mcast MAC\n",
3311d14abf15SRobert Mustacchi 			  mlist_pos->mac[0], mlist_pos->mac[1], mlist_pos->mac[2], mlist_pos->mac[3], mlist_pos->mac[4], mlist_pos->mac[5]);
3312d14abf15SRobert Mustacchi 	}
3313d14abf15SRobert Mustacchi 
3314d14abf15SRobert Mustacchi 	*line_idx = cnt;
3315d14abf15SRobert Mustacchi }
3316d14abf15SRobert Mustacchi 
ecore_mcast_hdl_del(struct _lm_device_t * pdev,struct ecore_mcast_obj * o,struct ecore_mcast_ramrod_params * p,int * line_idx)3317d14abf15SRobert Mustacchi static INLINE void ecore_mcast_hdl_del(struct _lm_device_t *pdev,
3318d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o, struct ecore_mcast_ramrod_params *p,
3319d14abf15SRobert Mustacchi 	int *line_idx)
3320d14abf15SRobert Mustacchi {
3321d14abf15SRobert Mustacchi 	int cnt = *line_idx, i;
3322d14abf15SRobert Mustacchi 
3323d14abf15SRobert Mustacchi 	for (i = 0; i < p->mcast_list_len; i++) {
3324d14abf15SRobert Mustacchi 		o->set_one_rule(pdev, o, cnt, NULL, ECORE_MCAST_CMD_DEL);
3325d14abf15SRobert Mustacchi 
3326d14abf15SRobert Mustacchi 		cnt++;
3327d14abf15SRobert Mustacchi 
3328d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "Deleting MAC. %d left\n",
3329d14abf15SRobert Mustacchi 			  p->mcast_list_len - i - 1);
3330d14abf15SRobert Mustacchi 	}
3331d14abf15SRobert Mustacchi 
3332d14abf15SRobert Mustacchi 	*line_idx = cnt;
3333d14abf15SRobert Mustacchi }
3334d14abf15SRobert Mustacchi 
3335d14abf15SRobert Mustacchi /**
3336d14abf15SRobert Mustacchi  * ecore_mcast_handle_current_cmd -
3337d14abf15SRobert Mustacchi  *
3338d14abf15SRobert Mustacchi  * @pdev:	device handle
3339d14abf15SRobert Mustacchi  * @p:
3340d14abf15SRobert Mustacchi  * @cmd:
3341d14abf15SRobert Mustacchi  * @start_cnt:	first line in the ramrod data that may be used
3342d14abf15SRobert Mustacchi  *
3343d14abf15SRobert Mustacchi  * This function is called iff there is enough place for the current command in
3344d14abf15SRobert Mustacchi  * the ramrod data.
3345d14abf15SRobert Mustacchi  * Returns number of lines filled in the ramrod data in total.
3346d14abf15SRobert Mustacchi  */
ecore_mcast_handle_current_cmd(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p,enum ecore_mcast_cmd cmd,int start_cnt)3347d14abf15SRobert Mustacchi static INLINE int ecore_mcast_handle_current_cmd(struct _lm_device_t *pdev,
3348d14abf15SRobert Mustacchi 			struct ecore_mcast_ramrod_params *p,
3349d14abf15SRobert Mustacchi 			enum ecore_mcast_cmd cmd,
3350d14abf15SRobert Mustacchi 			int start_cnt)
3351d14abf15SRobert Mustacchi {
3352d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o = p->mcast_obj;
3353d14abf15SRobert Mustacchi 	int cnt = start_cnt;
3354d14abf15SRobert Mustacchi 
3355d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "p->mcast_list_len=%d\n", p->mcast_list_len);
3356d14abf15SRobert Mustacchi 
3357d14abf15SRobert Mustacchi 	switch (cmd) {
3358d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_ADD:
3359d14abf15SRobert Mustacchi 		ecore_mcast_hdl_add(pdev, o, p, &cnt);
3360d14abf15SRobert Mustacchi 		break;
3361d14abf15SRobert Mustacchi 
3362d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_DEL:
3363d14abf15SRobert Mustacchi 		ecore_mcast_hdl_del(pdev, o, p, &cnt);
3364d14abf15SRobert Mustacchi 		break;
3365d14abf15SRobert Mustacchi 
3366d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_RESTORE:
3367d14abf15SRobert Mustacchi 		o->hdl_restore(pdev, o, 0, &cnt);
3368d14abf15SRobert Mustacchi 		break;
3369d14abf15SRobert Mustacchi 
3370d14abf15SRobert Mustacchi 	default:
3371d14abf15SRobert Mustacchi 		ECORE_ERR("Unknown command: %d\n", cmd);
3372d14abf15SRobert Mustacchi 		return ECORE_INVAL;
3373d14abf15SRobert Mustacchi 	}
3374d14abf15SRobert Mustacchi 
3375d14abf15SRobert Mustacchi 	/* The current command has been handled */
3376d14abf15SRobert Mustacchi 	p->mcast_list_len = 0;
3377d14abf15SRobert Mustacchi 
3378d14abf15SRobert Mustacchi 	return cnt;
3379d14abf15SRobert Mustacchi }
3380d14abf15SRobert Mustacchi 
ecore_mcast_validate_e2(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p,enum ecore_mcast_cmd cmd)3381d14abf15SRobert Mustacchi static int ecore_mcast_validate_e2(struct _lm_device_t *pdev,
3382d14abf15SRobert Mustacchi 				   struct ecore_mcast_ramrod_params *p,
3383d14abf15SRobert Mustacchi 				   enum ecore_mcast_cmd cmd)
3384d14abf15SRobert Mustacchi {
3385d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o = p->mcast_obj;
3386d14abf15SRobert Mustacchi 	int reg_sz = o->get_registry_size(o);
3387d14abf15SRobert Mustacchi 
3388d14abf15SRobert Mustacchi 	switch (cmd) {
3389d14abf15SRobert Mustacchi 	/* DEL command deletes all currently configured MACs */
3390d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_DEL:
3391d14abf15SRobert Mustacchi 		o->set_registry_size(o, 0);
3392*6680ee99SToomas Soome 		/* FALLTHROUGH */
3393d14abf15SRobert Mustacchi 
3394d14abf15SRobert Mustacchi 	/* RESTORE command will restore the entire multicast configuration */
3395d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_RESTORE:
3396d14abf15SRobert Mustacchi 		/* Here we set the approximate amount of work to do, which in
3397d14abf15SRobert Mustacchi 		 * fact may be only less as some MACs in postponed ADD
3398d14abf15SRobert Mustacchi 		 * command(s) scheduled before this command may fall into
3399d14abf15SRobert Mustacchi 		 * the same bin and the actual number of bins set in the
3400d14abf15SRobert Mustacchi 		 * registry would be less than we estimated here. See
3401d14abf15SRobert Mustacchi 		 * ecore_mcast_set_one_rule_e2() for further details.
3402d14abf15SRobert Mustacchi 		 */
3403d14abf15SRobert Mustacchi 		p->mcast_list_len = reg_sz;
3404d14abf15SRobert Mustacchi 		break;
3405d14abf15SRobert Mustacchi 
3406d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_ADD:
3407d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_CONT:
3408d14abf15SRobert Mustacchi 		/* Here we assume that all new MACs will fall into new bins.
3409d14abf15SRobert Mustacchi 		 * However we will correct the real registry size after we
3410d14abf15SRobert Mustacchi 		 * handle all pending commands.
3411d14abf15SRobert Mustacchi 		 */
3412d14abf15SRobert Mustacchi 		o->set_registry_size(o, reg_sz + p->mcast_list_len);
3413d14abf15SRobert Mustacchi 		break;
3414d14abf15SRobert Mustacchi 
3415d14abf15SRobert Mustacchi 	default:
3416d14abf15SRobert Mustacchi 		ECORE_ERR("Unknown command: %d\n", cmd);
3417d14abf15SRobert Mustacchi 		return ECORE_INVAL;
3418d14abf15SRobert Mustacchi 	}
3419d14abf15SRobert Mustacchi 
3420d14abf15SRobert Mustacchi 	/* Increase the total number of MACs pending to be configured */
3421d14abf15SRobert Mustacchi 	o->total_pending_num += p->mcast_list_len;
3422d14abf15SRobert Mustacchi 
3423d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
3424d14abf15SRobert Mustacchi }
3425d14abf15SRobert Mustacchi 
ecore_mcast_revert_e2(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p,int old_num_bins)3426d14abf15SRobert Mustacchi static void ecore_mcast_revert_e2(struct _lm_device_t *pdev,
3427d14abf15SRobert Mustacchi 				      struct ecore_mcast_ramrod_params *p,
3428d14abf15SRobert Mustacchi 				      int old_num_bins)
3429d14abf15SRobert Mustacchi {
3430d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o = p->mcast_obj;
3431d14abf15SRobert Mustacchi 
3432d14abf15SRobert Mustacchi 	o->set_registry_size(o, old_num_bins);
3433d14abf15SRobert Mustacchi 	o->total_pending_num -= p->mcast_list_len;
3434d14abf15SRobert Mustacchi }
3435d14abf15SRobert Mustacchi 
3436d14abf15SRobert Mustacchi /**
3437d14abf15SRobert Mustacchi  * ecore_mcast_set_rdata_hdr_e2 - sets a header values
3438d14abf15SRobert Mustacchi  *
3439d14abf15SRobert Mustacchi  * @pdev:	device handle
3440d14abf15SRobert Mustacchi  * @p:
3441d14abf15SRobert Mustacchi  * @len:	number of rules to handle
3442d14abf15SRobert Mustacchi  */
ecore_mcast_set_rdata_hdr_e2(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p,u8 len)3443d14abf15SRobert Mustacchi static INLINE void ecore_mcast_set_rdata_hdr_e2(struct _lm_device_t *pdev,
3444d14abf15SRobert Mustacchi 					struct ecore_mcast_ramrod_params *p,
3445d14abf15SRobert Mustacchi 					u8 len)
3446d14abf15SRobert Mustacchi {
3447d14abf15SRobert Mustacchi 	struct ecore_raw_obj *r = &p->mcast_obj->raw;
3448d14abf15SRobert Mustacchi 	struct eth_multicast_rules_ramrod_data *data =
3449d14abf15SRobert Mustacchi 		(struct eth_multicast_rules_ramrod_data *)(r->rdata);
3450d14abf15SRobert Mustacchi 
3451d14abf15SRobert Mustacchi 	data->header.echo = mm_cpu_to_le32((r->cid & ECORE_SWCID_MASK) |
3452d14abf15SRobert Mustacchi 					(ECORE_FILTER_MCAST_PENDING <<
3453d14abf15SRobert Mustacchi 					 ECORE_SWCID_SHIFT));
3454d14abf15SRobert Mustacchi 	data->header.rule_cnt = len;
3455d14abf15SRobert Mustacchi }
3456d14abf15SRobert Mustacchi 
3457d14abf15SRobert Mustacchi /**
3458d14abf15SRobert Mustacchi  * ecore_mcast_refresh_registry_e2 - recalculate the actual number of set bins
3459d14abf15SRobert Mustacchi  *
3460d14abf15SRobert Mustacchi  * @pdev:	device handle
3461d14abf15SRobert Mustacchi  * @o:
3462d14abf15SRobert Mustacchi  *
3463d14abf15SRobert Mustacchi  * Recalculate the actual number of set bins in the registry using Brian
3464d14abf15SRobert Mustacchi  * Kernighan's algorithm: it's execution complexity is as a number of set bins.
3465d14abf15SRobert Mustacchi  *
3466d14abf15SRobert Mustacchi  * returns 0 for the compliance with ecore_mcast_refresh_registry_e1().
3467d14abf15SRobert Mustacchi  */
ecore_mcast_refresh_registry_e2(struct _lm_device_t * pdev,struct ecore_mcast_obj * o)3468d14abf15SRobert Mustacchi static INLINE int ecore_mcast_refresh_registry_e2(struct _lm_device_t *pdev,
3469d14abf15SRobert Mustacchi 						  struct ecore_mcast_obj *o)
3470d14abf15SRobert Mustacchi {
3471d14abf15SRobert Mustacchi 	int i, cnt = 0;
3472d14abf15SRobert Mustacchi 	u64 elem;
3473d14abf15SRobert Mustacchi 
3474d14abf15SRobert Mustacchi 	for (i = 0; i < ECORE_MCAST_VEC_SZ; i++) {
3475d14abf15SRobert Mustacchi 		elem = o->registry.aprox_match.vec[i];
3476d14abf15SRobert Mustacchi 		for (; elem; cnt++)
3477d14abf15SRobert Mustacchi 			elem &= elem - 1;
3478d14abf15SRobert Mustacchi 	}
3479d14abf15SRobert Mustacchi 
3480d14abf15SRobert Mustacchi 	o->set_registry_size(o, cnt);
3481d14abf15SRobert Mustacchi 
3482d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
3483d14abf15SRobert Mustacchi }
3484d14abf15SRobert Mustacchi 
ecore_mcast_setup_e2(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p,enum ecore_mcast_cmd cmd)3485d14abf15SRobert Mustacchi static int ecore_mcast_setup_e2(struct _lm_device_t *pdev,
3486d14abf15SRobert Mustacchi 				struct ecore_mcast_ramrod_params *p,
3487d14abf15SRobert Mustacchi 				enum ecore_mcast_cmd cmd)
3488d14abf15SRobert Mustacchi {
3489d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &p->mcast_obj->raw;
3490d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o = p->mcast_obj;
3491d14abf15SRobert Mustacchi 	struct eth_multicast_rules_ramrod_data *data =
3492d14abf15SRobert Mustacchi 		(struct eth_multicast_rules_ramrod_data *)(raw->rdata);
3493d14abf15SRobert Mustacchi 	int cnt = 0, rc;
3494d14abf15SRobert Mustacchi 
3495d14abf15SRobert Mustacchi 	/* Reset the ramrod data buffer */
3496d14abf15SRobert Mustacchi 	mm_memset(data, 0, sizeof(*data));
3497d14abf15SRobert Mustacchi 
3498d14abf15SRobert Mustacchi 	cnt = ecore_mcast_handle_pending_cmds_e2(pdev, p);
3499d14abf15SRobert Mustacchi 
3500d14abf15SRobert Mustacchi 	/* If there are no more pending commands - clear SCHEDULED state */
3501d14abf15SRobert Mustacchi 	if (ECORE_LIST_IS_EMPTY(&o->pending_cmds_head))
3502d14abf15SRobert Mustacchi 		o->clear_sched(o);
3503d14abf15SRobert Mustacchi 
3504d14abf15SRobert Mustacchi 	/* The below may be TRUE iff there was enough room in ramrod
3505d14abf15SRobert Mustacchi 	 * data for all pending commands and for the current
3506d14abf15SRobert Mustacchi 	 * command. Otherwise the current command would have been added
3507d14abf15SRobert Mustacchi 	 * to the pending commands and p->mcast_list_len would have been
3508d14abf15SRobert Mustacchi 	 * zeroed.
3509d14abf15SRobert Mustacchi 	 */
3510d14abf15SRobert Mustacchi 	if (p->mcast_list_len > 0)
3511d14abf15SRobert Mustacchi 		cnt = ecore_mcast_handle_current_cmd(pdev, p, cmd, cnt);
3512d14abf15SRobert Mustacchi 
3513d14abf15SRobert Mustacchi 	/* We've pulled out some MACs - update the total number of
3514d14abf15SRobert Mustacchi 	 * outstanding.
3515d14abf15SRobert Mustacchi 	 */
3516d14abf15SRobert Mustacchi 	o->total_pending_num -= cnt;
3517d14abf15SRobert Mustacchi 
3518d14abf15SRobert Mustacchi 	/* send a ramrod */
3519d14abf15SRobert Mustacchi 	DbgBreakIf(o->total_pending_num < 0);
3520d14abf15SRobert Mustacchi 	DbgBreakIf(cnt > o->max_cmd_len);
3521d14abf15SRobert Mustacchi 
3522d14abf15SRobert Mustacchi 	ecore_mcast_set_rdata_hdr_e2(pdev, p, (u8)cnt);
3523d14abf15SRobert Mustacchi 
3524d14abf15SRobert Mustacchi 	/* Update a registry size if there are no more pending operations.
3525d14abf15SRobert Mustacchi 	 *
3526d14abf15SRobert Mustacchi 	 * We don't want to change the value of the registry size if there are
3527d14abf15SRobert Mustacchi 	 * pending operations because we want it to always be equal to the
3528d14abf15SRobert Mustacchi 	 * exact or the approximate number (see ecore_mcast_validate_e2()) of
3529d14abf15SRobert Mustacchi 	 * set bins after the last requested operation in order to properly
3530d14abf15SRobert Mustacchi 	 * evaluate the size of the next DEL/RESTORE operation.
3531d14abf15SRobert Mustacchi 	 *
3532d14abf15SRobert Mustacchi 	 * Note that we update the registry itself during command(s) handling
3533d14abf15SRobert Mustacchi 	 * - see ecore_mcast_set_one_rule_e2(). That's because for 57712 we
3534d14abf15SRobert Mustacchi 	 * aggregate multiple commands (ADD/DEL/RESTORE) into one ramrod but
3535d14abf15SRobert Mustacchi 	 * with a limited amount of update commands (per MAC/bin) and we don't
3536d14abf15SRobert Mustacchi 	 * know in this scope what the actual state of bins configuration is
3537d14abf15SRobert Mustacchi 	 * going to be after this ramrod.
3538d14abf15SRobert Mustacchi 	 */
3539d14abf15SRobert Mustacchi 	if (!o->total_pending_num)
3540d14abf15SRobert Mustacchi 		ecore_mcast_refresh_registry_e2(pdev, o);
3541d14abf15SRobert Mustacchi 
3542d14abf15SRobert Mustacchi 	/* If CLEAR_ONLY was requested - don't send a ramrod and clear
3543d14abf15SRobert Mustacchi 	 * RAMROD_PENDING status immediately.
3544d14abf15SRobert Mustacchi 	 */
3545d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) {
3546d14abf15SRobert Mustacchi 		raw->clear_pending(raw);
3547d14abf15SRobert Mustacchi 		return ECORE_SUCCESS;
3548d14abf15SRobert Mustacchi 	} else {
3549d14abf15SRobert Mustacchi 		/* No need for an explicit memory barrier here as long as we
3550d14abf15SRobert Mustacchi 		 * ensure the ordering of writing to the SPQ element
3551d14abf15SRobert Mustacchi 		 * and updating of the SPQ producer which involves a memory
3552d14abf15SRobert Mustacchi 		 * read. If the memory read is removed we will have to put a
3553d14abf15SRobert Mustacchi 		 * full memory barrier there (inside ecore_sp_post()).
3554d14abf15SRobert Mustacchi 		 */
3555d14abf15SRobert Mustacchi 
3556d14abf15SRobert Mustacchi 		/* Send a ramrod */
3557d14abf15SRobert Mustacchi 		rc = ecore_sp_post( pdev,
3558d14abf15SRobert Mustacchi 				    RAMROD_CMD_ID_ETH_MULTICAST_RULES,
3559d14abf15SRobert Mustacchi 				    raw->cid,
3560d14abf15SRobert Mustacchi 				    raw->rdata_mapping.as_u64,
3561d14abf15SRobert Mustacchi 				    ETH_CONNECTION_TYPE);
3562d14abf15SRobert Mustacchi 		if (rc)
3563d14abf15SRobert Mustacchi 			return rc;
3564d14abf15SRobert Mustacchi 
3565d14abf15SRobert Mustacchi 		/* Ramrod completion is pending */
3566d14abf15SRobert Mustacchi 		return ECORE_PENDING;
3567d14abf15SRobert Mustacchi 	}
3568d14abf15SRobert Mustacchi }
3569d14abf15SRobert Mustacchi 
ecore_mcast_validate_e1h(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p,enum ecore_mcast_cmd cmd)3570d14abf15SRobert Mustacchi static int ecore_mcast_validate_e1h(struct _lm_device_t *pdev,
3571d14abf15SRobert Mustacchi 				    struct ecore_mcast_ramrod_params *p,
3572d14abf15SRobert Mustacchi 				    enum ecore_mcast_cmd cmd)
3573d14abf15SRobert Mustacchi {
3574d14abf15SRobert Mustacchi 	/* Mark, that there is a work to do */
3575d14abf15SRobert Mustacchi 	if ((cmd == ECORE_MCAST_CMD_DEL) || (cmd == ECORE_MCAST_CMD_RESTORE))
3576d14abf15SRobert Mustacchi 		p->mcast_list_len = 1;
3577d14abf15SRobert Mustacchi 
3578d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
3579d14abf15SRobert Mustacchi }
3580d14abf15SRobert Mustacchi 
ecore_mcast_revert_e1h(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p,int old_num_bins)3581d14abf15SRobert Mustacchi static void ecore_mcast_revert_e1h(struct _lm_device_t *pdev,
3582d14abf15SRobert Mustacchi 				       struct ecore_mcast_ramrod_params *p,
3583d14abf15SRobert Mustacchi 				       int old_num_bins)
3584d14abf15SRobert Mustacchi {
3585d14abf15SRobert Mustacchi 	/* Do nothing */
3586d14abf15SRobert Mustacchi }
3587d14abf15SRobert Mustacchi 
3588d14abf15SRobert Mustacchi #define ECORE_57711_SET_MC_FILTER(filter, bit) \
3589d14abf15SRobert Mustacchi do { \
3590d14abf15SRobert Mustacchi 	(filter)[(bit) >> 5] |= (1 << ((bit) & 0x1f)); \
3591d14abf15SRobert Mustacchi } while (0)
3592d14abf15SRobert Mustacchi 
ecore_mcast_hdl_add_e1h(struct _lm_device_t * pdev,struct ecore_mcast_obj * o,struct ecore_mcast_ramrod_params * p,u32 * mc_filter)3593d14abf15SRobert Mustacchi static INLINE void ecore_mcast_hdl_add_e1h(struct _lm_device_t *pdev,
3594d14abf15SRobert Mustacchi 					   struct ecore_mcast_obj *o,
3595d14abf15SRobert Mustacchi 					   struct ecore_mcast_ramrod_params *p,
3596d14abf15SRobert Mustacchi 					   u32 *mc_filter)
3597d14abf15SRobert Mustacchi {
3598d14abf15SRobert Mustacchi 	struct ecore_mcast_list_elem *mlist_pos;
3599d14abf15SRobert Mustacchi 	int bit;
3600d14abf15SRobert Mustacchi 
3601d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(mlist_pos, &p->mcast_list, link,
3602d14abf15SRobert Mustacchi 				  struct ecore_mcast_list_elem) {
3603d14abf15SRobert Mustacchi 		bit = ecore_mcast_bin_from_mac(mlist_pos->mac);
3604d14abf15SRobert Mustacchi 		ECORE_57711_SET_MC_FILTER(mc_filter, bit);
3605d14abf15SRobert Mustacchi 
3606d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "About to configure %02x:%02x:%02x:%02x:%02x:%02x mcast MAC, bin %d\n",
3607d14abf15SRobert Mustacchi 			  mlist_pos->mac[0], mlist_pos->mac[1], mlist_pos->mac[2], mlist_pos->mac[3], mlist_pos->mac[4], mlist_pos->mac[5], bit);
3608d14abf15SRobert Mustacchi 
3609d14abf15SRobert Mustacchi 		/* bookkeeping... */
3610d14abf15SRobert Mustacchi 		BIT_VEC64_SET_BIT(o->registry.aprox_match.vec,
3611d14abf15SRobert Mustacchi 				  bit);
3612d14abf15SRobert Mustacchi 	}
3613d14abf15SRobert Mustacchi }
3614d14abf15SRobert Mustacchi 
ecore_mcast_hdl_restore_e1h(struct _lm_device_t * pdev,struct ecore_mcast_obj * o,struct ecore_mcast_ramrod_params * p,u32 * mc_filter)3615d14abf15SRobert Mustacchi static INLINE void ecore_mcast_hdl_restore_e1h(struct _lm_device_t *pdev,
3616d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o, struct ecore_mcast_ramrod_params *p,
3617d14abf15SRobert Mustacchi 	u32 *mc_filter)
3618d14abf15SRobert Mustacchi {
3619d14abf15SRobert Mustacchi 	int bit;
3620d14abf15SRobert Mustacchi 
3621d14abf15SRobert Mustacchi 	for (bit = ecore_mcast_get_next_bin(o, 0);
3622d14abf15SRobert Mustacchi 	     bit >= 0;
3623d14abf15SRobert Mustacchi 	     bit = ecore_mcast_get_next_bin(o, bit + 1)) {
3624d14abf15SRobert Mustacchi 		ECORE_57711_SET_MC_FILTER(mc_filter, bit);
3625d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "About to set bin %d\n", bit);
3626d14abf15SRobert Mustacchi 	}
3627d14abf15SRobert Mustacchi }
3628d14abf15SRobert Mustacchi 
3629d14abf15SRobert Mustacchi /* On 57711 we write the multicast MACs' approximate match
3630d14abf15SRobert Mustacchi  * table by directly into the TSTORM's internal RAM. So we don't
3631d14abf15SRobert Mustacchi  * really need to handle any tricks to make it work.
3632d14abf15SRobert Mustacchi  */
ecore_mcast_setup_e1h(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p,enum ecore_mcast_cmd cmd)3633d14abf15SRobert Mustacchi static int ecore_mcast_setup_e1h(struct _lm_device_t *pdev,
3634d14abf15SRobert Mustacchi 				 struct ecore_mcast_ramrod_params *p,
3635d14abf15SRobert Mustacchi 				 enum ecore_mcast_cmd cmd)
3636d14abf15SRobert Mustacchi {
3637d14abf15SRobert Mustacchi 	int i;
3638d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o = p->mcast_obj;
3639d14abf15SRobert Mustacchi 	struct ecore_raw_obj *r = &o->raw;
3640d14abf15SRobert Mustacchi 
3641d14abf15SRobert Mustacchi 	/* If CLEAR_ONLY has been requested - clear the registry
3642d14abf15SRobert Mustacchi 	 * and clear a pending bit.
3643d14abf15SRobert Mustacchi 	 */
3644d14abf15SRobert Mustacchi 	if (!ECORE_TEST_BIT(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) {
3645d14abf15SRobert Mustacchi 		u32 mc_filter[MC_HASH_SIZE] = {0};
3646d14abf15SRobert Mustacchi 
3647d14abf15SRobert Mustacchi 		/* Set the multicast filter bits before writing it into
3648d14abf15SRobert Mustacchi 		 * the internal memory.
3649d14abf15SRobert Mustacchi 		 */
3650d14abf15SRobert Mustacchi 		switch (cmd) {
3651d14abf15SRobert Mustacchi 		case ECORE_MCAST_CMD_ADD:
3652d14abf15SRobert Mustacchi 			ecore_mcast_hdl_add_e1h(pdev, o, p, mc_filter);
3653d14abf15SRobert Mustacchi 			break;
3654d14abf15SRobert Mustacchi 
3655d14abf15SRobert Mustacchi 		case ECORE_MCAST_CMD_DEL:
3656d14abf15SRobert Mustacchi 			ECORE_MSG(pdev,
3657d14abf15SRobert Mustacchi 				  "Invalidating multicast MACs configuration\n");
3658d14abf15SRobert Mustacchi 
3659d14abf15SRobert Mustacchi 			/* clear the registry */
3660d14abf15SRobert Mustacchi 			mm_memset(o->registry.aprox_match.vec, 0,
3661d14abf15SRobert Mustacchi 			       sizeof(o->registry.aprox_match.vec));
3662d14abf15SRobert Mustacchi 			break;
3663d14abf15SRobert Mustacchi 
3664d14abf15SRobert Mustacchi 		case ECORE_MCAST_CMD_RESTORE:
3665d14abf15SRobert Mustacchi 			ecore_mcast_hdl_restore_e1h(pdev, o, p, mc_filter);
3666d14abf15SRobert Mustacchi 			break;
3667d14abf15SRobert Mustacchi 
3668d14abf15SRobert Mustacchi 		default:
3669d14abf15SRobert Mustacchi 			ECORE_ERR("Unknown command: %d\n", cmd);
3670d14abf15SRobert Mustacchi 			return ECORE_INVAL;
3671d14abf15SRobert Mustacchi 		}
3672d14abf15SRobert Mustacchi 
3673d14abf15SRobert Mustacchi 		/* Set the mcast filter in the internal memory */
3674d14abf15SRobert Mustacchi 		for (i = 0; i < MC_HASH_SIZE; i++)
3675d14abf15SRobert Mustacchi 			REG_WR(pdev, MC_HASH_OFFSET(pdev, i), mc_filter[i]);
3676d14abf15SRobert Mustacchi 	} else
3677d14abf15SRobert Mustacchi 		/* clear the registry */
3678d14abf15SRobert Mustacchi 		mm_memset(o->registry.aprox_match.vec, 0,
3679d14abf15SRobert Mustacchi 		       sizeof(o->registry.aprox_match.vec));
3680d14abf15SRobert Mustacchi 
3681d14abf15SRobert Mustacchi 	/* We are done */
3682d14abf15SRobert Mustacchi 	r->clear_pending(r);
3683d14abf15SRobert Mustacchi 
3684d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
3685d14abf15SRobert Mustacchi }
3686d14abf15SRobert Mustacchi 
ecore_mcast_validate_e1(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p,enum ecore_mcast_cmd cmd)3687d14abf15SRobert Mustacchi static int ecore_mcast_validate_e1(struct _lm_device_t *pdev,
3688d14abf15SRobert Mustacchi 				   struct ecore_mcast_ramrod_params *p,
3689d14abf15SRobert Mustacchi 				   enum ecore_mcast_cmd cmd)
3690d14abf15SRobert Mustacchi {
3691d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o = p->mcast_obj;
3692d14abf15SRobert Mustacchi 	int reg_sz = o->get_registry_size(o);
3693d14abf15SRobert Mustacchi 
3694d14abf15SRobert Mustacchi 	switch (cmd) {
3695d14abf15SRobert Mustacchi 	/* DEL command deletes all currently configured MACs */
3696d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_DEL:
3697d14abf15SRobert Mustacchi 		o->set_registry_size(o, 0);
3698*6680ee99SToomas Soome 		/* FALLTHROUGH */
3699d14abf15SRobert Mustacchi 
3700d14abf15SRobert Mustacchi 	/* RESTORE command will restore the entire multicast configuration */
3701d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_RESTORE:
3702d14abf15SRobert Mustacchi 		p->mcast_list_len = reg_sz;
3703d14abf15SRobert Mustacchi 		  ECORE_MSG(pdev, "Command %d, p->mcast_list_len=%d\n",
3704d14abf15SRobert Mustacchi 				  cmd, p->mcast_list_len);
3705d14abf15SRobert Mustacchi 		break;
3706d14abf15SRobert Mustacchi 
3707d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_ADD:
3708d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_CONT:
3709d14abf15SRobert Mustacchi 		/* Multicast MACs on 57710 are configured as unicast MACs and
3710d14abf15SRobert Mustacchi 		 * there is only a limited number of CAM entries for that
3711d14abf15SRobert Mustacchi 		 * matter.
3712d14abf15SRobert Mustacchi 		 */
3713d14abf15SRobert Mustacchi 		if (p->mcast_list_len > o->max_cmd_len) {
3714d14abf15SRobert Mustacchi 			ECORE_ERR("Can't configure more than %d multicast MACs on 57710\n",
3715d14abf15SRobert Mustacchi 				  o->max_cmd_len);
3716d14abf15SRobert Mustacchi 			return ECORE_INVAL;
3717d14abf15SRobert Mustacchi 		}
3718d14abf15SRobert Mustacchi 		/* Every configured MAC should be cleared if DEL command is
3719d14abf15SRobert Mustacchi 		 * called. Only the last ADD command is relevant as long as
3720d14abf15SRobert Mustacchi 		 * every ADD commands overrides the previous configuration.
3721d14abf15SRobert Mustacchi 		 */
3722d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "p->mcast_list_len=%d\n", p->mcast_list_len);
3723d14abf15SRobert Mustacchi 		if (p->mcast_list_len > 0)
3724d14abf15SRobert Mustacchi 			o->set_registry_size(o, p->mcast_list_len);
3725d14abf15SRobert Mustacchi 
3726d14abf15SRobert Mustacchi 		break;
3727d14abf15SRobert Mustacchi 
3728d14abf15SRobert Mustacchi 	default:
3729d14abf15SRobert Mustacchi 		ECORE_ERR("Unknown command: %d\n", cmd);
3730d14abf15SRobert Mustacchi 		return ECORE_INVAL;
3731d14abf15SRobert Mustacchi 	}
3732d14abf15SRobert Mustacchi 
3733d14abf15SRobert Mustacchi 	/* We want to ensure that commands are executed one by one for 57710.
3734d14abf15SRobert Mustacchi 	 * Therefore each none-empty command will consume o->max_cmd_len.
3735d14abf15SRobert Mustacchi 	 */
3736d14abf15SRobert Mustacchi 	if (p->mcast_list_len)
3737d14abf15SRobert Mustacchi 		o->total_pending_num += o->max_cmd_len;
3738d14abf15SRobert Mustacchi 
3739d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
3740d14abf15SRobert Mustacchi }
3741d14abf15SRobert Mustacchi 
ecore_mcast_revert_e1(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p,int old_num_macs)3742d14abf15SRobert Mustacchi static void ecore_mcast_revert_e1(struct _lm_device_t *pdev,
3743d14abf15SRobert Mustacchi 				      struct ecore_mcast_ramrod_params *p,
3744d14abf15SRobert Mustacchi 				      int old_num_macs)
3745d14abf15SRobert Mustacchi {
3746d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o = p->mcast_obj;
3747d14abf15SRobert Mustacchi 
3748d14abf15SRobert Mustacchi 	o->set_registry_size(o, old_num_macs);
3749d14abf15SRobert Mustacchi 
3750d14abf15SRobert Mustacchi 	/* If current command hasn't been handled yet and we are
3751d14abf15SRobert Mustacchi 	 * here means that it's meant to be dropped and we have to
3752d14abf15SRobert Mustacchi 	 * update the number of outstanding MACs accordingly.
3753d14abf15SRobert Mustacchi 	 */
3754d14abf15SRobert Mustacchi 	if (p->mcast_list_len)
3755d14abf15SRobert Mustacchi 		o->total_pending_num -= o->max_cmd_len;
3756d14abf15SRobert Mustacchi }
3757d14abf15SRobert Mustacchi 
ecore_mcast_set_one_rule_e1(struct _lm_device_t * pdev,struct ecore_mcast_obj * o,int idx,union ecore_mcast_config_data * cfg_data,enum ecore_mcast_cmd cmd)3758d14abf15SRobert Mustacchi static void ecore_mcast_set_one_rule_e1(struct _lm_device_t *pdev,
3759d14abf15SRobert Mustacchi 					struct ecore_mcast_obj *o, int idx,
3760d14abf15SRobert Mustacchi 					union ecore_mcast_config_data *cfg_data,
3761d14abf15SRobert Mustacchi 					enum ecore_mcast_cmd cmd)
3762d14abf15SRobert Mustacchi {
3763d14abf15SRobert Mustacchi 	struct ecore_raw_obj *r = &o->raw;
3764d14abf15SRobert Mustacchi 	struct mac_configuration_cmd *data =
3765d14abf15SRobert Mustacchi 		(struct mac_configuration_cmd *)(r->rdata);
3766d14abf15SRobert Mustacchi 
3767d14abf15SRobert Mustacchi 	/* copy mac */
3768d14abf15SRobert Mustacchi 	if ((cmd == ECORE_MCAST_CMD_ADD) || (cmd == ECORE_MCAST_CMD_RESTORE)) {
3769d14abf15SRobert Mustacchi 		ecore_set_fw_mac_addr(&data->config_table[idx].msb_mac_addr,
3770d14abf15SRobert Mustacchi 				      &data->config_table[idx].middle_mac_addr,
3771d14abf15SRobert Mustacchi 				      &data->config_table[idx].lsb_mac_addr,
3772d14abf15SRobert Mustacchi 				      cfg_data->mac);
3773d14abf15SRobert Mustacchi 
3774d14abf15SRobert Mustacchi 		data->config_table[idx].vlan_id = 0;
3775d14abf15SRobert Mustacchi 		data->config_table[idx].pf_id = r->func_id;
3776d14abf15SRobert Mustacchi 		data->config_table[idx].clients_bit_vector =
3777d14abf15SRobert Mustacchi 			mm_cpu_to_le32(1 << r->cl_id);
3778d14abf15SRobert Mustacchi 
3779d14abf15SRobert Mustacchi 		ECORE_SET_FLAG(data->config_table[idx].flags,
3780d14abf15SRobert Mustacchi 			       MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
3781d14abf15SRobert Mustacchi 			       T_ETH_MAC_COMMAND_SET);
3782d14abf15SRobert Mustacchi 	}
3783d14abf15SRobert Mustacchi }
3784d14abf15SRobert Mustacchi 
3785d14abf15SRobert Mustacchi /**
3786d14abf15SRobert Mustacchi  * ecore_mcast_set_rdata_hdr_e1  - set header values in mac_configuration_cmd
3787d14abf15SRobert Mustacchi  *
3788d14abf15SRobert Mustacchi  * @pdev:	device handle
3789d14abf15SRobert Mustacchi  * @p:
3790d14abf15SRobert Mustacchi  * @len:	number of rules to handle
3791d14abf15SRobert Mustacchi  */
ecore_mcast_set_rdata_hdr_e1(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p,u8 len)3792d14abf15SRobert Mustacchi static INLINE void ecore_mcast_set_rdata_hdr_e1(struct _lm_device_t *pdev,
3793d14abf15SRobert Mustacchi 					struct ecore_mcast_ramrod_params *p,
3794d14abf15SRobert Mustacchi 					u8 len)
3795d14abf15SRobert Mustacchi {
3796d14abf15SRobert Mustacchi 	struct ecore_raw_obj *r = &p->mcast_obj->raw;
3797d14abf15SRobert Mustacchi 	struct mac_configuration_cmd *data =
3798d14abf15SRobert Mustacchi 		(struct mac_configuration_cmd *)(r->rdata);
3799d14abf15SRobert Mustacchi 
3800d14abf15SRobert Mustacchi 	u8 offset = (CHIP_REV_IS_SLOW(pdev) ?
3801d14abf15SRobert Mustacchi 		     ECORE_MAX_EMUL_MULTI*(1 + r->func_id) :
3802d14abf15SRobert Mustacchi 		     ECORE_MAX_MULTICAST*(1 + r->func_id));
3803d14abf15SRobert Mustacchi 
3804d14abf15SRobert Mustacchi 	data->hdr.offset = offset;
3805d14abf15SRobert Mustacchi 	data->hdr.client_id = mm_cpu_to_le16(0xff);
3806d14abf15SRobert Mustacchi 	data->hdr.echo = mm_cpu_to_le32((r->cid & ECORE_SWCID_MASK) |
3807d14abf15SRobert Mustacchi 				     (ECORE_FILTER_MCAST_PENDING <<
3808d14abf15SRobert Mustacchi 				      ECORE_SWCID_SHIFT));
3809d14abf15SRobert Mustacchi 	data->hdr.length = len;
3810d14abf15SRobert Mustacchi }
3811d14abf15SRobert Mustacchi 
3812d14abf15SRobert Mustacchi /**
3813d14abf15SRobert Mustacchi  * ecore_mcast_handle_restore_cmd_e1 - restore command for 57710
3814d14abf15SRobert Mustacchi  *
3815d14abf15SRobert Mustacchi  * @pdev:	device handle
3816d14abf15SRobert Mustacchi  * @o:
3817d14abf15SRobert Mustacchi  * @start_idx:	index in the registry to start from
3818d14abf15SRobert Mustacchi  * @rdata_idx:	index in the ramrod data to start from
3819d14abf15SRobert Mustacchi  *
3820d14abf15SRobert Mustacchi  * restore command for 57710 is like all other commands - always a stand alone
3821d14abf15SRobert Mustacchi  * command - start_idx and rdata_idx will always be 0. This function will always
3822d14abf15SRobert Mustacchi  * succeed.
3823d14abf15SRobert Mustacchi  * returns -1 to comply with 57712 variant.
3824d14abf15SRobert Mustacchi  */
ecore_mcast_handle_restore_cmd_e1(struct _lm_device_t * pdev,struct ecore_mcast_obj * o,int start_idx,int * rdata_idx)3825d14abf15SRobert Mustacchi static INLINE int ecore_mcast_handle_restore_cmd_e1(
3826d14abf15SRobert Mustacchi 	struct _lm_device_t *pdev, struct ecore_mcast_obj *o , int start_idx,
3827d14abf15SRobert Mustacchi 	int *rdata_idx)
3828d14abf15SRobert Mustacchi {
3829d14abf15SRobert Mustacchi 	struct ecore_mcast_mac_elem *elem;
3830d14abf15SRobert Mustacchi 	int i = 0;
3831d14abf15SRobert Mustacchi 	union ecore_mcast_config_data cfg_data = {NULL};
3832d14abf15SRobert Mustacchi 
3833d14abf15SRobert Mustacchi 	/* go through the registry and configure the MACs from it. */
3834d14abf15SRobert Mustacchi 	ECORE_LIST_FOR_EACH_ENTRY(elem, &o->registry.exact_match.macs, link,
3835d14abf15SRobert Mustacchi 				  struct ecore_mcast_mac_elem) {
3836d14abf15SRobert Mustacchi 		cfg_data.mac = &elem->mac[0];
3837d14abf15SRobert Mustacchi 		o->set_one_rule(pdev, o, i, &cfg_data, ECORE_MCAST_CMD_RESTORE);
3838d14abf15SRobert Mustacchi 
3839d14abf15SRobert Mustacchi 		i++;
3840d14abf15SRobert Mustacchi 
3841d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "About to configure %02x:%02x:%02x:%02x:%02x:%02x mcast MAC\n",
3842d14abf15SRobert Mustacchi 			  cfg_data.mac[0], cfg_data.mac[1], cfg_data.mac[2], cfg_data.mac[3], cfg_data.mac[4], cfg_data.mac[5]);
3843d14abf15SRobert Mustacchi 	}
3844d14abf15SRobert Mustacchi 
3845d14abf15SRobert Mustacchi 	*rdata_idx = i;
3846d14abf15SRobert Mustacchi 
3847d14abf15SRobert Mustacchi 	return -1;
3848d14abf15SRobert Mustacchi }
3849d14abf15SRobert Mustacchi 
ecore_mcast_handle_pending_cmds_e1(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p)3850d14abf15SRobert Mustacchi static INLINE int ecore_mcast_handle_pending_cmds_e1(
3851d14abf15SRobert Mustacchi 	struct _lm_device_t *pdev, struct ecore_mcast_ramrod_params *p)
3852d14abf15SRobert Mustacchi {
3853d14abf15SRobert Mustacchi 	struct ecore_pending_mcast_cmd *cmd_pos;
3854d14abf15SRobert Mustacchi 	struct ecore_mcast_mac_elem *pmac_pos;
3855d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o = p->mcast_obj;
3856d14abf15SRobert Mustacchi 	union ecore_mcast_config_data cfg_data = {NULL};
3857d14abf15SRobert Mustacchi 	int cnt = 0;
3858d14abf15SRobert Mustacchi 
3859d14abf15SRobert Mustacchi 	/* If nothing to be done - return */
3860d14abf15SRobert Mustacchi 	if (ECORE_LIST_IS_EMPTY(&o->pending_cmds_head))
3861d14abf15SRobert Mustacchi 		return 0;
3862d14abf15SRobert Mustacchi 
3863d14abf15SRobert Mustacchi 	/* Handle the first command */
3864d14abf15SRobert Mustacchi 	cmd_pos = ECORE_LIST_FIRST_ENTRY(&o->pending_cmds_head,
3865d14abf15SRobert Mustacchi 					 struct ecore_pending_mcast_cmd, link);
3866d14abf15SRobert Mustacchi 
3867d14abf15SRobert Mustacchi 	switch (cmd_pos->type) {
3868d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_ADD:
3869d14abf15SRobert Mustacchi 		ECORE_LIST_FOR_EACH_ENTRY(pmac_pos, &cmd_pos->data.macs_head,
3870d14abf15SRobert Mustacchi 					  link, struct ecore_mcast_mac_elem) {
3871d14abf15SRobert Mustacchi 			cfg_data.mac = &pmac_pos->mac[0];
3872d14abf15SRobert Mustacchi 			o->set_one_rule(pdev, o, cnt, &cfg_data, cmd_pos->type);
3873d14abf15SRobert Mustacchi 
3874d14abf15SRobert Mustacchi 			cnt++;
3875d14abf15SRobert Mustacchi 
3876d14abf15SRobert Mustacchi 			ECORE_MSG(pdev, "About to configure %02x:%02x:%02x:%02x:%02x:%02x mcast MAC\n",
3877d14abf15SRobert Mustacchi 				  pmac_pos->mac[0], pmac_pos->mac[1], pmac_pos->mac[2], pmac_pos->mac[3], pmac_pos->mac[4], pmac_pos->mac[5]);
3878d14abf15SRobert Mustacchi 		}
3879d14abf15SRobert Mustacchi 		break;
3880d14abf15SRobert Mustacchi 
3881d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_DEL:
3882d14abf15SRobert Mustacchi 		cnt = cmd_pos->data.macs_num;
3883d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "About to delete %d multicast MACs\n", cnt);
3884d14abf15SRobert Mustacchi 		break;
3885d14abf15SRobert Mustacchi 
3886d14abf15SRobert Mustacchi 	case ECORE_MCAST_CMD_RESTORE:
3887d14abf15SRobert Mustacchi 		o->hdl_restore(pdev, o, 0, &cnt);
3888d14abf15SRobert Mustacchi 		break;
3889d14abf15SRobert Mustacchi 
3890d14abf15SRobert Mustacchi 	default:
3891d14abf15SRobert Mustacchi 		ECORE_ERR("Unknown command: %d\n", cmd_pos->type);
3892d14abf15SRobert Mustacchi 		return ECORE_INVAL;
3893d14abf15SRobert Mustacchi 	}
3894d14abf15SRobert Mustacchi 
3895d14abf15SRobert Mustacchi 	ECORE_LIST_REMOVE_ENTRY(&cmd_pos->link, &o->pending_cmds_head);
3896d14abf15SRobert Mustacchi 	ECORE_FREE(pdev, cmd_pos, cmd_pos->alloc_len);
3897d14abf15SRobert Mustacchi 
3898d14abf15SRobert Mustacchi 	return cnt;
3899d14abf15SRobert Mustacchi }
3900d14abf15SRobert Mustacchi 
3901d14abf15SRobert Mustacchi /**
3902d14abf15SRobert Mustacchi  * ecore_get_fw_mac_addr - revert the ecore_set_fw_mac_addr().
3903d14abf15SRobert Mustacchi  *
3904d14abf15SRobert Mustacchi  * @fw_hi:
3905d14abf15SRobert Mustacchi  * @fw_mid:
3906d14abf15SRobert Mustacchi  * @fw_lo:
3907d14abf15SRobert Mustacchi  * @mac:
3908d14abf15SRobert Mustacchi  */
ecore_get_fw_mac_addr(__le16 * fw_hi,__le16 * fw_mid,__le16 * fw_lo,u8 * mac)3909d14abf15SRobert Mustacchi static INLINE void ecore_get_fw_mac_addr(__le16 *fw_hi, __le16 *fw_mid,
3910d14abf15SRobert Mustacchi 					 __le16 *fw_lo, u8 *mac)
3911d14abf15SRobert Mustacchi {
3912d14abf15SRobert Mustacchi 	mac[1] = ((u8 *)fw_hi)[0];
3913d14abf15SRobert Mustacchi 	mac[0] = ((u8 *)fw_hi)[1];
3914d14abf15SRobert Mustacchi 	mac[3] = ((u8 *)fw_mid)[0];
3915d14abf15SRobert Mustacchi 	mac[2] = ((u8 *)fw_mid)[1];
3916d14abf15SRobert Mustacchi 	mac[5] = ((u8 *)fw_lo)[0];
3917d14abf15SRobert Mustacchi 	mac[4] = ((u8 *)fw_lo)[1];
3918d14abf15SRobert Mustacchi }
3919d14abf15SRobert Mustacchi 
3920d14abf15SRobert Mustacchi /**
3921d14abf15SRobert Mustacchi  * ecore_mcast_refresh_registry_e1 -
3922d14abf15SRobert Mustacchi  *
3923d14abf15SRobert Mustacchi  * @pdev:	device handle
3924d14abf15SRobert Mustacchi  * @cnt:
3925d14abf15SRobert Mustacchi  *
3926d14abf15SRobert Mustacchi  * Check the ramrod data first entry flag to see if it's a DELETE or ADD command
3927d14abf15SRobert Mustacchi  * and update the registry correspondingly: if ADD - allocate a memory and add
3928d14abf15SRobert Mustacchi  * the entries to the registry (list), if DELETE - clear the registry and free
3929d14abf15SRobert Mustacchi  * the memory.
3930d14abf15SRobert Mustacchi  */
ecore_mcast_refresh_registry_e1(struct _lm_device_t * pdev,struct ecore_mcast_obj * o)3931d14abf15SRobert Mustacchi static INLINE int ecore_mcast_refresh_registry_e1(struct _lm_device_t *pdev,
3932d14abf15SRobert Mustacchi 						  struct ecore_mcast_obj *o)
3933d14abf15SRobert Mustacchi {
3934d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &o->raw;
3935d14abf15SRobert Mustacchi 	struct ecore_mcast_mac_elem *elem;
3936d14abf15SRobert Mustacchi 	struct mac_configuration_cmd *data =
3937d14abf15SRobert Mustacchi 			(struct mac_configuration_cmd *)(raw->rdata);
3938d14abf15SRobert Mustacchi 
3939d14abf15SRobert Mustacchi 	/* If first entry contains a SET bit - the command was ADD,
3940d14abf15SRobert Mustacchi 	 * otherwise - DEL_ALL
3941d14abf15SRobert Mustacchi 	 */
3942d14abf15SRobert Mustacchi 	if (ECORE_GET_FLAG(data->config_table[0].flags,
3943d14abf15SRobert Mustacchi 			MAC_CONFIGURATION_ENTRY_ACTION_TYPE)) {
3944d14abf15SRobert Mustacchi 		int i, len = data->hdr.length;
3945d14abf15SRobert Mustacchi 
3946d14abf15SRobert Mustacchi 		/* Break if it was a RESTORE command */
3947d14abf15SRobert Mustacchi 		if (!ECORE_LIST_IS_EMPTY(&o->registry.exact_match.macs))
3948d14abf15SRobert Mustacchi 			return ECORE_SUCCESS;
3949d14abf15SRobert Mustacchi 
3950d14abf15SRobert Mustacchi 		elem = ECORE_CALLOC(len, sizeof(*elem), GFP_ATOMIC, pdev);
3951d14abf15SRobert Mustacchi 		if (!elem) {
3952d14abf15SRobert Mustacchi 			ECORE_ERR("Failed to allocate registry memory\n");
3953d14abf15SRobert Mustacchi 			return ECORE_NOMEM;
3954d14abf15SRobert Mustacchi 		}
3955d14abf15SRobert Mustacchi 
3956d14abf15SRobert Mustacchi 		for (i = 0; i < len; i++, elem++) {
3957d14abf15SRobert Mustacchi 			ecore_get_fw_mac_addr(
3958d14abf15SRobert Mustacchi 				&data->config_table[i].msb_mac_addr,
3959d14abf15SRobert Mustacchi 				&data->config_table[i].middle_mac_addr,
3960d14abf15SRobert Mustacchi 				&data->config_table[i].lsb_mac_addr,
3961d14abf15SRobert Mustacchi 				elem->mac);
3962d14abf15SRobert Mustacchi 			ECORE_MSG(pdev, "Adding registry entry for [%02x:%02x:%02x:%02x:%02x:%02x]\n",
3963d14abf15SRobert Mustacchi 				  elem->mac[0], elem->mac[1], elem->mac[2], elem->mac[3], elem->mac[4], elem->mac[5]);
3964d14abf15SRobert Mustacchi 			ECORE_LIST_PUSH_TAIL(&elem->link,
3965d14abf15SRobert Mustacchi 					     &o->registry.exact_match.macs);
3966d14abf15SRobert Mustacchi 		}
3967d14abf15SRobert Mustacchi 	} else {
3968d14abf15SRobert Mustacchi 		elem = ECORE_LIST_FIRST_ENTRY(&o->registry.exact_match.macs,
3969d14abf15SRobert Mustacchi 					      struct ecore_mcast_mac_elem,
3970d14abf15SRobert Mustacchi 					      link);
3971d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "Deleting a registry\n");
3972d14abf15SRobert Mustacchi 		ECORE_FREE(pdev, elem, sizeof(*elem));
3973d14abf15SRobert Mustacchi 		ECORE_LIST_INIT(&o->registry.exact_match.macs);
3974d14abf15SRobert Mustacchi 	}
3975d14abf15SRobert Mustacchi 
3976d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
3977d14abf15SRobert Mustacchi }
3978d14abf15SRobert Mustacchi 
ecore_mcast_setup_e1(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p,enum ecore_mcast_cmd cmd)3979d14abf15SRobert Mustacchi static int ecore_mcast_setup_e1(struct _lm_device_t *pdev,
3980d14abf15SRobert Mustacchi 				struct ecore_mcast_ramrod_params *p,
3981d14abf15SRobert Mustacchi 				enum ecore_mcast_cmd cmd)
3982d14abf15SRobert Mustacchi {
3983d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o = p->mcast_obj;
3984d14abf15SRobert Mustacchi 	struct ecore_raw_obj *raw = &o->raw;
3985d14abf15SRobert Mustacchi 	struct mac_configuration_cmd *data =
3986d14abf15SRobert Mustacchi 		(struct mac_configuration_cmd *)(raw->rdata);
3987d14abf15SRobert Mustacchi 	int cnt = 0, i, rc;
3988d14abf15SRobert Mustacchi 
3989d14abf15SRobert Mustacchi 	/* Reset the ramrod data buffer */
3990d14abf15SRobert Mustacchi 	mm_memset(data, 0, sizeof(*data));
3991d14abf15SRobert Mustacchi 
3992d14abf15SRobert Mustacchi 	/* First set all entries as invalid */
3993d14abf15SRobert Mustacchi 	for (i = 0; i < o->max_cmd_len ; i++)
3994d14abf15SRobert Mustacchi 		ECORE_SET_FLAG(data->config_table[i].flags,
3995d14abf15SRobert Mustacchi 			MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
3996d14abf15SRobert Mustacchi 			T_ETH_MAC_COMMAND_INVALIDATE);
3997d14abf15SRobert Mustacchi 
3998d14abf15SRobert Mustacchi 	/* Handle pending commands first */
3999d14abf15SRobert Mustacchi 	cnt = ecore_mcast_handle_pending_cmds_e1(pdev, p);
4000d14abf15SRobert Mustacchi 
4001d14abf15SRobert Mustacchi 	/* If there are no more pending commands - clear SCHEDULED state */
4002d14abf15SRobert Mustacchi 	if (ECORE_LIST_IS_EMPTY(&o->pending_cmds_head))
4003d14abf15SRobert Mustacchi 		o->clear_sched(o);
4004d14abf15SRobert Mustacchi 
4005d14abf15SRobert Mustacchi 	/* The below may be TRUE iff there were no pending commands */
4006d14abf15SRobert Mustacchi 	if (!cnt)
4007d14abf15SRobert Mustacchi 		cnt = ecore_mcast_handle_current_cmd(pdev, p, cmd, 0);
4008d14abf15SRobert Mustacchi 
4009d14abf15SRobert Mustacchi 	/* For 57710 every command has o->max_cmd_len length to ensure that
4010d14abf15SRobert Mustacchi 	 * commands are done one at a time.
4011d14abf15SRobert Mustacchi 	 */
4012d14abf15SRobert Mustacchi 	o->total_pending_num -= o->max_cmd_len;
4013d14abf15SRobert Mustacchi 
4014d14abf15SRobert Mustacchi 	/* send a ramrod */
4015d14abf15SRobert Mustacchi 
4016d14abf15SRobert Mustacchi 	DbgBreakIf(cnt > o->max_cmd_len);
4017d14abf15SRobert Mustacchi 
4018d14abf15SRobert Mustacchi 	/* Set ramrod header (in particular, a number of entries to update) */
4019d14abf15SRobert Mustacchi 	ecore_mcast_set_rdata_hdr_e1(pdev, p, (u8)cnt);
4020d14abf15SRobert Mustacchi 
4021d14abf15SRobert Mustacchi 	/* update a registry: we need the registry contents to be always up
4022d14abf15SRobert Mustacchi 	 * to date in order to be able to execute a RESTORE opcode. Here
4023d14abf15SRobert Mustacchi 	 * we use the fact that for 57710 we sent one command at a time
4024d14abf15SRobert Mustacchi 	 * hence we may take the registry update out of the command handling
4025d14abf15SRobert Mustacchi 	 * and do it in a simpler way here.
4026d14abf15SRobert Mustacchi 	 */
4027d14abf15SRobert Mustacchi 	rc = ecore_mcast_refresh_registry_e1(pdev, o);
4028d14abf15SRobert Mustacchi 	if (rc)
4029d14abf15SRobert Mustacchi 		return rc;
4030d14abf15SRobert Mustacchi 
4031d14abf15SRobert Mustacchi 	/* If CLEAR_ONLY was requested - don't send a ramrod and clear
4032d14abf15SRobert Mustacchi 	 * RAMROD_PENDING status immediately.
4033d14abf15SRobert Mustacchi 	 */
4034d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) {
4035d14abf15SRobert Mustacchi 		raw->clear_pending(raw);
4036d14abf15SRobert Mustacchi 		return ECORE_SUCCESS;
4037d14abf15SRobert Mustacchi 	} else {
4038d14abf15SRobert Mustacchi 		/* No need for an explicit memory barrier here as long as we
4039d14abf15SRobert Mustacchi 		 * ensure the ordering of writing to the SPQ element
4040d14abf15SRobert Mustacchi 		 * and updating of the SPQ producer which involves a memory
4041d14abf15SRobert Mustacchi 		 * read. If the memory read is removed we will have to put a
4042d14abf15SRobert Mustacchi 		 * full memory barrier there (inside ecore_sp_post()).
4043d14abf15SRobert Mustacchi 		 */
4044d14abf15SRobert Mustacchi 
4045d14abf15SRobert Mustacchi 		/* Send a ramrod */
4046d14abf15SRobert Mustacchi 		rc = ecore_sp_post( pdev,
4047d14abf15SRobert Mustacchi 				    RAMROD_CMD_ID_ETH_SET_MAC,
4048d14abf15SRobert Mustacchi 				    raw->cid,
4049d14abf15SRobert Mustacchi 				    raw->rdata_mapping.as_u64,
4050d14abf15SRobert Mustacchi 				    ETH_CONNECTION_TYPE);
4051d14abf15SRobert Mustacchi 		if (rc)
4052d14abf15SRobert Mustacchi 			return rc;
4053d14abf15SRobert Mustacchi 
4054d14abf15SRobert Mustacchi 		/* Ramrod completion is pending */
4055d14abf15SRobert Mustacchi 		return ECORE_PENDING;
4056d14abf15SRobert Mustacchi 	}
4057d14abf15SRobert Mustacchi }
4058d14abf15SRobert Mustacchi 
ecore_mcast_get_registry_size_exact(struct ecore_mcast_obj * o)4059d14abf15SRobert Mustacchi static int ecore_mcast_get_registry_size_exact(struct ecore_mcast_obj *o)
4060d14abf15SRobert Mustacchi {
4061d14abf15SRobert Mustacchi 	return o->registry.exact_match.num_macs_set;
4062d14abf15SRobert Mustacchi }
4063d14abf15SRobert Mustacchi 
ecore_mcast_get_registry_size_aprox(struct ecore_mcast_obj * o)4064d14abf15SRobert Mustacchi static int ecore_mcast_get_registry_size_aprox(struct ecore_mcast_obj *o)
4065d14abf15SRobert Mustacchi {
4066d14abf15SRobert Mustacchi 	return o->registry.aprox_match.num_bins_set;
4067d14abf15SRobert Mustacchi }
4068d14abf15SRobert Mustacchi 
ecore_mcast_set_registry_size_exact(struct ecore_mcast_obj * o,int n)4069d14abf15SRobert Mustacchi static void ecore_mcast_set_registry_size_exact(struct ecore_mcast_obj *o,
4070d14abf15SRobert Mustacchi 						int n)
4071d14abf15SRobert Mustacchi {
4072d14abf15SRobert Mustacchi 	o->registry.exact_match.num_macs_set = n;
4073d14abf15SRobert Mustacchi }
4074d14abf15SRobert Mustacchi 
ecore_mcast_set_registry_size_aprox(struct ecore_mcast_obj * o,int n)4075d14abf15SRobert Mustacchi static void ecore_mcast_set_registry_size_aprox(struct ecore_mcast_obj *o,
4076d14abf15SRobert Mustacchi 						int n)
4077d14abf15SRobert Mustacchi {
4078d14abf15SRobert Mustacchi 	o->registry.aprox_match.num_bins_set = n;
4079d14abf15SRobert Mustacchi }
4080d14abf15SRobert Mustacchi 
ecore_config_mcast(struct _lm_device_t * pdev,struct ecore_mcast_ramrod_params * p,enum ecore_mcast_cmd cmd)4081d14abf15SRobert Mustacchi int ecore_config_mcast(struct _lm_device_t *pdev,
4082d14abf15SRobert Mustacchi 		       struct ecore_mcast_ramrod_params *p,
4083d14abf15SRobert Mustacchi 		       enum ecore_mcast_cmd cmd)
4084d14abf15SRobert Mustacchi {
4085d14abf15SRobert Mustacchi 	struct ecore_mcast_obj *o = p->mcast_obj;
4086d14abf15SRobert Mustacchi 	struct ecore_raw_obj *r = &o->raw;
4087d14abf15SRobert Mustacchi 	int rc = 0, old_reg_size;
4088d14abf15SRobert Mustacchi 
4089d14abf15SRobert Mustacchi 	/* This is needed to recover number of currently configured mcast macs
4090d14abf15SRobert Mustacchi 	 * in case of failure.
4091d14abf15SRobert Mustacchi 	 */
4092d14abf15SRobert Mustacchi 	old_reg_size = o->get_registry_size(o);
4093d14abf15SRobert Mustacchi 
4094d14abf15SRobert Mustacchi 	/* Do some calculations and checks */
4095d14abf15SRobert Mustacchi 	rc = o->validate(pdev, p, cmd);
4096d14abf15SRobert Mustacchi 	if (rc)
4097d14abf15SRobert Mustacchi 		return rc;
4098d14abf15SRobert Mustacchi 
4099d14abf15SRobert Mustacchi 	/* Return if there is no work to do */
4100d14abf15SRobert Mustacchi 	if ((!p->mcast_list_len) && (!o->check_sched(o)))
4101d14abf15SRobert Mustacchi 		return ECORE_SUCCESS;
4102d14abf15SRobert Mustacchi 
4103d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "o->total_pending_num=%d p->mcast_list_len=%d o->max_cmd_len=%d\n",
4104d14abf15SRobert Mustacchi 		  o->total_pending_num, p->mcast_list_len, o->max_cmd_len);
4105d14abf15SRobert Mustacchi 
4106d14abf15SRobert Mustacchi 	/* Enqueue the current command to the pending list if we can't complete
4107d14abf15SRobert Mustacchi 	 * it in the current iteration
4108d14abf15SRobert Mustacchi 	 */
4109d14abf15SRobert Mustacchi 	if (r->check_pending(r) ||
4110d14abf15SRobert Mustacchi 	    ((o->max_cmd_len > 0) && (o->total_pending_num > o->max_cmd_len))) {
4111d14abf15SRobert Mustacchi 		rc = o->enqueue_cmd(pdev, p->mcast_obj, p, cmd);
4112d14abf15SRobert Mustacchi 		if (rc < 0)
4113d14abf15SRobert Mustacchi 			goto error_exit1;
4114d14abf15SRobert Mustacchi 
4115d14abf15SRobert Mustacchi 		/* As long as the current command is in a command list we
4116d14abf15SRobert Mustacchi 		 * don't need to handle it separately.
4117d14abf15SRobert Mustacchi 		 */
4118d14abf15SRobert Mustacchi 		p->mcast_list_len = 0;
4119d14abf15SRobert Mustacchi 	}
4120d14abf15SRobert Mustacchi 
4121d14abf15SRobert Mustacchi 	if (!r->check_pending(r)) {
4122d14abf15SRobert Mustacchi 
4123d14abf15SRobert Mustacchi 		/* Set 'pending' state */
4124d14abf15SRobert Mustacchi 		r->set_pending(r);
4125d14abf15SRobert Mustacchi 
4126d14abf15SRobert Mustacchi 		/* Configure the new classification in the chip */
4127d14abf15SRobert Mustacchi 		rc = o->config_mcast(pdev, p, cmd);
4128d14abf15SRobert Mustacchi 		if (rc < 0)
4129d14abf15SRobert Mustacchi 			goto error_exit2;
4130d14abf15SRobert Mustacchi 
4131d14abf15SRobert Mustacchi 		/* Wait for a ramrod completion if was requested */
4132d14abf15SRobert Mustacchi 		if (ECORE_TEST_BIT(RAMROD_COMP_WAIT, &p->ramrod_flags))
4133d14abf15SRobert Mustacchi 			rc = o->wait_comp(pdev, o);
4134d14abf15SRobert Mustacchi 	}
4135d14abf15SRobert Mustacchi 
4136d14abf15SRobert Mustacchi 	return rc;
4137d14abf15SRobert Mustacchi 
4138d14abf15SRobert Mustacchi error_exit2:
4139d14abf15SRobert Mustacchi 	r->clear_pending(r);
4140d14abf15SRobert Mustacchi 
4141d14abf15SRobert Mustacchi error_exit1:
4142d14abf15SRobert Mustacchi 	o->revert(pdev, p, old_reg_size);
4143d14abf15SRobert Mustacchi 
4144d14abf15SRobert Mustacchi 	return rc;
4145d14abf15SRobert Mustacchi }
4146d14abf15SRobert Mustacchi 
ecore_mcast_clear_sched(struct ecore_mcast_obj * o)4147d14abf15SRobert Mustacchi static void ecore_mcast_clear_sched(struct ecore_mcast_obj *o)
4148d14abf15SRobert Mustacchi {
4149d14abf15SRobert Mustacchi 	smp_mb__before_atomic();
4150d14abf15SRobert Mustacchi 	ECORE_CLEAR_BIT(o->sched_state, o->raw.pstate);
4151d14abf15SRobert Mustacchi 	smp_mb__after_atomic();
4152d14abf15SRobert Mustacchi }
4153d14abf15SRobert Mustacchi 
ecore_mcast_set_sched(struct ecore_mcast_obj * o)4154d14abf15SRobert Mustacchi static void ecore_mcast_set_sched(struct ecore_mcast_obj *o)
4155d14abf15SRobert Mustacchi {
4156d14abf15SRobert Mustacchi 	smp_mb__before_atomic();
4157d14abf15SRobert Mustacchi 	ECORE_SET_BIT(o->sched_state, o->raw.pstate);
4158d14abf15SRobert Mustacchi 	smp_mb__after_atomic();
4159d14abf15SRobert Mustacchi }
4160d14abf15SRobert Mustacchi 
ecore_mcast_check_sched(struct ecore_mcast_obj * o)4161d14abf15SRobert Mustacchi static BOOL ecore_mcast_check_sched(struct ecore_mcast_obj *o)
4162d14abf15SRobert Mustacchi {
4163d14abf15SRobert Mustacchi 	return !!ECORE_TEST_BIT(o->sched_state, o->raw.pstate);
4164d14abf15SRobert Mustacchi }
4165d14abf15SRobert Mustacchi 
ecore_mcast_check_pending(struct ecore_mcast_obj * o)4166d14abf15SRobert Mustacchi static BOOL ecore_mcast_check_pending(struct ecore_mcast_obj *o)
4167d14abf15SRobert Mustacchi {
4168d14abf15SRobert Mustacchi 	return o->raw.check_pending(&o->raw) || o->check_sched(o);
4169d14abf15SRobert Mustacchi }
4170d14abf15SRobert Mustacchi #ifndef ECORE_ERASE
4171d14abf15SRobert Mustacchi typedef int (*enqueue_cmd_func)(struct _lm_device_t *pdev,
4172d14abf15SRobert Mustacchi 				struct ecore_mcast_obj *o,
4173d14abf15SRobert Mustacchi 				struct ecore_mcast_ramrod_params *p,
4174d14abf15SRobert Mustacchi 				enum ecore_mcast_cmd cmd);
4175d14abf15SRobert Mustacchi 
4176d14abf15SRobert Mustacchi typedef int (*hdl_restore_func)(struct _lm_device_t *pdev,
4177d14abf15SRobert Mustacchi 				struct ecore_mcast_obj *o,
4178d14abf15SRobert Mustacchi 				int start_bin, int *rdata_idx);
4179d14abf15SRobert Mustacchi 
4180d14abf15SRobert Mustacchi typedef void (*set_one_rule_func)(struct _lm_device_t *pdev,
4181d14abf15SRobert Mustacchi 				  struct ecore_mcast_obj *o, int idx,
4182d14abf15SRobert Mustacchi 				  union ecore_mcast_config_data *cfg_data,
4183d14abf15SRobert Mustacchi 				  enum ecore_mcast_cmd cmd);
4184d14abf15SRobert Mustacchi #endif
4185d14abf15SRobert Mustacchi 
ecore_init_mcast_obj(struct _lm_device_t * pdev,struct ecore_mcast_obj * mcast_obj,u8 mcast_cl_id,u32 mcast_cid,u8 func_id,u8 engine_id,void * rdata,lm_address_t rdata_mapping,int state,unsigned long * pstate,ecore_obj_type type)4186d14abf15SRobert Mustacchi void ecore_init_mcast_obj(struct _lm_device_t *pdev,
4187d14abf15SRobert Mustacchi 			  struct ecore_mcast_obj *mcast_obj,
4188d14abf15SRobert Mustacchi 			  u8 mcast_cl_id, u32 mcast_cid, u8 func_id,
4189d14abf15SRobert Mustacchi 			  u8 engine_id, void *rdata, lm_address_t rdata_mapping,
4190d14abf15SRobert Mustacchi 			  int state, unsigned long *pstate, ecore_obj_type type)
4191d14abf15SRobert Mustacchi {
4192d14abf15SRobert Mustacchi 	mm_memset(mcast_obj, 0, sizeof(*mcast_obj));
4193d14abf15SRobert Mustacchi 
4194d14abf15SRobert Mustacchi 	ecore_init_raw_obj(&mcast_obj->raw, mcast_cl_id, mcast_cid, func_id,
4195d14abf15SRobert Mustacchi 			   rdata, rdata_mapping, state, pstate, type);
4196d14abf15SRobert Mustacchi 
4197d14abf15SRobert Mustacchi 	mcast_obj->engine_id = engine_id;
4198d14abf15SRobert Mustacchi 
4199d14abf15SRobert Mustacchi 	ECORE_LIST_INIT(&mcast_obj->pending_cmds_head);
4200d14abf15SRobert Mustacchi 
4201d14abf15SRobert Mustacchi 	mcast_obj->sched_state = ECORE_FILTER_MCAST_SCHED;
4202d14abf15SRobert Mustacchi 	mcast_obj->check_sched = ecore_mcast_check_sched;
4203d14abf15SRobert Mustacchi 	mcast_obj->set_sched = ecore_mcast_set_sched;
4204d14abf15SRobert Mustacchi 	mcast_obj->clear_sched = ecore_mcast_clear_sched;
4205d14abf15SRobert Mustacchi 
4206d14abf15SRobert Mustacchi 	if (CHIP_IS_E1(pdev)) {
4207d14abf15SRobert Mustacchi 		mcast_obj->config_mcast      = ecore_mcast_setup_e1;
4208d14abf15SRobert Mustacchi 		mcast_obj->enqueue_cmd       = ecore_mcast_enqueue_cmd;
4209d14abf15SRobert Mustacchi 		mcast_obj->hdl_restore       =
4210d14abf15SRobert Mustacchi 			ecore_mcast_handle_restore_cmd_e1;
4211d14abf15SRobert Mustacchi 		mcast_obj->check_pending     = ecore_mcast_check_pending;
4212d14abf15SRobert Mustacchi 
4213d14abf15SRobert Mustacchi 		if (CHIP_REV_IS_SLOW(pdev))
4214d14abf15SRobert Mustacchi 			mcast_obj->max_cmd_len = ECORE_MAX_EMUL_MULTI;
4215d14abf15SRobert Mustacchi 		else
4216d14abf15SRobert Mustacchi 			mcast_obj->max_cmd_len = ECORE_MAX_MULTICAST;
4217d14abf15SRobert Mustacchi 
4218d14abf15SRobert Mustacchi 		mcast_obj->wait_comp         = ecore_mcast_wait;
4219d14abf15SRobert Mustacchi 		mcast_obj->set_one_rule      = ecore_mcast_set_one_rule_e1;
4220d14abf15SRobert Mustacchi 		mcast_obj->validate          = ecore_mcast_validate_e1;
4221d14abf15SRobert Mustacchi 		mcast_obj->revert            = ecore_mcast_revert_e1;
4222d14abf15SRobert Mustacchi 		mcast_obj->get_registry_size =
4223d14abf15SRobert Mustacchi 			ecore_mcast_get_registry_size_exact;
4224d14abf15SRobert Mustacchi 		mcast_obj->set_registry_size =
4225d14abf15SRobert Mustacchi 			ecore_mcast_set_registry_size_exact;
4226d14abf15SRobert Mustacchi 
4227d14abf15SRobert Mustacchi 		/* 57710 is the only chip that uses the exact match for mcast
4228d14abf15SRobert Mustacchi 		 * at the moment.
4229d14abf15SRobert Mustacchi 		 */
4230d14abf15SRobert Mustacchi 		ECORE_LIST_INIT(&mcast_obj->registry.exact_match.macs);
4231d14abf15SRobert Mustacchi 
4232d14abf15SRobert Mustacchi 	} else if (CHIP_IS_E1H(pdev)) {
4233d14abf15SRobert Mustacchi 		mcast_obj->config_mcast  = ecore_mcast_setup_e1h;
4234d14abf15SRobert Mustacchi 		mcast_obj->enqueue_cmd   = (enqueue_cmd_func)NULL;
4235d14abf15SRobert Mustacchi 		mcast_obj->hdl_restore   = (hdl_restore_func)NULL;
4236d14abf15SRobert Mustacchi 		mcast_obj->check_pending = ecore_mcast_check_pending;
4237d14abf15SRobert Mustacchi 
4238d14abf15SRobert Mustacchi 		/* 57711 doesn't send a ramrod, so it has unlimited credit
4239d14abf15SRobert Mustacchi 		 * for one command.
4240d14abf15SRobert Mustacchi 		 */
4241d14abf15SRobert Mustacchi 		mcast_obj->max_cmd_len       = -1;
4242d14abf15SRobert Mustacchi 		mcast_obj->wait_comp         = ecore_mcast_wait;
4243d14abf15SRobert Mustacchi 		mcast_obj->set_one_rule      = (set_one_rule_func)NULL;
4244d14abf15SRobert Mustacchi 		mcast_obj->validate          = ecore_mcast_validate_e1h;
4245d14abf15SRobert Mustacchi 		mcast_obj->revert            = ecore_mcast_revert_e1h;
4246d14abf15SRobert Mustacchi 		mcast_obj->get_registry_size =
4247d14abf15SRobert Mustacchi 			ecore_mcast_get_registry_size_aprox;
4248d14abf15SRobert Mustacchi 		mcast_obj->set_registry_size =
4249d14abf15SRobert Mustacchi 			ecore_mcast_set_registry_size_aprox;
4250d14abf15SRobert Mustacchi 	} else {
4251d14abf15SRobert Mustacchi 		mcast_obj->config_mcast      = ecore_mcast_setup_e2;
4252d14abf15SRobert Mustacchi 		mcast_obj->enqueue_cmd       = ecore_mcast_enqueue_cmd;
4253d14abf15SRobert Mustacchi 		mcast_obj->hdl_restore       =
4254d14abf15SRobert Mustacchi 			ecore_mcast_handle_restore_cmd_e2;
4255d14abf15SRobert Mustacchi 		mcast_obj->check_pending     = ecore_mcast_check_pending;
4256d14abf15SRobert Mustacchi 		/* TODO: There should be a proper HSI define for this number!!!
4257d14abf15SRobert Mustacchi 		 */
4258d14abf15SRobert Mustacchi 		mcast_obj->max_cmd_len       = 16;
4259d14abf15SRobert Mustacchi 		mcast_obj->wait_comp         = ecore_mcast_wait;
4260d14abf15SRobert Mustacchi 		mcast_obj->set_one_rule      = ecore_mcast_set_one_rule_e2;
4261d14abf15SRobert Mustacchi 		mcast_obj->validate          = ecore_mcast_validate_e2;
4262d14abf15SRobert Mustacchi 		mcast_obj->revert            = ecore_mcast_revert_e2;
4263d14abf15SRobert Mustacchi 		mcast_obj->get_registry_size =
4264d14abf15SRobert Mustacchi 			ecore_mcast_get_registry_size_aprox;
4265d14abf15SRobert Mustacchi 		mcast_obj->set_registry_size =
4266d14abf15SRobert Mustacchi 			ecore_mcast_set_registry_size_aprox;
4267d14abf15SRobert Mustacchi 	}
4268d14abf15SRobert Mustacchi }
4269d14abf15SRobert Mustacchi 
4270d14abf15SRobert Mustacchi /*************************** Credit handling **********************************/
4271d14abf15SRobert Mustacchi 
4272d14abf15SRobert Mustacchi /**
4273d14abf15SRobert Mustacchi  * atomic_add_ifless - add if the result is less than a given value.
4274d14abf15SRobert Mustacchi  *
4275d14abf15SRobert Mustacchi  * @v:	pointer of type atomic_t
4276d14abf15SRobert Mustacchi  * @a:	the amount to add to v...
4277d14abf15SRobert Mustacchi  * @u:	...if (v + a) is less than u.
4278d14abf15SRobert Mustacchi  *
4279d14abf15SRobert Mustacchi  * returns TRUE if (v + a) was less than u, and FALSE otherwise.
4280d14abf15SRobert Mustacchi  *
4281d14abf15SRobert Mustacchi  */
__atomic_add_ifless(atomic_t * v,int a,int u)4282d14abf15SRobert Mustacchi static INLINE BOOL __atomic_add_ifless(atomic_t *v, int a, int u)
4283d14abf15SRobert Mustacchi {
4284d14abf15SRobert Mustacchi 	int c, old;
4285d14abf15SRobert Mustacchi 
4286d14abf15SRobert Mustacchi 	c = ecore_atomic_read(v);
4287d14abf15SRobert Mustacchi 	for (;;) {
4288d14abf15SRobert Mustacchi 		if (ECORE_UNLIKELY(c + a >= u))
4289d14abf15SRobert Mustacchi 			return FALSE;
4290d14abf15SRobert Mustacchi 
4291d14abf15SRobert Mustacchi 		old = ecore_atomic_cmpxchg((v), c, c + a);
4292d14abf15SRobert Mustacchi 		if (ECORE_LIKELY(old == c))
4293d14abf15SRobert Mustacchi 			break;
4294d14abf15SRobert Mustacchi 		c = old;
4295d14abf15SRobert Mustacchi 	}
4296d14abf15SRobert Mustacchi 
4297d14abf15SRobert Mustacchi 	return TRUE;
4298d14abf15SRobert Mustacchi }
4299d14abf15SRobert Mustacchi 
4300d14abf15SRobert Mustacchi /**
4301d14abf15SRobert Mustacchi  * atomic_dec_ifmoe - dec if the result is more or equal than a given value.
4302d14abf15SRobert Mustacchi  *
4303d14abf15SRobert Mustacchi  * @v:	pointer of type atomic_t
4304d14abf15SRobert Mustacchi  * @a:	the amount to dec from v...
4305d14abf15SRobert Mustacchi  * @u:	...if (v - a) is more or equal than u.
4306d14abf15SRobert Mustacchi  *
4307d14abf15SRobert Mustacchi  * returns TRUE if (v - a) was more or equal than u, and FALSE
4308d14abf15SRobert Mustacchi  * otherwise.
4309d14abf15SRobert Mustacchi  */
__atomic_dec_ifmoe(atomic_t * v,int a,int u)4310d14abf15SRobert Mustacchi static INLINE BOOL __atomic_dec_ifmoe(atomic_t *v, int a, int u)
4311d14abf15SRobert Mustacchi {
4312d14abf15SRobert Mustacchi 	int c, old;
4313d14abf15SRobert Mustacchi 
4314d14abf15SRobert Mustacchi 	c = ecore_atomic_read(v);
4315d14abf15SRobert Mustacchi 	for (;;) {
4316d14abf15SRobert Mustacchi 		if (ECORE_UNLIKELY(c - a < u))
4317d14abf15SRobert Mustacchi 			return FALSE;
4318d14abf15SRobert Mustacchi 
4319d14abf15SRobert Mustacchi 		old = ecore_atomic_cmpxchg((v), c, c - a);
4320d14abf15SRobert Mustacchi 		if (ECORE_LIKELY(old == c))
4321d14abf15SRobert Mustacchi 			break;
4322d14abf15SRobert Mustacchi 		c = old;
4323d14abf15SRobert Mustacchi 	}
4324d14abf15SRobert Mustacchi 
4325d14abf15SRobert Mustacchi 	return TRUE;
4326d14abf15SRobert Mustacchi }
4327d14abf15SRobert Mustacchi 
ecore_credit_pool_get(struct ecore_credit_pool_obj * o,int cnt)4328d14abf15SRobert Mustacchi static BOOL ecore_credit_pool_get(struct ecore_credit_pool_obj *o, int cnt)
4329d14abf15SRobert Mustacchi {
4330d14abf15SRobert Mustacchi 	BOOL rc;
4331d14abf15SRobert Mustacchi 
4332d14abf15SRobert Mustacchi 	smp_mb();
4333d14abf15SRobert Mustacchi 	rc = __atomic_dec_ifmoe(&o->credit, cnt, 0);
4334d14abf15SRobert Mustacchi 	smp_mb();
4335d14abf15SRobert Mustacchi 
4336d14abf15SRobert Mustacchi 	return rc;
4337d14abf15SRobert Mustacchi }
4338d14abf15SRobert Mustacchi 
ecore_credit_pool_put(struct ecore_credit_pool_obj * o,int cnt)4339d14abf15SRobert Mustacchi static BOOL ecore_credit_pool_put(struct ecore_credit_pool_obj *o, int cnt)
4340d14abf15SRobert Mustacchi {
4341d14abf15SRobert Mustacchi 	BOOL rc;
4342d14abf15SRobert Mustacchi 
4343d14abf15SRobert Mustacchi 	smp_mb();
4344d14abf15SRobert Mustacchi 
4345d14abf15SRobert Mustacchi 	/* Don't let to refill if credit + cnt > pool_sz */
4346d14abf15SRobert Mustacchi 	rc = __atomic_add_ifless(&o->credit, cnt, o->pool_sz + 1);
4347d14abf15SRobert Mustacchi 
4348d14abf15SRobert Mustacchi 	smp_mb();
4349d14abf15SRobert Mustacchi 
4350d14abf15SRobert Mustacchi 	return rc;
4351d14abf15SRobert Mustacchi }
4352d14abf15SRobert Mustacchi 
ecore_credit_pool_check(struct ecore_credit_pool_obj * o)4353d14abf15SRobert Mustacchi static int ecore_credit_pool_check(struct ecore_credit_pool_obj *o)
4354d14abf15SRobert Mustacchi {
4355d14abf15SRobert Mustacchi 	int cur_credit;
4356d14abf15SRobert Mustacchi 
4357d14abf15SRobert Mustacchi 	smp_mb();
4358d14abf15SRobert Mustacchi 	cur_credit = ecore_atomic_read(&o->credit);
4359d14abf15SRobert Mustacchi 
4360d14abf15SRobert Mustacchi 	return cur_credit;
4361d14abf15SRobert Mustacchi }
4362d14abf15SRobert Mustacchi 
ecore_credit_pool_always_TRUE(struct ecore_credit_pool_obj * o,int cnt)4363d14abf15SRobert Mustacchi static BOOL ecore_credit_pool_always_TRUE(struct ecore_credit_pool_obj *o,
4364d14abf15SRobert Mustacchi 					  int cnt)
4365d14abf15SRobert Mustacchi {
4366d14abf15SRobert Mustacchi 	return TRUE;
4367d14abf15SRobert Mustacchi }
4368d14abf15SRobert Mustacchi 
ecore_credit_pool_get_entry(struct ecore_credit_pool_obj * o,int * offset)4369d14abf15SRobert Mustacchi static BOOL ecore_credit_pool_get_entry(
4370d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *o,
4371d14abf15SRobert Mustacchi 	int *offset)
4372d14abf15SRobert Mustacchi {
4373d14abf15SRobert Mustacchi 	int idx, vec, i;
4374d14abf15SRobert Mustacchi 
4375d14abf15SRobert Mustacchi 	*offset = -1;
4376d14abf15SRobert Mustacchi 
4377d14abf15SRobert Mustacchi 	/* Find "internal cam-offset" then add to base for this object... */
4378d14abf15SRobert Mustacchi 	for (vec = 0; vec < ECORE_POOL_VEC_SIZE; vec++) {
4379d14abf15SRobert Mustacchi 
4380d14abf15SRobert Mustacchi 		/* Skip the current vector if there are no free entries in it */
4381d14abf15SRobert Mustacchi 		if (!o->pool_mirror[vec])
4382d14abf15SRobert Mustacchi 			continue;
4383d14abf15SRobert Mustacchi 
4384d14abf15SRobert Mustacchi 		/* If we've got here we are going to find a free entry */
4385d14abf15SRobert Mustacchi 		for (idx = vec * BIT_VEC64_ELEM_SZ, i = 0;
4386d14abf15SRobert Mustacchi 		      i < BIT_VEC64_ELEM_SZ; idx++, i++)
4387d14abf15SRobert Mustacchi 
4388d14abf15SRobert Mustacchi 			if (BIT_VEC64_TEST_BIT(o->pool_mirror, idx)) {
4389d14abf15SRobert Mustacchi 				/* Got one!! */
4390d14abf15SRobert Mustacchi 				BIT_VEC64_CLEAR_BIT(o->pool_mirror, idx);
4391d14abf15SRobert Mustacchi 				*offset = o->base_pool_offset + idx;
4392d14abf15SRobert Mustacchi 				return TRUE;
4393d14abf15SRobert Mustacchi 			}
4394d14abf15SRobert Mustacchi 	}
4395d14abf15SRobert Mustacchi 
4396d14abf15SRobert Mustacchi 	return FALSE;
4397d14abf15SRobert Mustacchi }
4398d14abf15SRobert Mustacchi 
ecore_credit_pool_put_entry(struct ecore_credit_pool_obj * o,int offset)4399d14abf15SRobert Mustacchi static BOOL ecore_credit_pool_put_entry(
4400d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *o,
4401d14abf15SRobert Mustacchi 	int offset)
4402d14abf15SRobert Mustacchi {
4403d14abf15SRobert Mustacchi 	if (offset < o->base_pool_offset)
4404d14abf15SRobert Mustacchi 		return FALSE;
4405d14abf15SRobert Mustacchi 
4406d14abf15SRobert Mustacchi 	offset -= o->base_pool_offset;
4407d14abf15SRobert Mustacchi 
4408d14abf15SRobert Mustacchi 	if (offset >= o->pool_sz)
4409d14abf15SRobert Mustacchi 		return FALSE;
4410d14abf15SRobert Mustacchi 
4411d14abf15SRobert Mustacchi 	/* Return the entry to the pool */
4412d14abf15SRobert Mustacchi 	BIT_VEC64_SET_BIT(o->pool_mirror, offset);
4413d14abf15SRobert Mustacchi 
4414d14abf15SRobert Mustacchi 	return TRUE;
4415d14abf15SRobert Mustacchi }
4416d14abf15SRobert Mustacchi 
ecore_credit_pool_put_entry_always_TRUE(struct ecore_credit_pool_obj * o,int offset)4417d14abf15SRobert Mustacchi static BOOL ecore_credit_pool_put_entry_always_TRUE(
4418d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *o,
4419d14abf15SRobert Mustacchi 	int offset)
4420d14abf15SRobert Mustacchi {
4421d14abf15SRobert Mustacchi 	return TRUE;
4422d14abf15SRobert Mustacchi }
4423d14abf15SRobert Mustacchi 
ecore_credit_pool_get_entry_always_TRUE(struct ecore_credit_pool_obj * o,int * offset)4424d14abf15SRobert Mustacchi static BOOL ecore_credit_pool_get_entry_always_TRUE(
4425d14abf15SRobert Mustacchi 	struct ecore_credit_pool_obj *o,
4426d14abf15SRobert Mustacchi 	int *offset)
4427d14abf15SRobert Mustacchi {
4428d14abf15SRobert Mustacchi 	*offset = -1;
4429d14abf15SRobert Mustacchi 	return TRUE;
4430d14abf15SRobert Mustacchi }
4431d14abf15SRobert Mustacchi /**
4432d14abf15SRobert Mustacchi  * ecore_init_credit_pool - initialize credit pool internals.
4433d14abf15SRobert Mustacchi  *
4434d14abf15SRobert Mustacchi  * @p:
4435d14abf15SRobert Mustacchi  * @base:	Base entry in the CAM to use.
4436d14abf15SRobert Mustacchi  * @credit:	pool size.
4437d14abf15SRobert Mustacchi  *
4438d14abf15SRobert Mustacchi  * If base is negative no CAM entries handling will be performed.
4439d14abf15SRobert Mustacchi  * If credit is negative pool operations will always succeed (unlimited pool).
4440d14abf15SRobert Mustacchi  *
4441d14abf15SRobert Mustacchi  */
ecore_init_credit_pool(struct ecore_credit_pool_obj * p,int base,int credit)4442d14abf15SRobert Mustacchi static INLINE void ecore_init_credit_pool(struct ecore_credit_pool_obj *p,
4443d14abf15SRobert Mustacchi 					  int base, int credit)
4444d14abf15SRobert Mustacchi {
4445d14abf15SRobert Mustacchi 	/* Zero the object first */
4446d14abf15SRobert Mustacchi 	mm_memset(p, 0, sizeof(*p));
4447d14abf15SRobert Mustacchi 
4448d14abf15SRobert Mustacchi 	/* Set the table to all 1s */
4449d14abf15SRobert Mustacchi 	mm_memset(&p->pool_mirror, 0xff, sizeof(p->pool_mirror));
4450d14abf15SRobert Mustacchi 
4451d14abf15SRobert Mustacchi 	/* Init a pool as full */
4452d14abf15SRobert Mustacchi 	ecore_atomic_set(&p->credit, credit);
4453d14abf15SRobert Mustacchi 
4454d14abf15SRobert Mustacchi 	/* The total poll size */
4455d14abf15SRobert Mustacchi 	p->pool_sz = credit;
4456d14abf15SRobert Mustacchi 
4457d14abf15SRobert Mustacchi 	p->base_pool_offset = base;
4458d14abf15SRobert Mustacchi 
4459d14abf15SRobert Mustacchi 	/* Commit the change */
4460d14abf15SRobert Mustacchi 	smp_mb();
4461d14abf15SRobert Mustacchi 
4462d14abf15SRobert Mustacchi 	p->check = ecore_credit_pool_check;
4463d14abf15SRobert Mustacchi 
4464d14abf15SRobert Mustacchi 	/* if pool credit is negative - disable the checks */
4465d14abf15SRobert Mustacchi 	if (credit >= 0) {
4466d14abf15SRobert Mustacchi 		p->put      = ecore_credit_pool_put;
4467d14abf15SRobert Mustacchi 		p->get      = ecore_credit_pool_get;
4468d14abf15SRobert Mustacchi 		p->put_entry = ecore_credit_pool_put_entry;
4469d14abf15SRobert Mustacchi 		p->get_entry = ecore_credit_pool_get_entry;
4470d14abf15SRobert Mustacchi 	} else {
4471d14abf15SRobert Mustacchi 		p->put      = ecore_credit_pool_always_TRUE;
4472d14abf15SRobert Mustacchi 		p->get      = ecore_credit_pool_always_TRUE;
4473d14abf15SRobert Mustacchi 		p->put_entry = ecore_credit_pool_put_entry_always_TRUE;
4474d14abf15SRobert Mustacchi 		p->get_entry = ecore_credit_pool_get_entry_always_TRUE;
4475d14abf15SRobert Mustacchi 	}
4476d14abf15SRobert Mustacchi 
4477d14abf15SRobert Mustacchi 	/* If base is negative - disable entries handling */
4478d14abf15SRobert Mustacchi 	if (base < 0) {
4479d14abf15SRobert Mustacchi 		p->put_entry = ecore_credit_pool_put_entry_always_TRUE;
4480d14abf15SRobert Mustacchi 		p->get_entry = ecore_credit_pool_get_entry_always_TRUE;
4481d14abf15SRobert Mustacchi 	}
4482d14abf15SRobert Mustacchi }
4483d14abf15SRobert Mustacchi 
ecore_init_mac_credit_pool(struct _lm_device_t * pdev,struct ecore_credit_pool_obj * p,u8 func_id,u8 func_num)4484d14abf15SRobert Mustacchi void ecore_init_mac_credit_pool(struct _lm_device_t *pdev,
4485d14abf15SRobert Mustacchi 				struct ecore_credit_pool_obj *p, u8 func_id,
4486d14abf15SRobert Mustacchi 				u8 func_num)
4487d14abf15SRobert Mustacchi {
4488d14abf15SRobert Mustacchi /* TODO: this will be defined in consts as well... */
4489d14abf15SRobert Mustacchi #define ECORE_CAM_SIZE_EMUL 5
4490d14abf15SRobert Mustacchi 
4491d14abf15SRobert Mustacchi 	int cam_sz;
4492d14abf15SRobert Mustacchi 
4493d14abf15SRobert Mustacchi 	if (CHIP_IS_E1(pdev)) {
4494d14abf15SRobert Mustacchi 		/* In E1, Multicast is saved in cam... */
4495d14abf15SRobert Mustacchi 		if (!CHIP_REV_IS_SLOW(pdev))
4496d14abf15SRobert Mustacchi 			cam_sz = (MAX_MAC_CREDIT_E1 / 2) - ECORE_MAX_MULTICAST;
4497d14abf15SRobert Mustacchi 		else
4498d14abf15SRobert Mustacchi 			cam_sz = ECORE_CAM_SIZE_EMUL - ECORE_MAX_EMUL_MULTI;
4499d14abf15SRobert Mustacchi 
4500d14abf15SRobert Mustacchi 		ecore_init_credit_pool(p, func_id * cam_sz, cam_sz);
4501d14abf15SRobert Mustacchi 
4502d14abf15SRobert Mustacchi 	} else if (CHIP_IS_E1H(pdev)) {
4503d14abf15SRobert Mustacchi 		/* CAM credit is equally divided between all active functions
4504d14abf15SRobert Mustacchi 		 * on the PORT!.
4505d14abf15SRobert Mustacchi 		 */
4506d14abf15SRobert Mustacchi 		if ((func_num > 0)) {
4507d14abf15SRobert Mustacchi 			if (!CHIP_REV_IS_SLOW(pdev))
4508d14abf15SRobert Mustacchi 				cam_sz = (MAX_MAC_CREDIT_E1H / (2*func_num));
4509d14abf15SRobert Mustacchi 			else
4510d14abf15SRobert Mustacchi 				cam_sz = ECORE_CAM_SIZE_EMUL;
4511d14abf15SRobert Mustacchi 			ecore_init_credit_pool(p, func_id * cam_sz, cam_sz);
4512d14abf15SRobert Mustacchi 		} else {
4513d14abf15SRobert Mustacchi 			/* this should never happen! Block MAC operations. */
4514d14abf15SRobert Mustacchi 			ecore_init_credit_pool(p, 0, 0);
4515d14abf15SRobert Mustacchi 		}
4516d14abf15SRobert Mustacchi 
4517d14abf15SRobert Mustacchi 	} else {
4518d14abf15SRobert Mustacchi 
4519d14abf15SRobert Mustacchi 		/*
4520d14abf15SRobert Mustacchi 		 * CAM credit is equaly divided between all active functions
4521d14abf15SRobert Mustacchi 		 * on the PATH.
4522d14abf15SRobert Mustacchi 		 */
4523d14abf15SRobert Mustacchi 		if ((func_num > 1)) {
4524d14abf15SRobert Mustacchi 			if (!CHIP_REV_IS_SLOW(pdev))
4525d14abf15SRobert Mustacchi 				cam_sz = (MAX_MAC_CREDIT_E2
4526d14abf15SRobert Mustacchi 				- GET_NUM_VFS_PER_PATH(pdev))
4527d14abf15SRobert Mustacchi 				/ func_num
4528d14abf15SRobert Mustacchi 				+ GET_NUM_VFS_PER_PF(pdev);
4529d14abf15SRobert Mustacchi 			else
4530d14abf15SRobert Mustacchi 				cam_sz = ECORE_CAM_SIZE_EMUL;
4531d14abf15SRobert Mustacchi 
4532d14abf15SRobert Mustacchi 			/* No need for CAM entries handling for 57712 and
4533d14abf15SRobert Mustacchi 			 * newer.
4534d14abf15SRobert Mustacchi 			 */
4535d14abf15SRobert Mustacchi 			ecore_init_credit_pool(p, -1, cam_sz);
4536d14abf15SRobert Mustacchi 		} else if (func_num == 1) {
4537d14abf15SRobert Mustacchi 			if (!CHIP_REV_IS_SLOW(pdev))
4538d14abf15SRobert Mustacchi 				cam_sz = MAX_MAC_CREDIT_E2;
4539d14abf15SRobert Mustacchi 			else
4540d14abf15SRobert Mustacchi 				cam_sz = ECORE_CAM_SIZE_EMUL;
4541d14abf15SRobert Mustacchi 
4542d14abf15SRobert Mustacchi 			/* No need for CAM entries handling for 57712 and
4543d14abf15SRobert Mustacchi 			 * newer.
4544d14abf15SRobert Mustacchi 			 */
4545d14abf15SRobert Mustacchi 			ecore_init_credit_pool(p, -1, cam_sz);
4546d14abf15SRobert Mustacchi 		} else {
4547d14abf15SRobert Mustacchi 			/* this should never happen! Block MAC operations. */
4548d14abf15SRobert Mustacchi 			ecore_init_credit_pool(p, 0, 0);
4549d14abf15SRobert Mustacchi 		}
4550d14abf15SRobert Mustacchi 	}
4551d14abf15SRobert Mustacchi }
4552d14abf15SRobert Mustacchi 
ecore_init_vlan_credit_pool(struct _lm_device_t * pdev,struct ecore_credit_pool_obj * p,u8 func_id,u8 func_num)4553d14abf15SRobert Mustacchi void ecore_init_vlan_credit_pool(struct _lm_device_t *pdev,
4554d14abf15SRobert Mustacchi 				 struct ecore_credit_pool_obj *p,
4555d14abf15SRobert Mustacchi 				 u8 func_id,
4556d14abf15SRobert Mustacchi 				 u8 func_num)
4557d14abf15SRobert Mustacchi {
4558d14abf15SRobert Mustacchi 	if (CHIP_IS_E1x(pdev)) {
4559d14abf15SRobert Mustacchi 		/* There is no VLAN credit in HW on 57710 and 57711 only
4560d14abf15SRobert Mustacchi 		 * MAC / MAC-VLAN can be set
4561d14abf15SRobert Mustacchi 		 */
4562d14abf15SRobert Mustacchi 		ecore_init_credit_pool(p, 0, -1);
4563d14abf15SRobert Mustacchi 	} else {
4564d14abf15SRobert Mustacchi 		/* CAM credit is equally divided between all active functions
4565d14abf15SRobert Mustacchi 		 * on the PATH.
4566d14abf15SRobert Mustacchi 		 */
4567d14abf15SRobert Mustacchi 		if (func_num > 0) {
4568d14abf15SRobert Mustacchi 			int credit = MAX_VLAN_CREDIT_E2 / func_num;
4569d14abf15SRobert Mustacchi 			ecore_init_credit_pool(p, func_id * credit, credit);
4570d14abf15SRobert Mustacchi 		} else
4571d14abf15SRobert Mustacchi 			/* this should never happen! Block VLAN operations. */
4572d14abf15SRobert Mustacchi 			ecore_init_credit_pool(p, 0, 0);
4573d14abf15SRobert Mustacchi 	}
4574d14abf15SRobert Mustacchi }
4575d14abf15SRobert Mustacchi 
4576d14abf15SRobert Mustacchi /****************** RSS Configuration ******************/
4577d14abf15SRobert Mustacchi #if defined(ECORE_ERASE) && !defined(__FreeBSD__)
4578d14abf15SRobert Mustacchi /**
4579d14abf15SRobert Mustacchi  * bnx2x_debug_print_ind_table - prints the indirection table configuration.
4580d14abf15SRobert Mustacchi  *
4581d14abf15SRobert Mustacchi  * @bp:		driver handle
4582d14abf15SRobert Mustacchi  * @p:		pointer to rss configuration
4583d14abf15SRobert Mustacchi  *
4584d14abf15SRobert Mustacchi  * Prints it when NETIF_MSG_IFUP debug level is configured.
4585d14abf15SRobert Mustacchi  */
bnx2x_debug_print_ind_table(struct bnx2x * bp,struct bnx2x_config_rss_params * p)4586d14abf15SRobert Mustacchi static inline void bnx2x_debug_print_ind_table(struct bnx2x *bp,
4587d14abf15SRobert Mustacchi 					struct bnx2x_config_rss_params *p)
4588d14abf15SRobert Mustacchi {
4589d14abf15SRobert Mustacchi 	int i;
4590d14abf15SRobert Mustacchi 
4591d14abf15SRobert Mustacchi 	DP(BNX2X_MSG_SP, "Setting indirection table to:\n");
4592d14abf15SRobert Mustacchi 	DP(BNX2X_MSG_SP, "0x0000: ");
4593d14abf15SRobert Mustacchi 	for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++) {
4594d14abf15SRobert Mustacchi 		DP_CONT(BNX2X_MSG_SP, "0x%02x ", p->ind_table[i]);
4595d14abf15SRobert Mustacchi 
4596d14abf15SRobert Mustacchi 		/* Print 4 bytes in a line */
4597d14abf15SRobert Mustacchi 		if ((i + 1 < T_ETH_INDIRECTION_TABLE_SIZE) &&
4598d14abf15SRobert Mustacchi 		    (((i + 1) & 0x3) == 0)) {
4599d14abf15SRobert Mustacchi 			DP_CONT(BNX2X_MSG_SP, "\n");
4600d14abf15SRobert Mustacchi 			DP(BNX2X_MSG_SP, "0x%04x: ", i + 1);
4601d14abf15SRobert Mustacchi 		}
4602d14abf15SRobert Mustacchi 	}
4603d14abf15SRobert Mustacchi 
4604d14abf15SRobert Mustacchi 	DP_CONT(BNX2X_MSG_SP, "\n");
4605d14abf15SRobert Mustacchi }
4606d14abf15SRobert Mustacchi #endif /* ECORE_ERASE && !__FreeBSD__ */
4607d14abf15SRobert Mustacchi 
4608d14abf15SRobert Mustacchi /**
4609d14abf15SRobert Mustacchi  * ecore_setup_rss - configure RSS
4610d14abf15SRobert Mustacchi  *
4611d14abf15SRobert Mustacchi  * @pdev:	device handle
4612d14abf15SRobert Mustacchi  * @p:		rss configuration
4613d14abf15SRobert Mustacchi  *
4614d14abf15SRobert Mustacchi  * sends on UPDATE ramrod for that matter.
4615d14abf15SRobert Mustacchi  */
ecore_setup_rss(struct _lm_device_t * pdev,struct ecore_config_rss_params * p)4616d14abf15SRobert Mustacchi static int ecore_setup_rss(struct _lm_device_t *pdev,
4617d14abf15SRobert Mustacchi 			   struct ecore_config_rss_params *p)
4618d14abf15SRobert Mustacchi {
4619d14abf15SRobert Mustacchi 	struct ecore_rss_config_obj *o = p->rss_obj;
4620d14abf15SRobert Mustacchi 	struct ecore_raw_obj *r = &o->raw;
4621d14abf15SRobert Mustacchi 	struct eth_rss_update_ramrod_data *data =
4622d14abf15SRobert Mustacchi 		(struct eth_rss_update_ramrod_data *)(r->rdata);
4623d14abf15SRobert Mustacchi 	u16 caps = 0;
4624d14abf15SRobert Mustacchi 	u8 rss_mode = 0;
4625d14abf15SRobert Mustacchi 	int rc;
4626d14abf15SRobert Mustacchi 
4627d14abf15SRobert Mustacchi 	mm_memset(data, 0, sizeof(*data));
4628d14abf15SRobert Mustacchi 
4629d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Configuring RSS\n");
4630d14abf15SRobert Mustacchi 
4631d14abf15SRobert Mustacchi 	/* Set an echo field */
4632d14abf15SRobert Mustacchi 	data->echo = mm_cpu_to_le32((r->cid & ECORE_SWCID_MASK) |
4633d14abf15SRobert Mustacchi 				 (r->state << ECORE_SWCID_SHIFT));
4634d14abf15SRobert Mustacchi 
4635d14abf15SRobert Mustacchi 	/* RSS mode */
4636d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_RSS_MODE_DISABLED, &p->rss_flags))
4637d14abf15SRobert Mustacchi 		rss_mode = ETH_RSS_MODE_DISABLED;
4638d14abf15SRobert Mustacchi 	else if (ECORE_TEST_BIT(ECORE_RSS_MODE_REGULAR, &p->rss_flags))
4639d14abf15SRobert Mustacchi 		rss_mode = ETH_RSS_MODE_REGULAR;
4640d14abf15SRobert Mustacchi #if defined(__VMKLNX__) && (VMWARE_ESX_DDK_VERSION < 55000) /* ! BNX2X_UPSTREAM */
4641d14abf15SRobert Mustacchi 	else if (ECORE_TEST_BIT(ECORE_RSS_MODE_ESX51, &p->rss_flags))
4642d14abf15SRobert Mustacchi 		rss_mode = ETH_RSS_MODE_ESX51;
4643d14abf15SRobert Mustacchi #endif
4644d14abf15SRobert Mustacchi 
4645d14abf15SRobert Mustacchi 	data->rss_mode = rss_mode;
4646d14abf15SRobert Mustacchi 
4647d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "rss_mode=%d\n", rss_mode);
4648d14abf15SRobert Mustacchi 
4649d14abf15SRobert Mustacchi 	/* RSS capabilities */
4650d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_RSS_IPV4, &p->rss_flags))
4651d14abf15SRobert Mustacchi 		caps |= ETH_RSS_UPDATE_RAMROD_DATA_IPV4_CAPABILITY;
4652d14abf15SRobert Mustacchi 
4653d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_RSS_IPV4_TCP, &p->rss_flags))
4654d14abf15SRobert Mustacchi 		caps |= ETH_RSS_UPDATE_RAMROD_DATA_IPV4_TCP_CAPABILITY;
4655d14abf15SRobert Mustacchi 
4656d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_RSS_IPV4_UDP, &p->rss_flags))
4657d14abf15SRobert Mustacchi 		caps |= ETH_RSS_UPDATE_RAMROD_DATA_IPV4_UDP_CAPABILITY;
4658d14abf15SRobert Mustacchi 
4659d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_RSS_IPV6, &p->rss_flags))
4660d14abf15SRobert Mustacchi 		caps |= ETH_RSS_UPDATE_RAMROD_DATA_IPV6_CAPABILITY;
4661d14abf15SRobert Mustacchi 
4662d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_RSS_IPV6_TCP, &p->rss_flags))
4663d14abf15SRobert Mustacchi 		caps |= ETH_RSS_UPDATE_RAMROD_DATA_IPV6_TCP_CAPABILITY;
4664d14abf15SRobert Mustacchi 
4665d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_RSS_IPV6_UDP, &p->rss_flags))
4666d14abf15SRobert Mustacchi 		caps |= ETH_RSS_UPDATE_RAMROD_DATA_IPV6_UDP_CAPABILITY;
4667d14abf15SRobert Mustacchi 
4668d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_RSS_IPV4_VXLAN, &p->rss_flags))
4669d14abf15SRobert Mustacchi 		caps |= ETH_RSS_UPDATE_RAMROD_DATA_IPV4_VXLAN_CAPABILITY;
4670d14abf15SRobert Mustacchi 
4671d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_RSS_IPV6_VXLAN, &p->rss_flags))
4672d14abf15SRobert Mustacchi 		caps |= ETH_RSS_UPDATE_RAMROD_DATA_IPV6_VXLAN_CAPABILITY;
4673d14abf15SRobert Mustacchi 
4674d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_RSS_NVGRE_KEY_ENTROPY, &p->rss_flags))
4675d14abf15SRobert Mustacchi 		caps |= ETH_RSS_UPDATE_RAMROD_DATA_NVGRE_KEY_ENTROPY_CAPABILITY;
4676d14abf15SRobert Mustacchi 
4677d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_RSS_GRE_INNER_HDRS, &p->rss_flags))
4678d14abf15SRobert Mustacchi 		caps |= ETH_RSS_UPDATE_RAMROD_DATA_GRE_INNER_HDRS_CAPABILITY;
4679d14abf15SRobert Mustacchi 
4680d14abf15SRobert Mustacchi 	data->capabilities = mm_cpu_to_le16(caps);
4681d14abf15SRobert Mustacchi 
4682d14abf15SRobert Mustacchi 	/* Hashing mask */
4683d14abf15SRobert Mustacchi 	data->rss_result_mask = p->rss_result_mask;
4684d14abf15SRobert Mustacchi 
4685d14abf15SRobert Mustacchi 	/* RSS engine ID */
4686d14abf15SRobert Mustacchi 	data->rss_engine_id = o->engine_id;
4687d14abf15SRobert Mustacchi 
4688d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "rss_engine_id=%d\n", data->rss_engine_id);
4689d14abf15SRobert Mustacchi 
4690d14abf15SRobert Mustacchi 	/* Indirection table */
4691d14abf15SRobert Mustacchi 	mm_memcpy(data->indirection_table, p->ind_table,
4692d14abf15SRobert Mustacchi 		  T_ETH_INDIRECTION_TABLE_SIZE);
4693d14abf15SRobert Mustacchi 
4694d14abf15SRobert Mustacchi 	/* Remember the last configuration */
4695d14abf15SRobert Mustacchi 	mm_memcpy(o->ind_table, p->ind_table, T_ETH_INDIRECTION_TABLE_SIZE);
4696d14abf15SRobert Mustacchi 
4697d14abf15SRobert Mustacchi #if defined(ECORE_ERASE) && !defined(__FreeBSD__)
4698d14abf15SRobert Mustacchi 	/* Print the indirection table */
4699d14abf15SRobert Mustacchi 	if (netif_msg_ifup(bp))
4700d14abf15SRobert Mustacchi 		bnx2x_debug_print_ind_table(bp, p);
4701d14abf15SRobert Mustacchi #endif
4702d14abf15SRobert Mustacchi 
4703d14abf15SRobert Mustacchi 	/* RSS keys */
4704d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_RSS_SET_SRCH, &p->rss_flags)) {
4705d14abf15SRobert Mustacchi 		mm_memcpy(&data->rss_key[0], &p->rss_key[0],
4706d14abf15SRobert Mustacchi 		       sizeof(data->rss_key));
4707d14abf15SRobert Mustacchi 		data->capabilities |= ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY;
4708d14abf15SRobert Mustacchi 	}
4709d14abf15SRobert Mustacchi 
4710d14abf15SRobert Mustacchi 	/* No need for an explicit memory barrier here as long as we
4711d14abf15SRobert Mustacchi 	 * ensure the ordering of writing to the SPQ element
4712d14abf15SRobert Mustacchi 	 * and updating of the SPQ producer which involves a memory
4713d14abf15SRobert Mustacchi 	 * read. If the memory read is removed we will have to put a
4714d14abf15SRobert Mustacchi 	 * full memory barrier there (inside ecore_sp_post()).
4715d14abf15SRobert Mustacchi 	 */
4716d14abf15SRobert Mustacchi 
4717d14abf15SRobert Mustacchi 	/* Send a ramrod */
4718d14abf15SRobert Mustacchi 	rc = ecore_sp_post(pdev,
4719d14abf15SRobert Mustacchi 			     RAMROD_CMD_ID_ETH_RSS_UPDATE,
4720d14abf15SRobert Mustacchi 			     r->cid,
4721d14abf15SRobert Mustacchi 			     r->rdata_mapping.as_u64,
4722d14abf15SRobert Mustacchi 			     ETH_CONNECTION_TYPE);
4723d14abf15SRobert Mustacchi 
4724d14abf15SRobert Mustacchi 	if (rc < 0)
4725d14abf15SRobert Mustacchi 		return rc;
4726d14abf15SRobert Mustacchi 
4727d14abf15SRobert Mustacchi 	return ECORE_PENDING;
4728d14abf15SRobert Mustacchi }
4729d14abf15SRobert Mustacchi 
ecore_get_rss_ind_table(struct ecore_rss_config_obj * rss_obj,u8 * ind_table)4730d14abf15SRobert Mustacchi void ecore_get_rss_ind_table(struct ecore_rss_config_obj *rss_obj,
4731d14abf15SRobert Mustacchi 			     u8 *ind_table)
4732d14abf15SRobert Mustacchi {
4733d14abf15SRobert Mustacchi 	mm_memcpy(ind_table, rss_obj->ind_table, sizeof(rss_obj->ind_table));
4734d14abf15SRobert Mustacchi }
4735d14abf15SRobert Mustacchi 
ecore_config_rss(struct _lm_device_t * pdev,struct ecore_config_rss_params * p)4736d14abf15SRobert Mustacchi int ecore_config_rss(struct _lm_device_t *pdev,
4737d14abf15SRobert Mustacchi 		     struct ecore_config_rss_params *p)
4738d14abf15SRobert Mustacchi {
4739d14abf15SRobert Mustacchi 	int rc;
4740d14abf15SRobert Mustacchi 	struct ecore_rss_config_obj *o = p->rss_obj;
4741d14abf15SRobert Mustacchi 	struct ecore_raw_obj *r = &o->raw;
4742d14abf15SRobert Mustacchi 
4743d14abf15SRobert Mustacchi 	/* Do nothing if only driver cleanup was requested */
4744d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) {
4745d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "Not configuring RSS ramrod_flags=%lx\n",
4746d14abf15SRobert Mustacchi 			  p->ramrod_flags);
4747d14abf15SRobert Mustacchi 		return ECORE_SUCCESS;
4748d14abf15SRobert Mustacchi 	}
4749d14abf15SRobert Mustacchi 
4750d14abf15SRobert Mustacchi 	r->set_pending(r);
4751d14abf15SRobert Mustacchi 
4752d14abf15SRobert Mustacchi 	rc = o->config_rss(pdev, p);
4753d14abf15SRobert Mustacchi 	if (rc < 0) {
4754d14abf15SRobert Mustacchi 		r->clear_pending(r);
4755d14abf15SRobert Mustacchi 		return rc;
4756d14abf15SRobert Mustacchi 	}
4757d14abf15SRobert Mustacchi 
4758d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_COMP_WAIT, &p->ramrod_flags))
4759d14abf15SRobert Mustacchi 		rc = r->wait_comp(pdev, r);
4760d14abf15SRobert Mustacchi 
4761d14abf15SRobert Mustacchi 	return rc;
4762d14abf15SRobert Mustacchi }
4763d14abf15SRobert Mustacchi 
ecore_init_rss_config_obj(struct _lm_device_t * pdev,struct ecore_rss_config_obj * rss_obj,u8 cl_id,u32 cid,u8 func_id,u8 engine_id,void * rdata,lm_address_t rdata_mapping,int state,unsigned long * pstate,ecore_obj_type type)4764d14abf15SRobert Mustacchi void ecore_init_rss_config_obj(struct _lm_device_t *pdev,
4765d14abf15SRobert Mustacchi 			       struct ecore_rss_config_obj *rss_obj,
4766d14abf15SRobert Mustacchi 			       u8 cl_id, u32 cid, u8 func_id, u8 engine_id,
4767d14abf15SRobert Mustacchi 			       void *rdata, lm_address_t rdata_mapping,
4768d14abf15SRobert Mustacchi 			       int state, unsigned long *pstate,
4769d14abf15SRobert Mustacchi 			       ecore_obj_type type)
4770d14abf15SRobert Mustacchi {
4771d14abf15SRobert Mustacchi 	ecore_init_raw_obj(&rss_obj->raw, cl_id, cid, func_id, rdata,
4772d14abf15SRobert Mustacchi 			   rdata_mapping, state, pstate, type);
4773d14abf15SRobert Mustacchi 
4774d14abf15SRobert Mustacchi 	rss_obj->engine_id  = engine_id;
4775d14abf15SRobert Mustacchi 	rss_obj->config_rss = ecore_setup_rss;
4776d14abf15SRobert Mustacchi }
4777d14abf15SRobert Mustacchi 
4778d14abf15SRobert Mustacchi #ifdef ECORE_ERASE
4779d14abf15SRobert Mustacchi /********************** Queue state object ***********************************/
4780d14abf15SRobert Mustacchi 
4781d14abf15SRobert Mustacchi /**
4782d14abf15SRobert Mustacchi  * ecore_queue_state_change - perform Queue state change transition
4783d14abf15SRobert Mustacchi  *
4784d14abf15SRobert Mustacchi  * @pdev:	device handle
4785d14abf15SRobert Mustacchi  * @params:	parameters to perform the transition
4786d14abf15SRobert Mustacchi  *
4787d14abf15SRobert Mustacchi  * returns 0 in case of successfully completed transition, negative error
4788d14abf15SRobert Mustacchi  * code in case of failure, positive (EBUSY) value if there is a completion
4789d14abf15SRobert Mustacchi  * to that is still pending (possible only if RAMROD_COMP_WAIT is
4790d14abf15SRobert Mustacchi  * not set in params->ramrod_flags for asynchronous commands).
4791d14abf15SRobert Mustacchi  *
4792d14abf15SRobert Mustacchi  */
ecore_queue_state_change(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)4793d14abf15SRobert Mustacchi int ecore_queue_state_change(struct _lm_device_t *pdev,
4794d14abf15SRobert Mustacchi 			     struct ecore_queue_state_params *params)
4795d14abf15SRobert Mustacchi {
4796d14abf15SRobert Mustacchi 	struct ecore_queue_sp_obj *o = params->q_obj;
4797d14abf15SRobert Mustacchi 	int rc, pending_bit;
4798d14abf15SRobert Mustacchi 	unsigned long *pending = &o->pending;
4799d14abf15SRobert Mustacchi 
4800d14abf15SRobert Mustacchi 	/* Check that the requested transition is legal */
4801d14abf15SRobert Mustacchi 	rc = o->check_transition(pdev, o, params);
4802d14abf15SRobert Mustacchi 	if (rc) {
4803d14abf15SRobert Mustacchi 		ECORE_ERR("check transition returned an error. rc %d\n", rc);
4804d14abf15SRobert Mustacchi 		return ECORE_INVAL;
4805d14abf15SRobert Mustacchi 	}
4806d14abf15SRobert Mustacchi 
4807d14abf15SRobert Mustacchi 	/* Set "pending" bit */
4808d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "pending bit was=%lx\n", o->pending);
4809d14abf15SRobert Mustacchi 	pending_bit = o->set_pending(o, params);
4810d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "pending bit now=%lx\n", o->pending);
4811d14abf15SRobert Mustacchi 
4812d14abf15SRobert Mustacchi 	/* Don't send a command if only driver cleanup was requested */
4813d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_DRV_CLR_ONLY, &params->ramrod_flags))
4814d14abf15SRobert Mustacchi 		o->complete_cmd(pdev, o, pending_bit);
4815d14abf15SRobert Mustacchi 	else {
4816d14abf15SRobert Mustacchi 		/* Send a ramrod */
4817d14abf15SRobert Mustacchi 		rc = o->send_cmd(pdev, params);
4818d14abf15SRobert Mustacchi 		if (rc) {
4819d14abf15SRobert Mustacchi 			o->next_state = ECORE_Q_STATE_MAX;
4820d14abf15SRobert Mustacchi 			ECORE_CLEAR_BIT(pending_bit, pending);
4821d14abf15SRobert Mustacchi 			smp_mb__after_atomic();
4822d14abf15SRobert Mustacchi 			return rc;
4823d14abf15SRobert Mustacchi 		}
4824d14abf15SRobert Mustacchi 
4825d14abf15SRobert Mustacchi 		if (ECORE_TEST_BIT(RAMROD_COMP_WAIT, &params->ramrod_flags)) {
4826d14abf15SRobert Mustacchi 			rc = o->wait_comp(pdev, o, pending_bit);
4827d14abf15SRobert Mustacchi 			if (rc)
4828d14abf15SRobert Mustacchi 				return rc;
4829d14abf15SRobert Mustacchi 
4830d14abf15SRobert Mustacchi 			return ECORE_SUCCESS;
4831d14abf15SRobert Mustacchi 		}
4832d14abf15SRobert Mustacchi 	}
4833d14abf15SRobert Mustacchi 
4834d14abf15SRobert Mustacchi 	return ECORE_RET_PENDING(pending_bit, pending);
4835d14abf15SRobert Mustacchi }
4836d14abf15SRobert Mustacchi 
ecore_queue_set_pending(struct ecore_queue_sp_obj * obj,struct ecore_queue_state_params * params)4837d14abf15SRobert Mustacchi static int ecore_queue_set_pending(struct ecore_queue_sp_obj *obj,
4838d14abf15SRobert Mustacchi 				   struct ecore_queue_state_params *params)
4839d14abf15SRobert Mustacchi {
4840d14abf15SRobert Mustacchi 	enum ecore_queue_cmd cmd = params->cmd, bit;
4841d14abf15SRobert Mustacchi 
4842d14abf15SRobert Mustacchi 	/* ACTIVATE and DEACTIVATE commands are implemented on top of
4843d14abf15SRobert Mustacchi 	 * UPDATE command.
4844d14abf15SRobert Mustacchi 	 */
4845d14abf15SRobert Mustacchi 	if ((cmd == ECORE_Q_CMD_ACTIVATE) ||
4846d14abf15SRobert Mustacchi 	    (cmd == ECORE_Q_CMD_DEACTIVATE))
4847d14abf15SRobert Mustacchi 		bit = ECORE_Q_CMD_UPDATE;
4848d14abf15SRobert Mustacchi 	else
4849d14abf15SRobert Mustacchi 		bit = cmd;
4850d14abf15SRobert Mustacchi 
4851d14abf15SRobert Mustacchi 	ECORE_SET_BIT(bit, &obj->pending);
4852d14abf15SRobert Mustacchi 	return bit;
4853d14abf15SRobert Mustacchi }
4854d14abf15SRobert Mustacchi 
ecore_queue_wait_comp(struct _lm_device_t * pdev,struct ecore_queue_sp_obj * o,enum ecore_queue_cmd cmd)4855d14abf15SRobert Mustacchi static int ecore_queue_wait_comp(struct _lm_device_t *pdev,
4856d14abf15SRobert Mustacchi 				 struct ecore_queue_sp_obj *o,
4857d14abf15SRobert Mustacchi 				 enum ecore_queue_cmd cmd)
4858d14abf15SRobert Mustacchi {
4859d14abf15SRobert Mustacchi 	return ecore_state_wait(pdev, cmd, &o->pending);
4860d14abf15SRobert Mustacchi }
4861d14abf15SRobert Mustacchi 
4862d14abf15SRobert Mustacchi /**
4863d14abf15SRobert Mustacchi  * ecore_queue_comp_cmd - complete the state change command.
4864d14abf15SRobert Mustacchi  *
4865d14abf15SRobert Mustacchi  * @pdev:	device handle
4866d14abf15SRobert Mustacchi  * @o:
4867d14abf15SRobert Mustacchi  * @cmd:
4868d14abf15SRobert Mustacchi  *
4869d14abf15SRobert Mustacchi  * Checks that the arrived completion is expected.
4870d14abf15SRobert Mustacchi  */
ecore_queue_comp_cmd(struct _lm_device_t * pdev,struct ecore_queue_sp_obj * o,enum ecore_queue_cmd cmd)4871d14abf15SRobert Mustacchi static int ecore_queue_comp_cmd(struct _lm_device_t *pdev,
4872d14abf15SRobert Mustacchi 				struct ecore_queue_sp_obj *o,
4873d14abf15SRobert Mustacchi 				enum ecore_queue_cmd cmd)
4874d14abf15SRobert Mustacchi {
4875d14abf15SRobert Mustacchi 	unsigned long cur_pending = o->pending;
4876d14abf15SRobert Mustacchi 
4877d14abf15SRobert Mustacchi 	if (!ECORE_TEST_AND_CLEAR_BIT(cmd, &cur_pending)) {
4878d14abf15SRobert Mustacchi 		ECORE_ERR("Bad MC reply %d for queue %d in state %d pending 0x%lx, next_state %d\n",
4879d14abf15SRobert Mustacchi 			  cmd, o->cids[ECORE_PRIMARY_CID_INDEX],
4880d14abf15SRobert Mustacchi 			  o->state, cur_pending, o->next_state);
4881d14abf15SRobert Mustacchi 		return ECORE_INVAL;
4882d14abf15SRobert Mustacchi 	}
4883d14abf15SRobert Mustacchi 
4884d14abf15SRobert Mustacchi 	if (o->next_tx_only >= o->max_cos)
4885d14abf15SRobert Mustacchi 		/* >= because tx only must always be smaller than cos since the
4886d14abf15SRobert Mustacchi 		 * primary connection supports COS 0
4887d14abf15SRobert Mustacchi 		 */
4888d14abf15SRobert Mustacchi 		ECORE_ERR("illegal value for next tx_only: %d. max cos was %d",
4889d14abf15SRobert Mustacchi 			  o->next_tx_only, o->max_cos);
4890d14abf15SRobert Mustacchi 
4891d14abf15SRobert Mustacchi 	ECORE_MSG(pdev,
4892d14abf15SRobert Mustacchi 		  "Completing command %d for queue %d, setting state to %d\n",
4893d14abf15SRobert Mustacchi 		  cmd, o->cids[ECORE_PRIMARY_CID_INDEX], o->next_state);
4894d14abf15SRobert Mustacchi 
4895d14abf15SRobert Mustacchi 	if (o->next_tx_only)  /* print num tx-only if any exist */
4896d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "primary cid %d: num tx-only cons %d\n",
4897d14abf15SRobert Mustacchi 			  o->cids[ECORE_PRIMARY_CID_INDEX], o->next_tx_only);
4898d14abf15SRobert Mustacchi 
4899d14abf15SRobert Mustacchi 	o->state = o->next_state;
4900d14abf15SRobert Mustacchi 	o->num_tx_only = o->next_tx_only;
4901d14abf15SRobert Mustacchi 	o->next_state = ECORE_Q_STATE_MAX;
4902d14abf15SRobert Mustacchi 
4903d14abf15SRobert Mustacchi 	/* It's important that o->state and o->next_state are
4904d14abf15SRobert Mustacchi 	 * updated before o->pending.
4905d14abf15SRobert Mustacchi 	 */
4906d14abf15SRobert Mustacchi 	wmb();
4907d14abf15SRobert Mustacchi 
4908d14abf15SRobert Mustacchi 	ECORE_CLEAR_BIT(cmd, &o->pending);
4909d14abf15SRobert Mustacchi 	smp_mb__after_atomic();
4910d14abf15SRobert Mustacchi 
4911d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
4912d14abf15SRobert Mustacchi }
4913d14abf15SRobert Mustacchi 
ecore_q_fill_setup_data_e2(struct _lm_device_t * pdev,struct ecore_queue_state_params * cmd_params,struct client_init_ramrod_data * data)4914d14abf15SRobert Mustacchi static void ecore_q_fill_setup_data_e2(struct _lm_device_t *pdev,
4915d14abf15SRobert Mustacchi 				struct ecore_queue_state_params *cmd_params,
4916d14abf15SRobert Mustacchi 				struct client_init_ramrod_data *data)
4917d14abf15SRobert Mustacchi {
4918d14abf15SRobert Mustacchi 	struct ecore_queue_setup_params *params = &cmd_params->params.setup;
4919d14abf15SRobert Mustacchi 
4920d14abf15SRobert Mustacchi 	/* Rx data */
4921d14abf15SRobert Mustacchi 
4922d14abf15SRobert Mustacchi 	/* IPv6 TPA supported for E2 and above only */
4923d14abf15SRobert Mustacchi 	data->rx.tpa_en |= ECORE_TEST_BIT(ECORE_Q_FLG_TPA_IPV6,
4924d14abf15SRobert Mustacchi 					  &params->flags) *
4925d14abf15SRobert Mustacchi 				CLIENT_INIT_RX_DATA_TPA_EN_IPV6;
4926d14abf15SRobert Mustacchi }
4927d14abf15SRobert Mustacchi 
ecore_q_fill_init_general_data(struct _lm_device_t * pdev,struct ecore_queue_sp_obj * o,struct ecore_general_setup_params * params,struct client_init_general_data * gen_data,unsigned long * flags)4928d14abf15SRobert Mustacchi static void ecore_q_fill_init_general_data(struct _lm_device_t *pdev,
4929d14abf15SRobert Mustacchi 				struct ecore_queue_sp_obj *o,
4930d14abf15SRobert Mustacchi 				struct ecore_general_setup_params *params,
4931d14abf15SRobert Mustacchi 				struct client_init_general_data *gen_data,
4932d14abf15SRobert Mustacchi 				unsigned long *flags)
4933d14abf15SRobert Mustacchi {
4934d14abf15SRobert Mustacchi 	gen_data->client_id = o->cl_id;
4935d14abf15SRobert Mustacchi 
4936d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_Q_FLG_STATS, flags)) {
4937d14abf15SRobert Mustacchi 		gen_data->statistics_counter_id =
4938d14abf15SRobert Mustacchi 					params->stat_id;
4939d14abf15SRobert Mustacchi 		gen_data->statistics_en_flg = 1;
4940d14abf15SRobert Mustacchi 		gen_data->statistics_zero_flg =
4941d14abf15SRobert Mustacchi 			ECORE_TEST_BIT(ECORE_Q_FLG_ZERO_STATS, flags);
4942d14abf15SRobert Mustacchi 	} else
4943d14abf15SRobert Mustacchi 		gen_data->statistics_counter_id =
4944d14abf15SRobert Mustacchi 					DISABLE_STATISTIC_COUNTER_ID_VALUE;
4945d14abf15SRobert Mustacchi 
4946d14abf15SRobert Mustacchi 	gen_data->is_fcoe_flg = ECORE_TEST_BIT(ECORE_Q_FLG_FCOE,
4947d14abf15SRobert Mustacchi 						   flags);
4948d14abf15SRobert Mustacchi 	gen_data->activate_flg = ECORE_TEST_BIT(ECORE_Q_FLG_ACTIVE,
4949d14abf15SRobert Mustacchi 						    flags);
4950d14abf15SRobert Mustacchi 	gen_data->sp_client_id = params->spcl_id;
4951d14abf15SRobert Mustacchi 	gen_data->mtu = mm_cpu_to_le16(params->mtu);
4952d14abf15SRobert Mustacchi 	gen_data->func_id = o->func_id;
4953d14abf15SRobert Mustacchi 
4954d14abf15SRobert Mustacchi 	gen_data->cos = params->cos;
4955d14abf15SRobert Mustacchi 
4956d14abf15SRobert Mustacchi 	gen_data->traffic_type =
4957d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_FCOE, flags) ?
4958d14abf15SRobert Mustacchi 		LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW;
4959d14abf15SRobert Mustacchi 
4960d14abf15SRobert Mustacchi 	gen_data->fp_hsi_ver = ETH_FP_HSI_VERSION;
4961d14abf15SRobert Mustacchi 
4962d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "flags: active %d, cos %d, stats en %d\n",
4963d14abf15SRobert Mustacchi 		  gen_data->activate_flg, gen_data->cos, gen_data->statistics_en_flg);
4964d14abf15SRobert Mustacchi }
4965d14abf15SRobert Mustacchi 
ecore_q_fill_init_tx_data(struct ecore_queue_sp_obj * o,struct ecore_txq_setup_params * params,struct client_init_tx_data * tx_data,unsigned long * flags)4966d14abf15SRobert Mustacchi static void ecore_q_fill_init_tx_data(struct ecore_queue_sp_obj *o,
4967d14abf15SRobert Mustacchi 				struct ecore_txq_setup_params *params,
4968d14abf15SRobert Mustacchi 				struct client_init_tx_data *tx_data,
4969d14abf15SRobert Mustacchi 				unsigned long *flags)
4970d14abf15SRobert Mustacchi {
4971d14abf15SRobert Mustacchi 	tx_data->enforce_security_flg =
4972d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_TX_SEC, flags);
4973d14abf15SRobert Mustacchi 	tx_data->default_vlan =
4974d14abf15SRobert Mustacchi 		mm_cpu_to_le16(params->default_vlan);
4975d14abf15SRobert Mustacchi 	tx_data->default_vlan_flg =
4976d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_DEF_VLAN, flags);
4977d14abf15SRobert Mustacchi 	tx_data->tx_switching_flg =
4978d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_TX_SWITCH, flags);
4979d14abf15SRobert Mustacchi 	tx_data->anti_spoofing_flg =
4980d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_ANTI_SPOOF, flags);
4981d14abf15SRobert Mustacchi 	tx_data->force_default_pri_flg =
4982d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_FORCE_DEFAULT_PRI, flags);
4983d14abf15SRobert Mustacchi 	tx_data->refuse_outband_vlan_flg =
4984d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_REFUSE_OUTBAND_VLAN, flags);
4985d14abf15SRobert Mustacchi 	tx_data->tunnel_lso_inc_ip_id =
4986d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_TUN_INC_INNER_IP_ID, flags);
4987d14abf15SRobert Mustacchi 	tx_data->tunnel_non_lso_pcsum_location =
4988d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_PCSUM_ON_PKT, flags) ? CSUM_ON_PKT :
4989d14abf15SRobert Mustacchi 							    CSUM_ON_BD;
4990d14abf15SRobert Mustacchi 
4991d14abf15SRobert Mustacchi 	tx_data->tx_status_block_id = params->fw_sb_id;
4992d14abf15SRobert Mustacchi 	tx_data->tx_sb_index_number = params->sb_cq_index;
4993d14abf15SRobert Mustacchi 	tx_data->tss_leading_client_id = params->tss_leading_cl_id;
4994d14abf15SRobert Mustacchi 
4995d14abf15SRobert Mustacchi 	tx_data->tx_bd_page_base.lo =
4996d14abf15SRobert Mustacchi 		mm_cpu_to_le32(U64_LO(params->dscr_map.as_u64));
4997d14abf15SRobert Mustacchi 	tx_data->tx_bd_page_base.hi =
4998d14abf15SRobert Mustacchi 		mm_cpu_to_le32(U64_HI(params->dscr_map.as_u64));
4999d14abf15SRobert Mustacchi 
5000d14abf15SRobert Mustacchi 	/* Don't configure any Tx switching mode during queue SETUP */
5001d14abf15SRobert Mustacchi 	tx_data->state = 0;
5002d14abf15SRobert Mustacchi }
5003d14abf15SRobert Mustacchi 
ecore_q_fill_init_pause_data(struct ecore_queue_sp_obj * o,struct rxq_pause_params * params,struct client_init_rx_data * rx_data)5004d14abf15SRobert Mustacchi static void ecore_q_fill_init_pause_data(struct ecore_queue_sp_obj *o,
5005d14abf15SRobert Mustacchi 				struct rxq_pause_params *params,
5006d14abf15SRobert Mustacchi 				struct client_init_rx_data *rx_data)
5007d14abf15SRobert Mustacchi {
5008d14abf15SRobert Mustacchi 	/* flow control data */
5009d14abf15SRobert Mustacchi 	rx_data->cqe_pause_thr_low = mm_cpu_to_le16(params->rcq_th_lo);
5010d14abf15SRobert Mustacchi 	rx_data->cqe_pause_thr_high = mm_cpu_to_le16(params->rcq_th_hi);
5011d14abf15SRobert Mustacchi 	rx_data->bd_pause_thr_low = mm_cpu_to_le16(params->bd_th_lo);
5012d14abf15SRobert Mustacchi 	rx_data->bd_pause_thr_high = mm_cpu_to_le16(params->bd_th_hi);
5013d14abf15SRobert Mustacchi 	rx_data->sge_pause_thr_low = mm_cpu_to_le16(params->sge_th_lo);
5014d14abf15SRobert Mustacchi 	rx_data->sge_pause_thr_high = mm_cpu_to_le16(params->sge_th_hi);
5015d14abf15SRobert Mustacchi 	rx_data->rx_cos_mask = mm_cpu_to_le16(params->pri_map);
5016d14abf15SRobert Mustacchi }
5017d14abf15SRobert Mustacchi 
ecore_q_fill_init_rx_data(struct ecore_queue_sp_obj * o,struct ecore_rxq_setup_params * params,struct client_init_rx_data * rx_data,unsigned long * flags)5018d14abf15SRobert Mustacchi static void ecore_q_fill_init_rx_data(struct ecore_queue_sp_obj *o,
5019d14abf15SRobert Mustacchi 				struct ecore_rxq_setup_params *params,
5020d14abf15SRobert Mustacchi 				struct client_init_rx_data *rx_data,
5021d14abf15SRobert Mustacchi 				unsigned long *flags)
5022d14abf15SRobert Mustacchi {
5023d14abf15SRobert Mustacchi 	rx_data->tpa_en = ECORE_TEST_BIT(ECORE_Q_FLG_TPA, flags) *
5024d14abf15SRobert Mustacchi 				CLIENT_INIT_RX_DATA_TPA_EN_IPV4;
5025d14abf15SRobert Mustacchi 	rx_data->tpa_en |= ECORE_TEST_BIT(ECORE_Q_FLG_TPA_GRO, flags) *
5026d14abf15SRobert Mustacchi 				CLIENT_INIT_RX_DATA_TPA_MODE;
5027d14abf15SRobert Mustacchi #ifdef ECORE_UPSTREAM /* ECORE_UPSTREAM */
5028d14abf15SRobert Mustacchi 	rx_data->vmqueue_mode_en_flg = 0;
5029d14abf15SRobert Mustacchi #else
5030d14abf15SRobert Mustacchi 	rx_data->vmqueue_mode_en_flg =
5031d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_VMQUEUE_MODE, flags);
5032d14abf15SRobert Mustacchi #endif
5033d14abf15SRobert Mustacchi 
5034d14abf15SRobert Mustacchi #ifdef ECORE_OOO /* ! ECORE_UPSTREAM */
5035d14abf15SRobert Mustacchi 	rx_data->extra_data_over_sgl_en_flg =
5036d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_OOO, flags);
5037d14abf15SRobert Mustacchi #endif
5038d14abf15SRobert Mustacchi 	rx_data->cache_line_alignment_log_size =
5039d14abf15SRobert Mustacchi 		params->cache_line_log;
5040d14abf15SRobert Mustacchi 	rx_data->enable_dynamic_hc =
5041d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_DHC, flags);
5042d14abf15SRobert Mustacchi 	rx_data->max_sges_for_packet = params->max_sges_pkt;
5043d14abf15SRobert Mustacchi 	rx_data->client_qzone_id = params->cl_qzone_id;
5044d14abf15SRobert Mustacchi 	rx_data->max_agg_size = mm_cpu_to_le16(params->tpa_agg_sz);
5045d14abf15SRobert Mustacchi 
5046d14abf15SRobert Mustacchi 	/* Always start in DROP_ALL mode */
5047d14abf15SRobert Mustacchi 	rx_data->state = mm_cpu_to_le16(CLIENT_INIT_RX_DATA_UCAST_DROP_ALL |
5048d14abf15SRobert Mustacchi 				     CLIENT_INIT_RX_DATA_MCAST_DROP_ALL);
5049d14abf15SRobert Mustacchi 
5050d14abf15SRobert Mustacchi 	/* We don't set drop flags */
5051d14abf15SRobert Mustacchi 	rx_data->drop_ip_cs_err_flg = 0;
5052d14abf15SRobert Mustacchi 	rx_data->drop_tcp_cs_err_flg = 0;
5053d14abf15SRobert Mustacchi 	rx_data->drop_ttl0_flg = 0;
5054d14abf15SRobert Mustacchi 	rx_data->drop_udp_cs_err_flg = 0;
5055d14abf15SRobert Mustacchi 	rx_data->inner_vlan_removal_enable_flg =
5056d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_VLAN, flags);
5057d14abf15SRobert Mustacchi 	rx_data->outer_vlan_removal_enable_flg =
5058d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_OV, flags);
5059d14abf15SRobert Mustacchi 	rx_data->status_block_id = params->fw_sb_id;
5060d14abf15SRobert Mustacchi 	rx_data->rx_sb_index_number = params->sb_cq_index;
5061d14abf15SRobert Mustacchi 	rx_data->max_tpa_queues = params->max_tpa_queues;
5062d14abf15SRobert Mustacchi 	rx_data->max_bytes_on_bd = mm_cpu_to_le16(params->buf_sz);
5063d14abf15SRobert Mustacchi 	rx_data->sge_buff_size = mm_cpu_to_le16(params->sge_buf_sz);
5064d14abf15SRobert Mustacchi 	rx_data->bd_page_base.lo =
5065d14abf15SRobert Mustacchi 		mm_cpu_to_le32(U64_LO(params->dscr_map.as_u64));
5066d14abf15SRobert Mustacchi 	rx_data->bd_page_base.hi =
5067d14abf15SRobert Mustacchi 		mm_cpu_to_le32(U64_HI(params->dscr_map.as_u64));
5068d14abf15SRobert Mustacchi 	rx_data->sge_page_base.lo =
5069d14abf15SRobert Mustacchi 		mm_cpu_to_le32(U64_LO(params->sge_map.as_u64));
5070d14abf15SRobert Mustacchi 	rx_data->sge_page_base.hi =
5071d14abf15SRobert Mustacchi 		mm_cpu_to_le32(U64_HI(params->sge_map.as_u64));
5072d14abf15SRobert Mustacchi 	rx_data->cqe_page_base.lo =
5073d14abf15SRobert Mustacchi 		mm_cpu_to_le32(U64_LO(params->rcq_map.as_u64));
5074d14abf15SRobert Mustacchi 	rx_data->cqe_page_base.hi =
5075d14abf15SRobert Mustacchi 		mm_cpu_to_le32(U64_HI(params->rcq_map.as_u64));
5076d14abf15SRobert Mustacchi 	rx_data->is_leading_rss = ECORE_TEST_BIT(ECORE_Q_FLG_LEADING_RSS,
5077d14abf15SRobert Mustacchi 						 flags);
5078d14abf15SRobert Mustacchi 
5079d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_Q_FLG_MCAST, flags)) {
5080d14abf15SRobert Mustacchi 		rx_data->approx_mcast_engine_id = params->mcast_engine_id;
5081d14abf15SRobert Mustacchi 		rx_data->is_approx_mcast = 1;
5082d14abf15SRobert Mustacchi 	}
5083d14abf15SRobert Mustacchi 
5084d14abf15SRobert Mustacchi 	rx_data->rss_engine_id = params->rss_engine_id;
5085d14abf15SRobert Mustacchi 
5086d14abf15SRobert Mustacchi 	/* silent vlan removal */
5087d14abf15SRobert Mustacchi 	rx_data->silent_vlan_removal_flg =
5088d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_FLG_SILENT_VLAN_REM, flags);
5089d14abf15SRobert Mustacchi 	rx_data->silent_vlan_value =
5090d14abf15SRobert Mustacchi 		mm_cpu_to_le16(params->silent_removal_value);
5091d14abf15SRobert Mustacchi 	rx_data->silent_vlan_mask =
5092d14abf15SRobert Mustacchi 		mm_cpu_to_le16(params->silent_removal_mask);
5093d14abf15SRobert Mustacchi }
5094d14abf15SRobert Mustacchi 
5095d14abf15SRobert Mustacchi /* initialize the general, tx and rx parts of a queue object */
ecore_q_fill_setup_data_cmn(struct _lm_device_t * pdev,struct ecore_queue_state_params * cmd_params,struct client_init_ramrod_data * data)5096d14abf15SRobert Mustacchi static void ecore_q_fill_setup_data_cmn(struct _lm_device_t *pdev,
5097d14abf15SRobert Mustacchi 				struct ecore_queue_state_params *cmd_params,
5098d14abf15SRobert Mustacchi 				struct client_init_ramrod_data *data)
5099d14abf15SRobert Mustacchi {
5100d14abf15SRobert Mustacchi 	ecore_q_fill_init_general_data(pdev, cmd_params->q_obj,
5101d14abf15SRobert Mustacchi 				       &cmd_params->params.setup.gen_params,
5102d14abf15SRobert Mustacchi 				       &data->general,
5103d14abf15SRobert Mustacchi 				       &cmd_params->params.setup.flags);
5104d14abf15SRobert Mustacchi 
5105d14abf15SRobert Mustacchi 	ecore_q_fill_init_tx_data(cmd_params->q_obj,
5106d14abf15SRobert Mustacchi 				  &cmd_params->params.setup.txq_params,
5107d14abf15SRobert Mustacchi 				  &data->tx,
5108d14abf15SRobert Mustacchi 				  &cmd_params->params.setup.flags);
5109d14abf15SRobert Mustacchi 
5110d14abf15SRobert Mustacchi 	ecore_q_fill_init_rx_data(cmd_params->q_obj,
5111d14abf15SRobert Mustacchi 				  &cmd_params->params.setup.rxq_params,
5112d14abf15SRobert Mustacchi 				  &data->rx,
5113d14abf15SRobert Mustacchi 				  &cmd_params->params.setup.flags);
5114d14abf15SRobert Mustacchi 
5115d14abf15SRobert Mustacchi 	ecore_q_fill_init_pause_data(cmd_params->q_obj,
5116d14abf15SRobert Mustacchi 				     &cmd_params->params.setup.pause_params,
5117d14abf15SRobert Mustacchi 				     &data->rx);
5118d14abf15SRobert Mustacchi }
5119d14abf15SRobert Mustacchi 
5120d14abf15SRobert Mustacchi /* initialize the general and tx parts of a tx-only queue object */
ecore_q_fill_setup_tx_only(struct _lm_device_t * pdev,struct ecore_queue_state_params * cmd_params,struct tx_queue_init_ramrod_data * data)5121d14abf15SRobert Mustacchi static void ecore_q_fill_setup_tx_only(struct _lm_device_t *pdev,
5122d14abf15SRobert Mustacchi 				struct ecore_queue_state_params *cmd_params,
5123d14abf15SRobert Mustacchi 				struct tx_queue_init_ramrod_data *data)
5124d14abf15SRobert Mustacchi {
5125d14abf15SRobert Mustacchi 	ecore_q_fill_init_general_data(pdev, cmd_params->q_obj,
5126d14abf15SRobert Mustacchi 				       &cmd_params->params.tx_only.gen_params,
5127d14abf15SRobert Mustacchi 				       &data->general,
5128d14abf15SRobert Mustacchi 				       &cmd_params->params.tx_only.flags);
5129d14abf15SRobert Mustacchi 
5130d14abf15SRobert Mustacchi 	ecore_q_fill_init_tx_data(cmd_params->q_obj,
5131d14abf15SRobert Mustacchi 				  &cmd_params->params.tx_only.txq_params,
5132d14abf15SRobert Mustacchi 				  &data->tx,
5133d14abf15SRobert Mustacchi 				  &cmd_params->params.tx_only.flags);
5134d14abf15SRobert Mustacchi 
5135d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "cid %d, tx bd page lo %x hi %x",
5136d14abf15SRobert Mustacchi 		  cmd_params->q_obj->cids[0],
5137d14abf15SRobert Mustacchi 		  data->tx.tx_bd_page_base.lo,
5138d14abf15SRobert Mustacchi 		  data->tx.tx_bd_page_base.hi);
5139d14abf15SRobert Mustacchi }
5140d14abf15SRobert Mustacchi 
5141d14abf15SRobert Mustacchi /**
5142d14abf15SRobert Mustacchi  * ecore_q_init - init HW/FW queue
5143d14abf15SRobert Mustacchi  *
5144d14abf15SRobert Mustacchi  * @pdev:	device handle
5145d14abf15SRobert Mustacchi  * @params:
5146d14abf15SRobert Mustacchi  *
5147d14abf15SRobert Mustacchi  * HW/FW initial Queue configuration:
5148d14abf15SRobert Mustacchi  *      - HC: Rx and Tx
5149d14abf15SRobert Mustacchi  *      - CDU context validation
5150d14abf15SRobert Mustacchi  *
5151d14abf15SRobert Mustacchi  */
ecore_q_init(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5152d14abf15SRobert Mustacchi static INLINE int ecore_q_init(struct _lm_device_t *pdev,
5153d14abf15SRobert Mustacchi 			       struct ecore_queue_state_params *params)
5154d14abf15SRobert Mustacchi {
5155d14abf15SRobert Mustacchi 	struct ecore_queue_sp_obj *o = params->q_obj;
5156d14abf15SRobert Mustacchi 	struct ecore_queue_init_params *init = &params->params.init;
5157d14abf15SRobert Mustacchi 	u16 hc_usec;
5158d14abf15SRobert Mustacchi 	u8 cos;
5159d14abf15SRobert Mustacchi 
5160d14abf15SRobert Mustacchi 	/* Tx HC configuration */
5161d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_Q_TYPE_HAS_TX, &o->type) &&
5162d14abf15SRobert Mustacchi 	    ECORE_TEST_BIT(ECORE_Q_FLG_HC, &init->tx.flags)) {
5163d14abf15SRobert Mustacchi 		hc_usec = init->tx.hc_rate ? 1000000 / init->tx.hc_rate : 0;
5164d14abf15SRobert Mustacchi 
5165d14abf15SRobert Mustacchi 		ECORE_TODO_UPDATE_COALESCE_SB_INDEX(pdev, init->tx.fw_sb_id,
5166d14abf15SRobert Mustacchi 			init->tx.sb_cq_index,
5167d14abf15SRobert Mustacchi 			!ECORE_TEST_BIT(ECORE_Q_FLG_HC_EN, &init->tx.flags),
5168d14abf15SRobert Mustacchi 			hc_usec);
5169d14abf15SRobert Mustacchi 	}
5170d14abf15SRobert Mustacchi 
5171d14abf15SRobert Mustacchi 	/* Rx HC configuration */
5172d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_Q_TYPE_HAS_RX, &o->type) &&
5173d14abf15SRobert Mustacchi 	    ECORE_TEST_BIT(ECORE_Q_FLG_HC, &init->rx.flags)) {
5174d14abf15SRobert Mustacchi 		hc_usec = init->rx.hc_rate ? 1000000 / init->rx.hc_rate : 0;
5175d14abf15SRobert Mustacchi 
5176d14abf15SRobert Mustacchi 		ECORE_TODO_UPDATE_COALESCE_SB_INDEX(pdev, init->rx.fw_sb_id,
5177d14abf15SRobert Mustacchi 			init->rx.sb_cq_index,
5178d14abf15SRobert Mustacchi 			!ECORE_TEST_BIT(ECORE_Q_FLG_HC_EN, &init->rx.flags),
5179d14abf15SRobert Mustacchi 			hc_usec);
5180d14abf15SRobert Mustacchi 	}
5181d14abf15SRobert Mustacchi 
5182d14abf15SRobert Mustacchi 	/* Set CDU context validation values */
5183d14abf15SRobert Mustacchi 	for (cos = 0; cos < o->max_cos; cos++) {
5184d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "setting context validation. cid %d, cos %d\n",
5185d14abf15SRobert Mustacchi 			  o->cids[cos], cos);
5186d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "context pointer %p\n", init->cxts[cos]);
5187d14abf15SRobert Mustacchi 		ECORE_SET_CTX_VALIDATION(pdev, init->cxts[cos], o->cids[cos]);
5188d14abf15SRobert Mustacchi 	}
5189d14abf15SRobert Mustacchi 
5190d14abf15SRobert Mustacchi 	/* As no ramrod is sent, complete the command immediately  */
5191d14abf15SRobert Mustacchi 	o->complete_cmd(pdev, o, ECORE_Q_CMD_INIT);
5192d14abf15SRobert Mustacchi 
5193d14abf15SRobert Mustacchi 	mmiowb();
5194d14abf15SRobert Mustacchi 	smp_mb();
5195d14abf15SRobert Mustacchi 
5196d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
5197d14abf15SRobert Mustacchi }
5198d14abf15SRobert Mustacchi 
ecore_q_send_setup_e1x(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5199d14abf15SRobert Mustacchi static INLINE int ecore_q_send_setup_e1x(struct _lm_device_t *pdev,
5200d14abf15SRobert Mustacchi 					struct ecore_queue_state_params *params)
5201d14abf15SRobert Mustacchi {
5202d14abf15SRobert Mustacchi 	struct ecore_queue_sp_obj *o = params->q_obj;
5203d14abf15SRobert Mustacchi 	struct client_init_ramrod_data *rdata =
5204d14abf15SRobert Mustacchi 		(struct client_init_ramrod_data *)o->rdata;
5205d14abf15SRobert Mustacchi 	lm_address_t data_mapping = o->rdata_mapping;
5206d14abf15SRobert Mustacchi 	int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP;
5207d14abf15SRobert Mustacchi 
5208d14abf15SRobert Mustacchi 	/* Clear the ramrod data */
5209d14abf15SRobert Mustacchi 	mm_memset(rdata, 0, sizeof(*rdata));
5210d14abf15SRobert Mustacchi 
5211d14abf15SRobert Mustacchi 	/* Fill the ramrod data */
5212d14abf15SRobert Mustacchi 	ecore_q_fill_setup_data_cmn(pdev, params, rdata);
5213d14abf15SRobert Mustacchi 
5214d14abf15SRobert Mustacchi 	/* No need for an explicit memory barrier here as long as we
5215d14abf15SRobert Mustacchi 	 * ensure the ordering of writing to the SPQ element
5216d14abf15SRobert Mustacchi 	 * and updating of the SPQ producer which involves a memory
5217d14abf15SRobert Mustacchi 	 * read. If the memory read is removed we will have to put a
5218d14abf15SRobert Mustacchi 	 * full memory barrier there (inside ecore_sp_post()).
5219d14abf15SRobert Mustacchi 	 */
5220d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev,
5221d14abf15SRobert Mustacchi 			     ramrod,
5222d14abf15SRobert Mustacchi 			     o->cids[ECORE_PRIMARY_CID_INDEX],
5223d14abf15SRobert Mustacchi 			     data_mapping.as_u64,
5224d14abf15SRobert Mustacchi 			     ETH_CONNECTION_TYPE);
5225d14abf15SRobert Mustacchi }
5226d14abf15SRobert Mustacchi 
ecore_q_send_setup_e2(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5227d14abf15SRobert Mustacchi static INLINE int ecore_q_send_setup_e2(struct _lm_device_t *pdev,
5228d14abf15SRobert Mustacchi 					struct ecore_queue_state_params *params)
5229d14abf15SRobert Mustacchi {
5230d14abf15SRobert Mustacchi 	struct ecore_queue_sp_obj *o = params->q_obj;
5231d14abf15SRobert Mustacchi 	struct client_init_ramrod_data *rdata =
5232d14abf15SRobert Mustacchi 		(struct client_init_ramrod_data *)o->rdata;
5233d14abf15SRobert Mustacchi 	lm_address_t data_mapping = o->rdata_mapping;
5234d14abf15SRobert Mustacchi 	int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP;
5235d14abf15SRobert Mustacchi 
5236d14abf15SRobert Mustacchi 	/* Clear the ramrod data */
5237d14abf15SRobert Mustacchi 	mm_memset(rdata, 0, sizeof(*rdata));
5238d14abf15SRobert Mustacchi 
5239d14abf15SRobert Mustacchi 	/* Fill the ramrod data */
5240d14abf15SRobert Mustacchi 	ecore_q_fill_setup_data_cmn(pdev, params, rdata);
5241d14abf15SRobert Mustacchi 	ecore_q_fill_setup_data_e2(pdev, params, rdata);
5242d14abf15SRobert Mustacchi 
5243d14abf15SRobert Mustacchi 	/* No need for an explicit memory barrier here as long as we
5244d14abf15SRobert Mustacchi 	 * ensure the ordering of writing to the SPQ element
5245d14abf15SRobert Mustacchi 	 * and updating of the SPQ producer which involves a memory
5246d14abf15SRobert Mustacchi 	 * read. If the memory read is removed we will have to put a
5247d14abf15SRobert Mustacchi 	 * full memory barrier there (inside ecore_sp_post()).
5248d14abf15SRobert Mustacchi 	 */
5249d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev,
5250d14abf15SRobert Mustacchi 			     ramrod,
5251d14abf15SRobert Mustacchi 			     o->cids[ECORE_PRIMARY_CID_INDEX],
5252d14abf15SRobert Mustacchi 			     data_mapping.as_u64,
5253d14abf15SRobert Mustacchi 			     ETH_CONNECTION_TYPE);
5254d14abf15SRobert Mustacchi }
5255d14abf15SRobert Mustacchi 
ecore_q_send_setup_tx_only(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5256d14abf15SRobert Mustacchi static inline int ecore_q_send_setup_tx_only(struct _lm_device_t *pdev,
5257d14abf15SRobert Mustacchi 				  struct ecore_queue_state_params *params)
5258d14abf15SRobert Mustacchi {
5259d14abf15SRobert Mustacchi 	struct ecore_queue_sp_obj *o = params->q_obj;
5260d14abf15SRobert Mustacchi 	struct tx_queue_init_ramrod_data *rdata =
5261d14abf15SRobert Mustacchi 		(struct tx_queue_init_ramrod_data *)o->rdata;
5262d14abf15SRobert Mustacchi 	lm_address_t data_mapping = o->rdata_mapping;
5263d14abf15SRobert Mustacchi 	int ramrod = RAMROD_CMD_ID_ETH_TX_QUEUE_SETUP;
5264d14abf15SRobert Mustacchi 	struct ecore_queue_setup_tx_only_params *tx_only_params =
5265d14abf15SRobert Mustacchi 		&params->params.tx_only;
5266d14abf15SRobert Mustacchi 	u8 cid_index = tx_only_params->cid_index;
5267d14abf15SRobert Mustacchi 
5268d14abf15SRobert Mustacchi #ifdef ECORE_OOO /* ! ECORE_UPSTREAM */
5269d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_Q_TYPE_FWD, &o->type))
5270d14abf15SRobert Mustacchi 		ramrod = RAMROD_CMD_ID_ETH_FORWARD_SETUP;
5271d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "sending forward tx-only ramrod");
5272d14abf15SRobert Mustacchi #endif
5273d14abf15SRobert Mustacchi 
5274d14abf15SRobert Mustacchi 	if (cid_index >= o->max_cos) {
5275d14abf15SRobert Mustacchi 		ECORE_ERR("queue[%d]: cid_index (%d) is out of range\n",
5276d14abf15SRobert Mustacchi 			  o->cl_id, cid_index);
5277d14abf15SRobert Mustacchi 		return ECORE_INVAL;
5278d14abf15SRobert Mustacchi 	}
5279d14abf15SRobert Mustacchi 
5280d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "parameters received: cos: %d sp-id: %d\n",
5281d14abf15SRobert Mustacchi 		  tx_only_params->gen_params.cos,
5282d14abf15SRobert Mustacchi 		  tx_only_params->gen_params.spcl_id);
5283d14abf15SRobert Mustacchi 
5284d14abf15SRobert Mustacchi 	/* Clear the ramrod data */
5285d14abf15SRobert Mustacchi 	mm_memset(rdata, 0, sizeof(*rdata));
5286d14abf15SRobert Mustacchi 
5287d14abf15SRobert Mustacchi 	/* Fill the ramrod data */
5288d14abf15SRobert Mustacchi 	ecore_q_fill_setup_tx_only(pdev, params, rdata);
5289d14abf15SRobert Mustacchi 
5290d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "sending tx-only ramrod: cid %d, client-id %d, sp-client id %d, cos %d\n",
5291d14abf15SRobert Mustacchi 		  o->cids[cid_index], rdata->general.client_id,
5292d14abf15SRobert Mustacchi 		  rdata->general.sp_client_id, rdata->general.cos);
5293d14abf15SRobert Mustacchi 
5294d14abf15SRobert Mustacchi 	/* No need for an explicit memory barrier here as long as we
5295d14abf15SRobert Mustacchi 	 * ensure the ordering of writing to the SPQ element
5296d14abf15SRobert Mustacchi 	 * and updating of the SPQ producer which involves a memory
5297d14abf15SRobert Mustacchi 	 * read. If the memory read is removed we will have to put a
5298d14abf15SRobert Mustacchi 	 * full memory barrier there (inside ecore_sp_post()).
5299d14abf15SRobert Mustacchi 	 */
5300d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, ramrod, o->cids[cid_index],
5301d14abf15SRobert Mustacchi 			     data_mapping.as_u64, ETH_CONNECTION_TYPE);
5302d14abf15SRobert Mustacchi }
5303d14abf15SRobert Mustacchi 
ecore_q_fill_update_data(struct _lm_device_t * pdev,struct ecore_queue_sp_obj * obj,struct ecore_queue_update_params * params,struct client_update_ramrod_data * data)5304d14abf15SRobert Mustacchi static void ecore_q_fill_update_data(struct _lm_device_t *pdev,
5305d14abf15SRobert Mustacchi 				     struct ecore_queue_sp_obj *obj,
5306d14abf15SRobert Mustacchi 				     struct ecore_queue_update_params *params,
5307d14abf15SRobert Mustacchi 				     struct client_update_ramrod_data *data)
5308d14abf15SRobert Mustacchi {
5309d14abf15SRobert Mustacchi 	/* Client ID of the client to update */
5310d14abf15SRobert Mustacchi 	data->client_id = obj->cl_id;
5311d14abf15SRobert Mustacchi 
5312d14abf15SRobert Mustacchi 	/* Function ID of the client to update */
5313d14abf15SRobert Mustacchi 	data->func_id = obj->func_id;
5314d14abf15SRobert Mustacchi 
5315d14abf15SRobert Mustacchi 	/* Default VLAN value */
5316d14abf15SRobert Mustacchi 	data->default_vlan = mm_cpu_to_le16(params->def_vlan);
5317d14abf15SRobert Mustacchi 
5318d14abf15SRobert Mustacchi 	/* Inner VLAN stripping */
5319d14abf15SRobert Mustacchi 	data->inner_vlan_removal_enable_flg =
5320d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_IN_VLAN_REM,
5321d14abf15SRobert Mustacchi 			       &params->update_flags);
5322d14abf15SRobert Mustacchi 	data->inner_vlan_removal_change_flg =
5323d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_IN_VLAN_REM_CHNG,
5324d14abf15SRobert Mustacchi 		       &params->update_flags);
5325d14abf15SRobert Mustacchi 
5326d14abf15SRobert Mustacchi 	/* Outer VLAN stripping */
5327d14abf15SRobert Mustacchi 	data->outer_vlan_removal_enable_flg =
5328d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_OUT_VLAN_REM,
5329d14abf15SRobert Mustacchi 			       &params->update_flags);
5330d14abf15SRobert Mustacchi 	data->outer_vlan_removal_change_flg =
5331d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_OUT_VLAN_REM_CHNG,
5332d14abf15SRobert Mustacchi 		       &params->update_flags);
5333d14abf15SRobert Mustacchi 
5334d14abf15SRobert Mustacchi 	/* Drop packets that have source MAC that doesn't belong to this
5335d14abf15SRobert Mustacchi 	 * Queue.
5336d14abf15SRobert Mustacchi 	 */
5337d14abf15SRobert Mustacchi 	data->anti_spoofing_enable_flg =
5338d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_ANTI_SPOOF,
5339d14abf15SRobert Mustacchi 			       &params->update_flags);
5340d14abf15SRobert Mustacchi 	data->anti_spoofing_change_flg =
5341d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_ANTI_SPOOF_CHNG,
5342d14abf15SRobert Mustacchi 		       &params->update_flags);
5343d14abf15SRobert Mustacchi 
5344d14abf15SRobert Mustacchi 	/* Activate/Deactivate */
5345d14abf15SRobert Mustacchi 	data->activate_flg =
5346d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_ACTIVATE, &params->update_flags);
5347d14abf15SRobert Mustacchi 	data->activate_change_flg =
5348d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_ACTIVATE_CHNG,
5349d14abf15SRobert Mustacchi 			       &params->update_flags);
5350d14abf15SRobert Mustacchi 
5351d14abf15SRobert Mustacchi 	/* Enable default VLAN */
5352d14abf15SRobert Mustacchi 	data->default_vlan_enable_flg =
5353d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_DEF_VLAN_EN,
5354d14abf15SRobert Mustacchi 			       &params->update_flags);
5355d14abf15SRobert Mustacchi 	data->default_vlan_change_flg =
5356d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_DEF_VLAN_EN_CHNG,
5357d14abf15SRobert Mustacchi 		       &params->update_flags);
5358d14abf15SRobert Mustacchi 
5359d14abf15SRobert Mustacchi 	/* silent vlan removal */
5360d14abf15SRobert Mustacchi 	data->silent_vlan_change_flg =
5361d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_SILENT_VLAN_REM_CHNG,
5362d14abf15SRobert Mustacchi 			       &params->update_flags);
5363d14abf15SRobert Mustacchi 	data->silent_vlan_removal_flg =
5364d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_SILENT_VLAN_REM,
5365d14abf15SRobert Mustacchi 			       &params->update_flags);
5366d14abf15SRobert Mustacchi 	data->silent_vlan_value = mm_cpu_to_le16(params->silent_removal_value);
5367d14abf15SRobert Mustacchi 	data->silent_vlan_mask = mm_cpu_to_le16(params->silent_removal_mask);
5368d14abf15SRobert Mustacchi 
5369d14abf15SRobert Mustacchi 	/* tx switching */
5370d14abf15SRobert Mustacchi 	data->tx_switching_flg =
5371d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_TX_SWITCHING,
5372d14abf15SRobert Mustacchi 			       &params->update_flags);
5373d14abf15SRobert Mustacchi 	data->tx_switching_change_flg =
5374d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_TX_SWITCHING_CHNG,
5375d14abf15SRobert Mustacchi 			       &params->update_flags);
5376d14abf15SRobert Mustacchi 
5377d14abf15SRobert Mustacchi 	/* PTP */
5378d14abf15SRobert Mustacchi 	data->handle_ptp_pkts_flg =
5379d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_PTP_PKTS,
5380d14abf15SRobert Mustacchi 			       &params->update_flags);
5381d14abf15SRobert Mustacchi 	data->handle_ptp_pkts_change_flg =
5382d14abf15SRobert Mustacchi 		ECORE_TEST_BIT(ECORE_Q_UPDATE_PTP_PKTS_CHNG,
5383d14abf15SRobert Mustacchi 			       &params->update_flags);
5384d14abf15SRobert Mustacchi }
5385d14abf15SRobert Mustacchi 
ecore_q_send_update(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5386d14abf15SRobert Mustacchi static INLINE int ecore_q_send_update(struct _lm_device_t *pdev,
5387d14abf15SRobert Mustacchi 				      struct ecore_queue_state_params *params)
5388d14abf15SRobert Mustacchi {
5389d14abf15SRobert Mustacchi 	struct ecore_queue_sp_obj *o = params->q_obj;
5390d14abf15SRobert Mustacchi 	struct client_update_ramrod_data *rdata =
5391d14abf15SRobert Mustacchi 		(struct client_update_ramrod_data *)o->rdata;
5392d14abf15SRobert Mustacchi 	lm_address_t data_mapping = o->rdata_mapping;
5393d14abf15SRobert Mustacchi 	struct ecore_queue_update_params *update_params =
5394d14abf15SRobert Mustacchi 		&params->params.update;
5395d14abf15SRobert Mustacchi 	u8 cid_index = update_params->cid_index;
5396d14abf15SRobert Mustacchi 
5397d14abf15SRobert Mustacchi 	if (cid_index >= o->max_cos) {
5398d14abf15SRobert Mustacchi 		ECORE_ERR("queue[%d]: cid_index (%d) is out of range\n",
5399d14abf15SRobert Mustacchi 			  o->cl_id, cid_index);
5400d14abf15SRobert Mustacchi 		return ECORE_INVAL;
5401d14abf15SRobert Mustacchi 	}
5402d14abf15SRobert Mustacchi 
5403d14abf15SRobert Mustacchi 	/* Clear the ramrod data */
5404d14abf15SRobert Mustacchi 	mm_memset(rdata, 0, sizeof(*rdata));
5405d14abf15SRobert Mustacchi 
5406d14abf15SRobert Mustacchi 	/* Fill the ramrod data */
5407d14abf15SRobert Mustacchi 	ecore_q_fill_update_data(pdev, o, update_params, rdata);
5408d14abf15SRobert Mustacchi 
5409d14abf15SRobert Mustacchi 	/* No need for an explicit memory barrier here as long as we
5410d14abf15SRobert Mustacchi 	 * ensure the ordering of writing to the SPQ element
5411d14abf15SRobert Mustacchi 	 * and updating of the SPQ producer which involves a memory
5412d14abf15SRobert Mustacchi 	 * read. If the memory read is removed we will have to put a
5413d14abf15SRobert Mustacchi 	 * full memory barrier there (inside ecore_sp_post()).
5414d14abf15SRobert Mustacchi 	 */
5415d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, RAMROD_CMD_ID_ETH_CLIENT_UPDATE,
5416d14abf15SRobert Mustacchi 			     o->cids[cid_index], data_mapping.as_u64,
5417d14abf15SRobert Mustacchi 			     ETH_CONNECTION_TYPE);
5418d14abf15SRobert Mustacchi }
5419d14abf15SRobert Mustacchi 
5420d14abf15SRobert Mustacchi /**
5421d14abf15SRobert Mustacchi  * ecore_q_send_deactivate - send DEACTIVATE command
5422d14abf15SRobert Mustacchi  *
5423d14abf15SRobert Mustacchi  * @pdev:	device handle
5424d14abf15SRobert Mustacchi  * @params:
5425d14abf15SRobert Mustacchi  *
5426d14abf15SRobert Mustacchi  * implemented using the UPDATE command.
5427d14abf15SRobert Mustacchi  */
ecore_q_send_deactivate(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5428d14abf15SRobert Mustacchi static INLINE int ecore_q_send_deactivate(struct _lm_device_t *pdev,
5429d14abf15SRobert Mustacchi 					struct ecore_queue_state_params *params)
5430d14abf15SRobert Mustacchi {
5431d14abf15SRobert Mustacchi 	struct ecore_queue_update_params *update = &params->params.update;
5432d14abf15SRobert Mustacchi 
5433d14abf15SRobert Mustacchi 	mm_memset(update, 0, sizeof(*update));
5434d14abf15SRobert Mustacchi 
5435d14abf15SRobert Mustacchi 	ECORE_SET_BIT_NA(ECORE_Q_UPDATE_ACTIVATE_CHNG, &update->update_flags);
5436d14abf15SRobert Mustacchi 
5437d14abf15SRobert Mustacchi 	return ecore_q_send_update(pdev, params);
5438d14abf15SRobert Mustacchi }
5439d14abf15SRobert Mustacchi 
5440d14abf15SRobert Mustacchi /**
5441d14abf15SRobert Mustacchi  * ecore_q_send_activate - send ACTIVATE command
5442d14abf15SRobert Mustacchi  *
5443d14abf15SRobert Mustacchi  * @pdev:	device handle
5444d14abf15SRobert Mustacchi  * @params:
5445d14abf15SRobert Mustacchi  *
5446d14abf15SRobert Mustacchi  * implemented using the UPDATE command.
5447d14abf15SRobert Mustacchi  */
ecore_q_send_activate(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5448d14abf15SRobert Mustacchi static INLINE int ecore_q_send_activate(struct _lm_device_t *pdev,
5449d14abf15SRobert Mustacchi 					struct ecore_queue_state_params *params)
5450d14abf15SRobert Mustacchi {
5451d14abf15SRobert Mustacchi 	struct ecore_queue_update_params *update = &params->params.update;
5452d14abf15SRobert Mustacchi 
5453d14abf15SRobert Mustacchi 	mm_memset(update, 0, sizeof(*update));
5454d14abf15SRobert Mustacchi 
5455d14abf15SRobert Mustacchi 	ECORE_SET_BIT_NA(ECORE_Q_UPDATE_ACTIVATE, &update->update_flags);
5456d14abf15SRobert Mustacchi 	ECORE_SET_BIT_NA(ECORE_Q_UPDATE_ACTIVATE_CHNG, &update->update_flags);
5457d14abf15SRobert Mustacchi 
5458d14abf15SRobert Mustacchi 	return ecore_q_send_update(pdev, params);
5459d14abf15SRobert Mustacchi }
5460d14abf15SRobert Mustacchi 
ecore_q_fill_update_tpa_data(struct _lm_device_t * pdev,struct ecore_queue_sp_obj * obj,struct ecore_queue_update_tpa_params * params,struct tpa_update_ramrod_data * data)5461d14abf15SRobert Mustacchi static void ecore_q_fill_update_tpa_data(struct _lm_device_t *pdev,
5462d14abf15SRobert Mustacchi 				struct ecore_queue_sp_obj *obj,
5463d14abf15SRobert Mustacchi 				struct ecore_queue_update_tpa_params *params,
5464d14abf15SRobert Mustacchi 				struct tpa_update_ramrod_data *data)
5465d14abf15SRobert Mustacchi {
5466d14abf15SRobert Mustacchi 	data->client_id = obj->cl_id;
5467d14abf15SRobert Mustacchi 	data->complete_on_both_clients = params->complete_on_both_clients;
5468d14abf15SRobert Mustacchi 	data->dont_verify_rings_pause_thr_flg =
5469d14abf15SRobert Mustacchi 		params->dont_verify_thr;
5470d14abf15SRobert Mustacchi 	data->max_agg_size = mm_cpu_to_le16(params->max_agg_sz);
5471d14abf15SRobert Mustacchi 	data->max_sges_for_packet = params->max_sges_pkt;
5472d14abf15SRobert Mustacchi 	data->max_tpa_queues = params->max_tpa_queues;
5473d14abf15SRobert Mustacchi 	data->sge_buff_size = mm_cpu_to_le16(params->sge_buff_sz);
5474d14abf15SRobert Mustacchi 	data->sge_page_base_hi = mm_cpu_to_le32(U64_HI(params->sge_map.as_u64));
5475d14abf15SRobert Mustacchi 	data->sge_page_base_lo = mm_cpu_to_le32(U64_LO(params->sge_map.as_u64));
5476d14abf15SRobert Mustacchi 	data->sge_pause_thr_high = mm_cpu_to_le16(params->sge_pause_thr_high);
5477d14abf15SRobert Mustacchi 	data->sge_pause_thr_low = mm_cpu_to_le16(params->sge_pause_thr_low);
5478d14abf15SRobert Mustacchi 	data->tpa_mode = params->tpa_mode;
5479d14abf15SRobert Mustacchi 	data->update_ipv4 = params->update_ipv4;
5480d14abf15SRobert Mustacchi 	data->update_ipv6 = params->update_ipv6;
5481d14abf15SRobert Mustacchi }
5482d14abf15SRobert Mustacchi 
ecore_q_send_update_tpa(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5483d14abf15SRobert Mustacchi static INLINE int ecore_q_send_update_tpa(struct _lm_device_t *pdev,
5484d14abf15SRobert Mustacchi 					struct ecore_queue_state_params *params)
5485d14abf15SRobert Mustacchi {
5486d14abf15SRobert Mustacchi 	struct ecore_queue_sp_obj *o = params->q_obj;
5487d14abf15SRobert Mustacchi 	struct tpa_update_ramrod_data *rdata =
5488d14abf15SRobert Mustacchi 		(struct tpa_update_ramrod_data *)o->rdata;
5489d14abf15SRobert Mustacchi 	lm_address_t data_mapping = o->rdata_mapping;
5490d14abf15SRobert Mustacchi 	struct ecore_queue_update_tpa_params *update_tpa_params =
5491d14abf15SRobert Mustacchi 		&params->params.update_tpa;
5492d14abf15SRobert Mustacchi 	u16 type;
5493d14abf15SRobert Mustacchi 
5494d14abf15SRobert Mustacchi 	/* Clear the ramrod data */
5495d14abf15SRobert Mustacchi 	mm_memset(rdata, 0, sizeof(*rdata));
5496d14abf15SRobert Mustacchi 
5497d14abf15SRobert Mustacchi 	/* Fill the ramrod data */
5498d14abf15SRobert Mustacchi 	ecore_q_fill_update_tpa_data(pdev, o, update_tpa_params, rdata);
5499d14abf15SRobert Mustacchi 
5500d14abf15SRobert Mustacchi 	/* Add the function id inside the type, so that sp post function
5501d14abf15SRobert Mustacchi 	 * doesn't automatically add the PF func-id, this is required
5502d14abf15SRobert Mustacchi 	 * for operations done by PFs on behalf of their VFs
5503d14abf15SRobert Mustacchi 	 */
5504d14abf15SRobert Mustacchi 	type = ETH_CONNECTION_TYPE |
5505d14abf15SRobert Mustacchi 		((o->func_id) << SPE_HDR_FUNCTION_ID_SHIFT);
5506d14abf15SRobert Mustacchi 
5507d14abf15SRobert Mustacchi 	/* No need for an explicit memory barrier here as long as we
5508d14abf15SRobert Mustacchi 	 * ensure the ordering of writing to the SPQ element
5509d14abf15SRobert Mustacchi 	 * and updating of the SPQ producer which involves a memory
5510d14abf15SRobert Mustacchi 	 * read. If the memory read is removed we will have to put a
5511d14abf15SRobert Mustacchi 	 * full memory barrier there (inside ecore_sp_post()).
5512d14abf15SRobert Mustacchi 	 */
5513d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, RAMROD_CMD_ID_ETH_TPA_UPDATE,
5514d14abf15SRobert Mustacchi 			     o->cids[ECORE_PRIMARY_CID_INDEX],
5515d14abf15SRobert Mustacchi 			     data_mapping.as_u64, type);
5516d14abf15SRobert Mustacchi }
5517d14abf15SRobert Mustacchi 
ecore_q_send_halt(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5518d14abf15SRobert Mustacchi static INLINE int ecore_q_send_halt(struct _lm_device_t *pdev,
5519d14abf15SRobert Mustacchi 				    struct ecore_queue_state_params *params)
5520d14abf15SRobert Mustacchi {
5521d14abf15SRobert Mustacchi 	struct ecore_queue_sp_obj *o = params->q_obj;
5522d14abf15SRobert Mustacchi 
5523d14abf15SRobert Mustacchi #if !defined(ECORE_ERASE) || defined(__FreeBSD__)
5524d14abf15SRobert Mustacchi 	/* build eth_halt_ramrod_data.client_id in a big-endian friendly way */
5525d14abf15SRobert Mustacchi 	lm_address_t    data_mapping = { {0} };
5526d14abf15SRobert Mustacchi 	data_mapping.as_u32.low = o->cl_id;
5527d14abf15SRobert Mustacchi 
5528d14abf15SRobert Mustacchi 	/* No need for an explicit memory barrier here as long as we
5529d14abf15SRobert Mustacchi 	 * ensure the ordering of writing to the SPQ element
5530d14abf15SRobert Mustacchi 	 * and updating of the SPQ producer which involves a memory
5531d14abf15SRobert Mustacchi 	 * read. If the memory read is removed we will have to put a
5532d14abf15SRobert Mustacchi 	 * full memory barrier there (inside ecore_sp_post()).
5533d14abf15SRobert Mustacchi 	 */
5534d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev,
5535d14abf15SRobert Mustacchi 			     RAMROD_CMD_ID_ETH_HALT,
5536d14abf15SRobert Mustacchi 			     o->cids[ECORE_PRIMARY_CID_INDEX],
5537d14abf15SRobert Mustacchi 			     data_mapping.as_u64,
5538d14abf15SRobert Mustacchi 			     ETH_CONNECTION_TYPE);
5539d14abf15SRobert Mustacchi #else
5540d14abf15SRobert Mustacchi 	return bnx2x_sp_post(pdev, RAMROD_CMD_ID_ETH_HALT,
5541d14abf15SRobert Mustacchi 			     o->cids[ECORE_PRIMARY_CID_INDEX], 0, o->cl_id,
5542d14abf15SRobert Mustacchi 			     ETH_CONNECTION_TYPE);
5543d14abf15SRobert Mustacchi #endif
5544d14abf15SRobert Mustacchi }
5545d14abf15SRobert Mustacchi 
ecore_q_send_cfc_del(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5546d14abf15SRobert Mustacchi static INLINE int ecore_q_send_cfc_del(struct _lm_device_t *pdev,
5547d14abf15SRobert Mustacchi 				       struct ecore_queue_state_params *params)
5548d14abf15SRobert Mustacchi {
5549d14abf15SRobert Mustacchi 	struct ecore_queue_sp_obj *o = params->q_obj;
5550d14abf15SRobert Mustacchi 	u8 cid_idx = params->params.cfc_del.cid_index;
5551d14abf15SRobert Mustacchi 
5552d14abf15SRobert Mustacchi 	if (cid_idx >= o->max_cos) {
5553d14abf15SRobert Mustacchi 		ECORE_ERR("queue[%d]: cid_index (%d) is out of range\n",
5554d14abf15SRobert Mustacchi 			  o->cl_id, cid_idx);
5555d14abf15SRobert Mustacchi 		return ECORE_INVAL;
5556d14abf15SRobert Mustacchi 	}
5557d14abf15SRobert Mustacchi 
5558d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, RAMROD_CMD_ID_COMMON_CFC_DEL,
5559d14abf15SRobert Mustacchi 			     o->cids[cid_idx], 0,
5560d14abf15SRobert Mustacchi 			     NONE_CONNECTION_TYPE);
5561d14abf15SRobert Mustacchi }
5562d14abf15SRobert Mustacchi 
ecore_q_send_terminate(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5563d14abf15SRobert Mustacchi static INLINE int ecore_q_send_terminate(struct _lm_device_t *pdev,
5564d14abf15SRobert Mustacchi 					struct ecore_queue_state_params *params)
5565d14abf15SRobert Mustacchi {
5566d14abf15SRobert Mustacchi 	struct ecore_queue_sp_obj *o = params->q_obj;
5567d14abf15SRobert Mustacchi 	u8 cid_index = params->params.terminate.cid_index;
5568d14abf15SRobert Mustacchi 
5569d14abf15SRobert Mustacchi 	if (cid_index >= o->max_cos) {
5570d14abf15SRobert Mustacchi 		ECORE_ERR("queue[%d]: cid_index (%d) is out of range\n",
5571d14abf15SRobert Mustacchi 			  o->cl_id, cid_index);
5572d14abf15SRobert Mustacchi 		return ECORE_INVAL;
5573d14abf15SRobert Mustacchi 	}
5574d14abf15SRobert Mustacchi 
5575d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, RAMROD_CMD_ID_ETH_TERMINATE,
5576d14abf15SRobert Mustacchi 			     o->cids[cid_index], 0,
5577d14abf15SRobert Mustacchi 			     ETH_CONNECTION_TYPE);
5578d14abf15SRobert Mustacchi }
5579d14abf15SRobert Mustacchi 
ecore_q_send_empty(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5580d14abf15SRobert Mustacchi static INLINE int ecore_q_send_empty(struct _lm_device_t *pdev,
5581d14abf15SRobert Mustacchi 				     struct ecore_queue_state_params *params)
5582d14abf15SRobert Mustacchi {
5583d14abf15SRobert Mustacchi 	struct ecore_queue_sp_obj *o = params->q_obj;
5584d14abf15SRobert Mustacchi 
5585d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, RAMROD_CMD_ID_ETH_EMPTY,
5586d14abf15SRobert Mustacchi 			     o->cids[ECORE_PRIMARY_CID_INDEX], 0,
5587d14abf15SRobert Mustacchi 			     ETH_CONNECTION_TYPE);
5588d14abf15SRobert Mustacchi }
5589d14abf15SRobert Mustacchi 
ecore_queue_send_cmd_cmn(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5590d14abf15SRobert Mustacchi static INLINE int ecore_queue_send_cmd_cmn(struct _lm_device_t *pdev,
5591d14abf15SRobert Mustacchi 					struct ecore_queue_state_params *params)
5592d14abf15SRobert Mustacchi {
5593d14abf15SRobert Mustacchi 	switch (params->cmd) {
5594d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_INIT:
5595d14abf15SRobert Mustacchi 		return ecore_q_init(pdev, params);
5596d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_SETUP_TX_ONLY:
5597d14abf15SRobert Mustacchi 		return ecore_q_send_setup_tx_only(pdev, params);
5598d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_DEACTIVATE:
5599d14abf15SRobert Mustacchi 		return ecore_q_send_deactivate(pdev, params);
5600d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_ACTIVATE:
5601d14abf15SRobert Mustacchi 		return ecore_q_send_activate(pdev, params);
5602d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_UPDATE:
5603d14abf15SRobert Mustacchi 		return ecore_q_send_update(pdev, params);
5604d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_UPDATE_TPA:
5605d14abf15SRobert Mustacchi 		return ecore_q_send_update_tpa(pdev, params);
5606d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_HALT:
5607d14abf15SRobert Mustacchi 		return ecore_q_send_halt(pdev, params);
5608d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_CFC_DEL:
5609d14abf15SRobert Mustacchi 		return ecore_q_send_cfc_del(pdev, params);
5610d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_TERMINATE:
5611d14abf15SRobert Mustacchi 		return ecore_q_send_terminate(pdev, params);
5612d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_EMPTY:
5613d14abf15SRobert Mustacchi 		return ecore_q_send_empty(pdev, params);
5614d14abf15SRobert Mustacchi 	default:
5615d14abf15SRobert Mustacchi 		ECORE_ERR("Unknown command: %d\n", params->cmd);
5616d14abf15SRobert Mustacchi 		return ECORE_INVAL;
5617d14abf15SRobert Mustacchi 	}
5618d14abf15SRobert Mustacchi }
5619d14abf15SRobert Mustacchi 
ecore_queue_send_cmd_e1x(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5620d14abf15SRobert Mustacchi static int ecore_queue_send_cmd_e1x(struct _lm_device_t *pdev,
5621d14abf15SRobert Mustacchi 				    struct ecore_queue_state_params *params)
5622d14abf15SRobert Mustacchi {
5623d14abf15SRobert Mustacchi 	switch (params->cmd) {
5624d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_SETUP:
5625d14abf15SRobert Mustacchi 		return ecore_q_send_setup_e1x(pdev, params);
5626d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_INIT:
5627d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_SETUP_TX_ONLY:
5628d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_DEACTIVATE:
5629d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_ACTIVATE:
5630d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_UPDATE:
5631d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_UPDATE_TPA:
5632d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_HALT:
5633d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_CFC_DEL:
5634d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_TERMINATE:
5635d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_EMPTY:
5636d14abf15SRobert Mustacchi 		return ecore_queue_send_cmd_cmn(pdev, params);
5637d14abf15SRobert Mustacchi 	default:
5638d14abf15SRobert Mustacchi 		ECORE_ERR("Unknown command: %d\n", params->cmd);
5639d14abf15SRobert Mustacchi 		return ECORE_INVAL;
5640d14abf15SRobert Mustacchi 	}
5641d14abf15SRobert Mustacchi }
5642d14abf15SRobert Mustacchi 
ecore_queue_send_cmd_e2(struct _lm_device_t * pdev,struct ecore_queue_state_params * params)5643d14abf15SRobert Mustacchi static int ecore_queue_send_cmd_e2(struct _lm_device_t *pdev,
5644d14abf15SRobert Mustacchi 				   struct ecore_queue_state_params *params)
5645d14abf15SRobert Mustacchi {
5646d14abf15SRobert Mustacchi 	switch (params->cmd) {
5647d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_SETUP:
5648d14abf15SRobert Mustacchi 		return ecore_q_send_setup_e2(pdev, params);
5649d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_INIT:
5650d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_SETUP_TX_ONLY:
5651d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_DEACTIVATE:
5652d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_ACTIVATE:
5653d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_UPDATE:
5654d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_UPDATE_TPA:
5655d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_HALT:
5656d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_CFC_DEL:
5657d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_TERMINATE:
5658d14abf15SRobert Mustacchi 	case ECORE_Q_CMD_EMPTY:
5659d14abf15SRobert Mustacchi 		return ecore_queue_send_cmd_cmn(pdev, params);
5660d14abf15SRobert Mustacchi 	default:
5661d14abf15SRobert Mustacchi 		ECORE_ERR("Unknown command: %d\n", params->cmd);
5662d14abf15SRobert Mustacchi 		return ECORE_INVAL;
5663d14abf15SRobert Mustacchi 	}
5664d14abf15SRobert Mustacchi }
5665d14abf15SRobert Mustacchi 
5666d14abf15SRobert Mustacchi /**
5667d14abf15SRobert Mustacchi  * ecore_queue_chk_transition - check state machine of a regular Queue
5668d14abf15SRobert Mustacchi  *
5669d14abf15SRobert Mustacchi  * @pdev:	device handle
5670d14abf15SRobert Mustacchi  * @o:
5671d14abf15SRobert Mustacchi  * @params:
5672d14abf15SRobert Mustacchi  *
5673d14abf15SRobert Mustacchi  * (not Forwarding)
5674d14abf15SRobert Mustacchi  * It both checks if the requested command is legal in a current
5675d14abf15SRobert Mustacchi  * state and, if it's legal, sets a `next_state' in the object
5676d14abf15SRobert Mustacchi  * that will be used in the completion flow to set the `state'
5677d14abf15SRobert Mustacchi  * of the object.
5678d14abf15SRobert Mustacchi  *
5679d14abf15SRobert Mustacchi  * returns 0 if a requested command is a legal transition,
5680d14abf15SRobert Mustacchi  *         ECORE_INVAL otherwise.
5681d14abf15SRobert Mustacchi  */
ecore_queue_chk_transition(struct _lm_device_t * pdev,struct ecore_queue_sp_obj * o,struct ecore_queue_state_params * params)5682d14abf15SRobert Mustacchi static int ecore_queue_chk_transition(struct _lm_device_t *pdev,
5683d14abf15SRobert Mustacchi 				      struct ecore_queue_sp_obj *o,
5684d14abf15SRobert Mustacchi 				      struct ecore_queue_state_params *params)
5685d14abf15SRobert Mustacchi {
5686d14abf15SRobert Mustacchi 	enum ecore_q_state state = o->state, next_state = ECORE_Q_STATE_MAX;
5687d14abf15SRobert Mustacchi 	enum ecore_queue_cmd cmd = params->cmd;
5688d14abf15SRobert Mustacchi 	struct ecore_queue_update_params *update_params =
5689d14abf15SRobert Mustacchi 		 &params->params.update;
5690d14abf15SRobert Mustacchi 	u8 next_tx_only = o->num_tx_only;
5691d14abf15SRobert Mustacchi 
5692d14abf15SRobert Mustacchi 	/* Forget all pending for completion commands if a driver only state
5693d14abf15SRobert Mustacchi 	 * transition has been requested.
5694d14abf15SRobert Mustacchi 	 */
5695d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_DRV_CLR_ONLY, &params->ramrod_flags)) {
5696d14abf15SRobert Mustacchi 		o->pending = 0;
5697d14abf15SRobert Mustacchi 		o->next_state = ECORE_Q_STATE_MAX;
5698d14abf15SRobert Mustacchi 	}
5699d14abf15SRobert Mustacchi 
5700d14abf15SRobert Mustacchi 	/* Don't allow a next state transition if we are in the middle of
5701d14abf15SRobert Mustacchi 	 * the previous one.
5702d14abf15SRobert Mustacchi 	 */
5703d14abf15SRobert Mustacchi 	if (o->pending) {
5704d14abf15SRobert Mustacchi 		ECORE_ERR("Blocking transition since pending was %lx\n",
5705d14abf15SRobert Mustacchi 			  o->pending);
5706d14abf15SRobert Mustacchi 		return ECORE_BUSY;
5707d14abf15SRobert Mustacchi 	}
5708d14abf15SRobert Mustacchi 
5709d14abf15SRobert Mustacchi 	switch (state) {
5710d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_RESET:
5711d14abf15SRobert Mustacchi 		if (cmd == ECORE_Q_CMD_INIT)
5712d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_INITIALIZED;
5713d14abf15SRobert Mustacchi 
5714d14abf15SRobert Mustacchi 		break;
5715d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_INITIALIZED:
5716d14abf15SRobert Mustacchi 		if (cmd == ECORE_Q_CMD_SETUP) {
5717d14abf15SRobert Mustacchi 			if (ECORE_TEST_BIT(ECORE_Q_FLG_ACTIVE,
5718d14abf15SRobert Mustacchi 					   &params->params.setup.flags))
5719d14abf15SRobert Mustacchi 				next_state = ECORE_Q_STATE_ACTIVE;
5720d14abf15SRobert Mustacchi 			else
5721d14abf15SRobert Mustacchi 				next_state = ECORE_Q_STATE_INACTIVE;
5722d14abf15SRobert Mustacchi 		}
5723d14abf15SRobert Mustacchi 
5724d14abf15SRobert Mustacchi 		break;
5725d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_ACTIVE:
5726d14abf15SRobert Mustacchi 		if (cmd == ECORE_Q_CMD_DEACTIVATE)
5727d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_INACTIVE;
5728d14abf15SRobert Mustacchi 
5729d14abf15SRobert Mustacchi 		else if ((cmd == ECORE_Q_CMD_EMPTY) ||
5730d14abf15SRobert Mustacchi 			 (cmd == ECORE_Q_CMD_UPDATE_TPA))
5731d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_ACTIVE;
5732d14abf15SRobert Mustacchi 
5733d14abf15SRobert Mustacchi 		else if (cmd == ECORE_Q_CMD_SETUP_TX_ONLY) {
5734d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_MULTI_COS;
5735d14abf15SRobert Mustacchi 			next_tx_only = 1;
5736d14abf15SRobert Mustacchi 		}
5737d14abf15SRobert Mustacchi 
5738d14abf15SRobert Mustacchi 		else if (cmd == ECORE_Q_CMD_HALT)
5739d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_STOPPED;
5740d14abf15SRobert Mustacchi 
5741d14abf15SRobert Mustacchi 		else if (cmd == ECORE_Q_CMD_UPDATE) {
5742d14abf15SRobert Mustacchi 			/* If "active" state change is requested, update the
5743d14abf15SRobert Mustacchi 			 *  state accordingly.
5744d14abf15SRobert Mustacchi 			 */
5745d14abf15SRobert Mustacchi 			if (ECORE_TEST_BIT(ECORE_Q_UPDATE_ACTIVATE_CHNG,
5746d14abf15SRobert Mustacchi 					   &update_params->update_flags) &&
5747d14abf15SRobert Mustacchi 			    !ECORE_TEST_BIT(ECORE_Q_UPDATE_ACTIVATE,
5748d14abf15SRobert Mustacchi 					    &update_params->update_flags))
5749d14abf15SRobert Mustacchi 				next_state = ECORE_Q_STATE_INACTIVE;
5750d14abf15SRobert Mustacchi 			else
5751d14abf15SRobert Mustacchi 				next_state = ECORE_Q_STATE_ACTIVE;
5752d14abf15SRobert Mustacchi 		}
5753d14abf15SRobert Mustacchi 
5754d14abf15SRobert Mustacchi 		break;
5755d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_MULTI_COS:
5756d14abf15SRobert Mustacchi 		if (cmd == ECORE_Q_CMD_TERMINATE)
5757d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_MCOS_TERMINATED;
5758d14abf15SRobert Mustacchi 
5759d14abf15SRobert Mustacchi 		else if (cmd == ECORE_Q_CMD_SETUP_TX_ONLY) {
5760d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_MULTI_COS;
5761d14abf15SRobert Mustacchi 			next_tx_only = o->num_tx_only + 1;
5762d14abf15SRobert Mustacchi 		}
5763d14abf15SRobert Mustacchi 
5764d14abf15SRobert Mustacchi 		else if ((cmd == ECORE_Q_CMD_EMPTY) ||
5765d14abf15SRobert Mustacchi 			 (cmd == ECORE_Q_CMD_UPDATE_TPA))
5766d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_MULTI_COS;
5767d14abf15SRobert Mustacchi 
5768d14abf15SRobert Mustacchi 		else if (cmd == ECORE_Q_CMD_UPDATE) {
5769d14abf15SRobert Mustacchi 			/* If "active" state change is requested, update the
5770d14abf15SRobert Mustacchi 			 *  state accordingly.
5771d14abf15SRobert Mustacchi 			 */
5772d14abf15SRobert Mustacchi 			if (ECORE_TEST_BIT(ECORE_Q_UPDATE_ACTIVATE_CHNG,
5773d14abf15SRobert Mustacchi 					   &update_params->update_flags) &&
5774d14abf15SRobert Mustacchi 			    !ECORE_TEST_BIT(ECORE_Q_UPDATE_ACTIVATE,
5775d14abf15SRobert Mustacchi 					    &update_params->update_flags))
5776d14abf15SRobert Mustacchi 				next_state = ECORE_Q_STATE_INACTIVE;
5777d14abf15SRobert Mustacchi 			else
5778d14abf15SRobert Mustacchi 				next_state = ECORE_Q_STATE_MULTI_COS;
5779d14abf15SRobert Mustacchi 		}
5780d14abf15SRobert Mustacchi 
5781d14abf15SRobert Mustacchi 		break;
5782d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_MCOS_TERMINATED:
5783d14abf15SRobert Mustacchi 		if (cmd == ECORE_Q_CMD_CFC_DEL) {
5784d14abf15SRobert Mustacchi 			next_tx_only = o->num_tx_only - 1;
5785d14abf15SRobert Mustacchi 			if (next_tx_only == 0)
5786d14abf15SRobert Mustacchi 				next_state = ECORE_Q_STATE_ACTIVE;
5787d14abf15SRobert Mustacchi 			else
5788d14abf15SRobert Mustacchi 				next_state = ECORE_Q_STATE_MULTI_COS;
5789d14abf15SRobert Mustacchi 		}
5790d14abf15SRobert Mustacchi 
5791d14abf15SRobert Mustacchi 		break;
5792d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_INACTIVE:
5793d14abf15SRobert Mustacchi 		if (cmd == ECORE_Q_CMD_ACTIVATE)
5794d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_ACTIVE;
5795d14abf15SRobert Mustacchi 
5796d14abf15SRobert Mustacchi 		else if ((cmd == ECORE_Q_CMD_EMPTY) ||
5797d14abf15SRobert Mustacchi 			 (cmd == ECORE_Q_CMD_UPDATE_TPA))
5798d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_INACTIVE;
5799d14abf15SRobert Mustacchi 
5800d14abf15SRobert Mustacchi 		else if (cmd == ECORE_Q_CMD_HALT)
5801d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_STOPPED;
5802d14abf15SRobert Mustacchi 
5803d14abf15SRobert Mustacchi 		else if (cmd == ECORE_Q_CMD_UPDATE) {
5804d14abf15SRobert Mustacchi 			/* If "active" state change is requested, update the
5805d14abf15SRobert Mustacchi 			 * state accordingly.
5806d14abf15SRobert Mustacchi 			 */
5807d14abf15SRobert Mustacchi 			if (ECORE_TEST_BIT(ECORE_Q_UPDATE_ACTIVATE_CHNG,
5808d14abf15SRobert Mustacchi 					   &update_params->update_flags) &&
5809d14abf15SRobert Mustacchi 			    ECORE_TEST_BIT(ECORE_Q_UPDATE_ACTIVATE,
5810d14abf15SRobert Mustacchi 					   &update_params->update_flags)){
5811d14abf15SRobert Mustacchi 				if (o->num_tx_only == 0)
5812d14abf15SRobert Mustacchi 					next_state = ECORE_Q_STATE_ACTIVE;
5813d14abf15SRobert Mustacchi 				else /* tx only queues exist for this queue */
5814d14abf15SRobert Mustacchi 					next_state = ECORE_Q_STATE_MULTI_COS;
5815d14abf15SRobert Mustacchi 			} else
5816d14abf15SRobert Mustacchi 				next_state = ECORE_Q_STATE_INACTIVE;
5817d14abf15SRobert Mustacchi 		}
5818d14abf15SRobert Mustacchi 
5819d14abf15SRobert Mustacchi 		break;
5820d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_STOPPED:
5821d14abf15SRobert Mustacchi 		if (cmd == ECORE_Q_CMD_TERMINATE)
5822d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_TERMINATED;
5823d14abf15SRobert Mustacchi 
5824d14abf15SRobert Mustacchi 		break;
5825d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_TERMINATED:
5826d14abf15SRobert Mustacchi 		if (cmd == ECORE_Q_CMD_CFC_DEL)
5827d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_RESET;
5828d14abf15SRobert Mustacchi 
5829d14abf15SRobert Mustacchi 		break;
5830d14abf15SRobert Mustacchi 	default:
5831d14abf15SRobert Mustacchi 		ECORE_ERR("Illegal state: %d\n", state);
5832d14abf15SRobert Mustacchi 	}
5833d14abf15SRobert Mustacchi 
5834d14abf15SRobert Mustacchi 	/* Transition is assured */
5835d14abf15SRobert Mustacchi 	if (next_state != ECORE_Q_STATE_MAX) {
5836d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "Good state transition: %d(%d)->%d\n",
5837d14abf15SRobert Mustacchi 			  state, cmd, next_state);
5838d14abf15SRobert Mustacchi 		o->next_state = next_state;
5839d14abf15SRobert Mustacchi 		o->next_tx_only = next_tx_only;
5840d14abf15SRobert Mustacchi 		return ECORE_SUCCESS;
5841d14abf15SRobert Mustacchi 	}
5842d14abf15SRobert Mustacchi 
5843d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Bad state transition request: %d %d\n", state, cmd);
5844d14abf15SRobert Mustacchi 
5845d14abf15SRobert Mustacchi 	return ECORE_INVAL;
5846d14abf15SRobert Mustacchi }
5847d14abf15SRobert Mustacchi #ifdef ECORE_OOO /* ! ECORE_UPSTREAM */
5848d14abf15SRobert Mustacchi 
5849d14abf15SRobert Mustacchi /**
5850d14abf15SRobert Mustacchi  * ecore_queue_chk_fwd_transition - check state machine of a Forwarding Queue.
5851d14abf15SRobert Mustacchi  *
5852d14abf15SRobert Mustacchi  * @pdev:	device handle
5853d14abf15SRobert Mustacchi  * @o:
5854d14abf15SRobert Mustacchi  * @params:
5855d14abf15SRobert Mustacchi  *
5856d14abf15SRobert Mustacchi  * It both checks if the requested command is legal in a current
5857d14abf15SRobert Mustacchi  * state and, if it's legal, sets a `next_state' in the object
5858d14abf15SRobert Mustacchi  * that will be used in the completion flow to set the `state'
5859d14abf15SRobert Mustacchi  * of the object.
5860d14abf15SRobert Mustacchi  *
5861d14abf15SRobert Mustacchi  * returns 0 if a requested command is a legal transition,
5862d14abf15SRobert Mustacchi  *         ECORE_INVAL otherwise.
5863d14abf15SRobert Mustacchi  */
ecore_queue_chk_fwd_transition(struct _lm_device_t * pdev,struct ecore_queue_sp_obj * o,struct ecore_queue_state_params * params)5864d14abf15SRobert Mustacchi static int ecore_queue_chk_fwd_transition(struct _lm_device_t *pdev,
5865d14abf15SRobert Mustacchi 					  struct ecore_queue_sp_obj *o,
5866d14abf15SRobert Mustacchi 					struct ecore_queue_state_params *params)
5867d14abf15SRobert Mustacchi {
5868d14abf15SRobert Mustacchi 	enum ecore_q_state state = o->state, next_state = ECORE_Q_STATE_MAX;
5869d14abf15SRobert Mustacchi 	enum ecore_queue_cmd cmd = params->cmd;
5870d14abf15SRobert Mustacchi 
5871d14abf15SRobert Mustacchi 	switch (state) {
5872d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_RESET:
5873d14abf15SRobert Mustacchi 		if (cmd == ECORE_Q_CMD_INIT)
5874d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_INITIALIZED;
5875d14abf15SRobert Mustacchi 
5876d14abf15SRobert Mustacchi 		break;
5877d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_INITIALIZED:
5878d14abf15SRobert Mustacchi 		if (cmd == ECORE_Q_CMD_SETUP_TX_ONLY) {
5879d14abf15SRobert Mustacchi 			if (ECORE_TEST_BIT(ECORE_Q_FLG_ACTIVE,
5880d14abf15SRobert Mustacchi 					   &params->params.tx_only.flags))
5881d14abf15SRobert Mustacchi 				next_state = ECORE_Q_STATE_ACTIVE;
5882d14abf15SRobert Mustacchi 			else
5883d14abf15SRobert Mustacchi 				next_state = ECORE_Q_STATE_INACTIVE;
5884d14abf15SRobert Mustacchi 		}
5885d14abf15SRobert Mustacchi 
5886d14abf15SRobert Mustacchi 		break;
5887d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_ACTIVE:
5888d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_INACTIVE:
5889d14abf15SRobert Mustacchi 		if (cmd == ECORE_Q_CMD_CFC_DEL)
5890d14abf15SRobert Mustacchi 			next_state = ECORE_Q_STATE_RESET;
5891d14abf15SRobert Mustacchi 
5892d14abf15SRobert Mustacchi 		break;
5893d14abf15SRobert Mustacchi 	default:
5894d14abf15SRobert Mustacchi 		ECORE_ERR("Illegal state: %d\n", state);
5895d14abf15SRobert Mustacchi 	}
5896d14abf15SRobert Mustacchi 
5897d14abf15SRobert Mustacchi 	/* Transition is assured */
5898d14abf15SRobert Mustacchi 	if (next_state != ECORE_Q_STATE_MAX) {
5899d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "Good state transition: %d(%d)->%d\n",
5900d14abf15SRobert Mustacchi 			  state, cmd, next_state);
5901d14abf15SRobert Mustacchi 		o->next_state = next_state;
5902d14abf15SRobert Mustacchi 		return ECORE_SUCCESS;
5903d14abf15SRobert Mustacchi 	}
5904d14abf15SRobert Mustacchi 
5905d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Bad state transition request: %d %d\n", state, cmd);
5906d14abf15SRobert Mustacchi 	return ECORE_INVAL;
5907d14abf15SRobert Mustacchi }
5908d14abf15SRobert Mustacchi #endif
5909d14abf15SRobert Mustacchi 
ecore_init_queue_obj(struct _lm_device_t * pdev,struct ecore_queue_sp_obj * obj,u8 cl_id,u32 * cids,u8 cid_cnt,u8 func_id,void * rdata,lm_address_t rdata_mapping,unsigned long type)5910d14abf15SRobert Mustacchi void ecore_init_queue_obj(struct _lm_device_t *pdev,
5911d14abf15SRobert Mustacchi 			  struct ecore_queue_sp_obj *obj,
5912d14abf15SRobert Mustacchi 			  u8 cl_id, u32 *cids, u8 cid_cnt, u8 func_id,
5913d14abf15SRobert Mustacchi 			  void *rdata,
5914d14abf15SRobert Mustacchi 			  lm_address_t rdata_mapping, unsigned long type)
5915d14abf15SRobert Mustacchi {
5916d14abf15SRobert Mustacchi 	mm_memset(obj, 0, sizeof(*obj));
5917d14abf15SRobert Mustacchi 
5918d14abf15SRobert Mustacchi 	/* We support only ECORE_MULTI_TX_COS Tx CoS at the moment */
5919d14abf15SRobert Mustacchi 	BUG_ON(ECORE_MULTI_TX_COS < cid_cnt);
5920d14abf15SRobert Mustacchi 
5921d14abf15SRobert Mustacchi 	memcpy(obj->cids, cids, sizeof(obj->cids[0]) * cid_cnt);
5922d14abf15SRobert Mustacchi 	obj->max_cos = cid_cnt;
5923d14abf15SRobert Mustacchi 	obj->cl_id = cl_id;
5924d14abf15SRobert Mustacchi 	obj->func_id = func_id;
5925d14abf15SRobert Mustacchi 	obj->rdata = rdata;
5926d14abf15SRobert Mustacchi 	obj->rdata_mapping = rdata_mapping;
5927d14abf15SRobert Mustacchi 	obj->type = type;
5928d14abf15SRobert Mustacchi 	obj->next_state = ECORE_Q_STATE_MAX;
5929d14abf15SRobert Mustacchi 
5930d14abf15SRobert Mustacchi 	if (CHIP_IS_E1x(pdev))
5931d14abf15SRobert Mustacchi 		obj->send_cmd = ecore_queue_send_cmd_e1x;
5932d14abf15SRobert Mustacchi 	else
5933d14abf15SRobert Mustacchi 		obj->send_cmd = ecore_queue_send_cmd_e2;
5934d14abf15SRobert Mustacchi 
5935d14abf15SRobert Mustacchi #ifdef ECORE_OOO /* ! ECORE_UPSTREAM */
5936d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_Q_TYPE_FWD, &type))
5937d14abf15SRobert Mustacchi 		obj->check_transition = ecore_queue_chk_fwd_transition;
5938d14abf15SRobert Mustacchi 	else
5939d14abf15SRobert Mustacchi #endif
5940d14abf15SRobert Mustacchi 	obj->check_transition = ecore_queue_chk_transition;
5941d14abf15SRobert Mustacchi 
5942d14abf15SRobert Mustacchi 	obj->complete_cmd = ecore_queue_comp_cmd;
5943d14abf15SRobert Mustacchi 	obj->wait_comp = ecore_queue_wait_comp;
5944d14abf15SRobert Mustacchi 	obj->set_pending = ecore_queue_set_pending;
5945d14abf15SRobert Mustacchi }
5946d14abf15SRobert Mustacchi 
5947d14abf15SRobert Mustacchi /* return a queue object's logical state*/
ecore_get_q_logical_state(struct _lm_device_t * pdev,struct ecore_queue_sp_obj * obj)5948d14abf15SRobert Mustacchi int ecore_get_q_logical_state(struct _lm_device_t *pdev,
5949d14abf15SRobert Mustacchi 			       struct ecore_queue_sp_obj *obj)
5950d14abf15SRobert Mustacchi {
5951d14abf15SRobert Mustacchi 	switch (obj->state) {
5952d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_ACTIVE:
5953d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_MULTI_COS:
5954d14abf15SRobert Mustacchi 		return ECORE_Q_LOGICAL_STATE_ACTIVE;
5955d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_RESET:
5956d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_INITIALIZED:
5957d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_MCOS_TERMINATED:
5958d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_INACTIVE:
5959d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_STOPPED:
5960d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_TERMINATED:
5961d14abf15SRobert Mustacchi 	case ECORE_Q_STATE_FLRED:
5962d14abf15SRobert Mustacchi 		return ECORE_Q_LOGICAL_STATE_STOPPED;
5963d14abf15SRobert Mustacchi 	default:
5964d14abf15SRobert Mustacchi 		return ECORE_INVAL;
5965d14abf15SRobert Mustacchi 	}
5966d14abf15SRobert Mustacchi }
5967d14abf15SRobert Mustacchi 
5968d14abf15SRobert Mustacchi /********************** Function state object *********************************/
ecore_func_get_state(struct _lm_device_t * pdev,struct ecore_func_sp_obj * o)5969d14abf15SRobert Mustacchi enum ecore_func_state ecore_func_get_state(struct _lm_device_t *pdev,
5970d14abf15SRobert Mustacchi 					   struct ecore_func_sp_obj *o)
5971d14abf15SRobert Mustacchi {
5972d14abf15SRobert Mustacchi 	/* in the middle of transaction - return INVALID state */
5973d14abf15SRobert Mustacchi 	if (o->pending)
5974d14abf15SRobert Mustacchi 		return ECORE_F_STATE_MAX;
5975d14abf15SRobert Mustacchi 
5976d14abf15SRobert Mustacchi 	/* unsure the order of reading of o->pending and o->state
5977d14abf15SRobert Mustacchi 	 * o->pending should be read first
5978d14abf15SRobert Mustacchi 	 */
5979d14abf15SRobert Mustacchi 	rmb();
5980d14abf15SRobert Mustacchi 
5981d14abf15SRobert Mustacchi 	return o->state;
5982d14abf15SRobert Mustacchi }
5983d14abf15SRobert Mustacchi 
ecore_func_wait_comp(struct _lm_device_t * pdev,struct ecore_func_sp_obj * o,enum ecore_func_cmd cmd)5984d14abf15SRobert Mustacchi static int ecore_func_wait_comp(struct _lm_device_t *pdev,
5985d14abf15SRobert Mustacchi 				struct ecore_func_sp_obj *o,
5986d14abf15SRobert Mustacchi 				enum ecore_func_cmd cmd)
5987d14abf15SRobert Mustacchi {
5988d14abf15SRobert Mustacchi 	return ecore_state_wait(pdev, cmd, &o->pending);
5989d14abf15SRobert Mustacchi }
5990d14abf15SRobert Mustacchi 
5991d14abf15SRobert Mustacchi /**
5992d14abf15SRobert Mustacchi  * ecore_func_state_change_comp - complete the state machine transition
5993d14abf15SRobert Mustacchi  *
5994d14abf15SRobert Mustacchi  * @pdev:	device handle
5995d14abf15SRobert Mustacchi  * @o:
5996d14abf15SRobert Mustacchi  * @cmd:
5997d14abf15SRobert Mustacchi  *
5998d14abf15SRobert Mustacchi  * Called on state change transition. Completes the state
5999d14abf15SRobert Mustacchi  * machine transition only - no HW interaction.
6000d14abf15SRobert Mustacchi  */
ecore_func_state_change_comp(struct _lm_device_t * pdev,struct ecore_func_sp_obj * o,enum ecore_func_cmd cmd)6001d14abf15SRobert Mustacchi static INLINE int ecore_func_state_change_comp(struct _lm_device_t *pdev,
6002d14abf15SRobert Mustacchi 					       struct ecore_func_sp_obj *o,
6003d14abf15SRobert Mustacchi 					       enum ecore_func_cmd cmd)
6004d14abf15SRobert Mustacchi {
6005d14abf15SRobert Mustacchi 	unsigned long cur_pending = o->pending;
6006d14abf15SRobert Mustacchi 
6007d14abf15SRobert Mustacchi 	if (!ECORE_TEST_AND_CLEAR_BIT(cmd, &cur_pending)) {
6008d14abf15SRobert Mustacchi 		ECORE_ERR("Bad MC reply %d for func %d in state %d pending 0x%lx, next_state %d\n",
6009d14abf15SRobert Mustacchi 			  cmd, FUNC_ID(pdev), o->state,
6010d14abf15SRobert Mustacchi 			  cur_pending, o->next_state);
6011d14abf15SRobert Mustacchi 		return ECORE_INVAL;
6012d14abf15SRobert Mustacchi 	}
6013d14abf15SRobert Mustacchi 
6014d14abf15SRobert Mustacchi 	ECORE_MSG(pdev,
6015d14abf15SRobert Mustacchi 		  "Completing command %d for func %d, setting state to %d\n",
6016d14abf15SRobert Mustacchi 		  cmd, FUNC_ID(pdev), o->next_state);
6017d14abf15SRobert Mustacchi 
6018d14abf15SRobert Mustacchi 	o->state = o->next_state;
6019d14abf15SRobert Mustacchi 	o->next_state = ECORE_F_STATE_MAX;
6020d14abf15SRobert Mustacchi 
6021d14abf15SRobert Mustacchi 	/* It's important that o->state and o->next_state are
6022d14abf15SRobert Mustacchi 	 * updated before o->pending.
6023d14abf15SRobert Mustacchi 	 */
6024d14abf15SRobert Mustacchi 	wmb();
6025d14abf15SRobert Mustacchi 
6026d14abf15SRobert Mustacchi 	ECORE_CLEAR_BIT(cmd, &o->pending);
6027d14abf15SRobert Mustacchi 	smp_mb__after_atomic();
6028d14abf15SRobert Mustacchi 
6029d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
6030d14abf15SRobert Mustacchi }
6031d14abf15SRobert Mustacchi 
6032d14abf15SRobert Mustacchi /**
6033d14abf15SRobert Mustacchi  * ecore_func_comp_cmd - complete the state change command
6034d14abf15SRobert Mustacchi  *
6035d14abf15SRobert Mustacchi  * @pdev:	device handle
6036d14abf15SRobert Mustacchi  * @o:
6037d14abf15SRobert Mustacchi  * @cmd:
6038d14abf15SRobert Mustacchi  *
6039d14abf15SRobert Mustacchi  * Checks that the arrived completion is expected.
6040d14abf15SRobert Mustacchi  */
ecore_func_comp_cmd(struct _lm_device_t * pdev,struct ecore_func_sp_obj * o,enum ecore_func_cmd cmd)6041d14abf15SRobert Mustacchi static int ecore_func_comp_cmd(struct _lm_device_t *pdev,
6042d14abf15SRobert Mustacchi 			       struct ecore_func_sp_obj *o,
6043d14abf15SRobert Mustacchi 			       enum ecore_func_cmd cmd)
6044d14abf15SRobert Mustacchi {
6045d14abf15SRobert Mustacchi 	/* Complete the state machine part first, check if it's a
6046d14abf15SRobert Mustacchi 	 * legal completion.
6047d14abf15SRobert Mustacchi 	 */
6048d14abf15SRobert Mustacchi 	int rc = ecore_func_state_change_comp(pdev, o, cmd);
6049d14abf15SRobert Mustacchi 	return rc;
6050d14abf15SRobert Mustacchi }
6051d14abf15SRobert Mustacchi 
6052d14abf15SRobert Mustacchi /**
6053d14abf15SRobert Mustacchi  * ecore_func_chk_transition - perform function state machine transition
6054d14abf15SRobert Mustacchi  *
6055d14abf15SRobert Mustacchi  * @pdev:	device handle
6056d14abf15SRobert Mustacchi  * @o:
6057d14abf15SRobert Mustacchi  * @params:
6058d14abf15SRobert Mustacchi  *
6059d14abf15SRobert Mustacchi  * It both checks if the requested command is legal in a current
6060d14abf15SRobert Mustacchi  * state and, if it's legal, sets a `next_state' in the object
6061d14abf15SRobert Mustacchi  * that will be used in the completion flow to set the `state'
6062d14abf15SRobert Mustacchi  * of the object.
6063d14abf15SRobert Mustacchi  *
6064d14abf15SRobert Mustacchi  * returns 0 if a requested command is a legal transition,
6065d14abf15SRobert Mustacchi  *         ECORE_INVAL otherwise.
6066d14abf15SRobert Mustacchi  */
ecore_func_chk_transition(struct _lm_device_t * pdev,struct ecore_func_sp_obj * o,struct ecore_func_state_params * params)6067d14abf15SRobert Mustacchi static int ecore_func_chk_transition(struct _lm_device_t *pdev,
6068d14abf15SRobert Mustacchi 				     struct ecore_func_sp_obj *o,
6069d14abf15SRobert Mustacchi 				     struct ecore_func_state_params *params)
6070d14abf15SRobert Mustacchi {
6071d14abf15SRobert Mustacchi 	enum ecore_func_state state = o->state, next_state = ECORE_F_STATE_MAX;
6072d14abf15SRobert Mustacchi 	enum ecore_func_cmd cmd = params->cmd;
6073d14abf15SRobert Mustacchi 
6074d14abf15SRobert Mustacchi 	/* Forget all pending for completion commands if a driver only state
6075d14abf15SRobert Mustacchi 	 * transition has been requested.
6076d14abf15SRobert Mustacchi 	 */
6077d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_DRV_CLR_ONLY, &params->ramrod_flags)) {
6078d14abf15SRobert Mustacchi 		o->pending = 0;
6079d14abf15SRobert Mustacchi 		o->next_state = ECORE_F_STATE_MAX;
6080d14abf15SRobert Mustacchi 	}
6081d14abf15SRobert Mustacchi 
6082d14abf15SRobert Mustacchi 	/* Don't allow a next state transition if we are in the middle of
6083d14abf15SRobert Mustacchi 	 * the previous one.
6084d14abf15SRobert Mustacchi 	 */
6085d14abf15SRobert Mustacchi 	if (o->pending)
6086d14abf15SRobert Mustacchi 		return ECORE_BUSY;
6087d14abf15SRobert Mustacchi 
6088d14abf15SRobert Mustacchi 	switch (state) {
6089d14abf15SRobert Mustacchi 	case ECORE_F_STATE_RESET:
6090d14abf15SRobert Mustacchi 		if (cmd == ECORE_F_CMD_HW_INIT)
6091d14abf15SRobert Mustacchi 			next_state = ECORE_F_STATE_INITIALIZED;
6092d14abf15SRobert Mustacchi 
6093d14abf15SRobert Mustacchi 		break;
6094d14abf15SRobert Mustacchi 	case ECORE_F_STATE_INITIALIZED:
6095d14abf15SRobert Mustacchi 		if (cmd == ECORE_F_CMD_START)
6096d14abf15SRobert Mustacchi 			next_state = ECORE_F_STATE_STARTED;
6097d14abf15SRobert Mustacchi 
6098d14abf15SRobert Mustacchi 		else if (cmd == ECORE_F_CMD_HW_RESET)
6099d14abf15SRobert Mustacchi 			next_state = ECORE_F_STATE_RESET;
6100d14abf15SRobert Mustacchi 
6101d14abf15SRobert Mustacchi 		break;
6102d14abf15SRobert Mustacchi 	case ECORE_F_STATE_STARTED:
6103d14abf15SRobert Mustacchi 		if (cmd == ECORE_F_CMD_STOP)
6104d14abf15SRobert Mustacchi 			next_state = ECORE_F_STATE_INITIALIZED;
6105d14abf15SRobert Mustacchi 		/* afex ramrods can be sent only in started mode, and only
6106d14abf15SRobert Mustacchi 		 * if not pending for function_stop ramrod completion
6107d14abf15SRobert Mustacchi 		 * for these events - next state remained STARTED.
6108d14abf15SRobert Mustacchi 		 */
6109d14abf15SRobert Mustacchi 		else if ((cmd == ECORE_F_CMD_AFEX_UPDATE) &&
6110d14abf15SRobert Mustacchi 			 (!ECORE_TEST_BIT(ECORE_F_CMD_STOP, &o->pending)))
6111d14abf15SRobert Mustacchi 			next_state = ECORE_F_STATE_STARTED;
6112d14abf15SRobert Mustacchi 
6113d14abf15SRobert Mustacchi 		else if ((cmd == ECORE_F_CMD_AFEX_VIFLISTS) &&
6114d14abf15SRobert Mustacchi 			 (!ECORE_TEST_BIT(ECORE_F_CMD_STOP, &o->pending)))
6115d14abf15SRobert Mustacchi 			next_state = ECORE_F_STATE_STARTED;
6116d14abf15SRobert Mustacchi 
6117d14abf15SRobert Mustacchi 		/* Switch_update ramrod can be sent in either started or
6118d14abf15SRobert Mustacchi 		 * tx_stopped state, and it doesn't change the state.
6119d14abf15SRobert Mustacchi 		 */
6120d14abf15SRobert Mustacchi 		else if ((cmd == ECORE_F_CMD_SWITCH_UPDATE) &&
6121d14abf15SRobert Mustacchi 			 (!ECORE_TEST_BIT(ECORE_F_CMD_STOP, &o->pending)))
6122d14abf15SRobert Mustacchi 			next_state = ECORE_F_STATE_STARTED;
6123d14abf15SRobert Mustacchi 
6124d14abf15SRobert Mustacchi 		else if ((cmd == ECORE_F_CMD_SET_TIMESYNC) &&
6125d14abf15SRobert Mustacchi 			 (!ECORE_TEST_BIT(ECORE_F_CMD_STOP, &o->pending)))
6126d14abf15SRobert Mustacchi 			next_state = ECORE_F_STATE_STARTED;
6127d14abf15SRobert Mustacchi 
6128d14abf15SRobert Mustacchi 		else if (cmd == ECORE_F_CMD_TX_STOP)
6129d14abf15SRobert Mustacchi 			next_state = ECORE_F_STATE_TX_STOPPED;
6130d14abf15SRobert Mustacchi 
6131d14abf15SRobert Mustacchi 		break;
6132d14abf15SRobert Mustacchi 	case ECORE_F_STATE_TX_STOPPED:
6133d14abf15SRobert Mustacchi 		if ((cmd == ECORE_F_CMD_SWITCH_UPDATE) &&
6134d14abf15SRobert Mustacchi 		    (!ECORE_TEST_BIT(ECORE_F_CMD_STOP, &o->pending)))
6135d14abf15SRobert Mustacchi 			next_state = ECORE_F_STATE_TX_STOPPED;
6136d14abf15SRobert Mustacchi 
6137d14abf15SRobert Mustacchi 		else if ((cmd == ECORE_F_CMD_SET_TIMESYNC) &&
6138d14abf15SRobert Mustacchi 		    (!ECORE_TEST_BIT(ECORE_F_CMD_STOP, &o->pending)))
6139d14abf15SRobert Mustacchi 			next_state = ECORE_F_STATE_TX_STOPPED;
6140d14abf15SRobert Mustacchi 
6141d14abf15SRobert Mustacchi 		else if (cmd == ECORE_F_CMD_TX_START)
6142d14abf15SRobert Mustacchi 			next_state = ECORE_F_STATE_STARTED;
6143d14abf15SRobert Mustacchi 
6144d14abf15SRobert Mustacchi 		break;
6145d14abf15SRobert Mustacchi 	default:
6146d14abf15SRobert Mustacchi 		ECORE_ERR("Unknown state: %d\n", state);
6147d14abf15SRobert Mustacchi 	}
6148d14abf15SRobert Mustacchi 
6149d14abf15SRobert Mustacchi 	/* Transition is assured */
6150d14abf15SRobert Mustacchi 	if (next_state != ECORE_F_STATE_MAX) {
6151d14abf15SRobert Mustacchi 		ECORE_MSG(pdev, "Good function state transition: %d(%d)->%d\n",
6152d14abf15SRobert Mustacchi 			  state, cmd, next_state);
6153d14abf15SRobert Mustacchi 		o->next_state = next_state;
6154d14abf15SRobert Mustacchi 		return ECORE_SUCCESS;
6155d14abf15SRobert Mustacchi 	}
6156d14abf15SRobert Mustacchi 
6157d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "Bad function state transition request: %d %d\n",
6158d14abf15SRobert Mustacchi 		  state, cmd);
6159d14abf15SRobert Mustacchi 
6160d14abf15SRobert Mustacchi 	return ECORE_INVAL;
6161d14abf15SRobert Mustacchi }
6162d14abf15SRobert Mustacchi 
6163d14abf15SRobert Mustacchi /**
6164d14abf15SRobert Mustacchi  * ecore_func_init_func - performs HW init at function stage
6165d14abf15SRobert Mustacchi  *
6166d14abf15SRobert Mustacchi  * @pdev:	device handle
6167d14abf15SRobert Mustacchi  * @drv:
6168d14abf15SRobert Mustacchi  *
6169d14abf15SRobert Mustacchi  * Init HW when the current phase is
6170d14abf15SRobert Mustacchi  * FW_MSG_CODE_DRV_LOAD_FUNCTION: initialize only FUNCTION-only
6171d14abf15SRobert Mustacchi  * HW blocks.
6172d14abf15SRobert Mustacchi  */
ecore_func_init_func(struct _lm_device_t * pdev,const struct ecore_func_sp_drv_ops * drv)6173d14abf15SRobert Mustacchi static INLINE int ecore_func_init_func(struct _lm_device_t *pdev,
6174d14abf15SRobert Mustacchi 				       const struct ecore_func_sp_drv_ops *drv)
6175d14abf15SRobert Mustacchi {
6176d14abf15SRobert Mustacchi 	return drv->init_hw_func(pdev);
6177d14abf15SRobert Mustacchi }
6178d14abf15SRobert Mustacchi 
6179d14abf15SRobert Mustacchi /**
6180d14abf15SRobert Mustacchi  * ecore_func_init_port - performs HW init at port stage
6181d14abf15SRobert Mustacchi  *
6182d14abf15SRobert Mustacchi  * @pdev:	device handle
6183d14abf15SRobert Mustacchi  * @drv:
6184d14abf15SRobert Mustacchi  *
6185d14abf15SRobert Mustacchi  * Init HW when the current phase is
6186d14abf15SRobert Mustacchi  * FW_MSG_CODE_DRV_LOAD_PORT: initialize PORT-only and
6187d14abf15SRobert Mustacchi  * FUNCTION-only HW blocks.
6188d14abf15SRobert Mustacchi  *
6189d14abf15SRobert Mustacchi  */
ecore_func_init_port(struct _lm_device_t * pdev,const struct ecore_func_sp_drv_ops * drv)6190d14abf15SRobert Mustacchi static INLINE int ecore_func_init_port(struct _lm_device_t *pdev,
6191d14abf15SRobert Mustacchi 				       const struct ecore_func_sp_drv_ops *drv)
6192d14abf15SRobert Mustacchi {
6193d14abf15SRobert Mustacchi 	int rc = drv->init_hw_port(pdev);
6194d14abf15SRobert Mustacchi 	if (rc)
6195d14abf15SRobert Mustacchi 		return rc;
6196d14abf15SRobert Mustacchi 
6197d14abf15SRobert Mustacchi 	return ecore_func_init_func(pdev, drv);
6198d14abf15SRobert Mustacchi }
6199d14abf15SRobert Mustacchi 
6200d14abf15SRobert Mustacchi /**
6201d14abf15SRobert Mustacchi  * ecore_func_init_cmn_chip - performs HW init at chip-common stage
6202d14abf15SRobert Mustacchi  *
6203d14abf15SRobert Mustacchi  * @pdev:	device handle
6204d14abf15SRobert Mustacchi  * @drv:
6205d14abf15SRobert Mustacchi  *
6206d14abf15SRobert Mustacchi  * Init HW when the current phase is
6207d14abf15SRobert Mustacchi  * FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: initialize COMMON_CHIP,
6208d14abf15SRobert Mustacchi  * PORT-only and FUNCTION-only HW blocks.
6209d14abf15SRobert Mustacchi  */
ecore_func_init_cmn_chip(struct _lm_device_t * pdev,const struct ecore_func_sp_drv_ops * drv)6210d14abf15SRobert Mustacchi static INLINE int ecore_func_init_cmn_chip(struct _lm_device_t *pdev,
6211d14abf15SRobert Mustacchi 					const struct ecore_func_sp_drv_ops *drv)
6212d14abf15SRobert Mustacchi {
6213d14abf15SRobert Mustacchi 	int rc = drv->init_hw_cmn_chip(pdev);
6214d14abf15SRobert Mustacchi 	if (rc)
6215d14abf15SRobert Mustacchi 		return rc;
6216d14abf15SRobert Mustacchi 
6217d14abf15SRobert Mustacchi 	return ecore_func_init_port(pdev, drv);
6218d14abf15SRobert Mustacchi }
6219d14abf15SRobert Mustacchi 
6220d14abf15SRobert Mustacchi /**
6221d14abf15SRobert Mustacchi  * ecore_func_init_cmn - performs HW init at common stage
6222d14abf15SRobert Mustacchi  *
6223d14abf15SRobert Mustacchi  * @pdev:	device handle
6224d14abf15SRobert Mustacchi  * @drv:
6225d14abf15SRobert Mustacchi  *
6226d14abf15SRobert Mustacchi  * Init HW when the current phase is
6227d14abf15SRobert Mustacchi  * FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: initialize COMMON,
6228d14abf15SRobert Mustacchi  * PORT-only and FUNCTION-only HW blocks.
6229d14abf15SRobert Mustacchi  */
ecore_func_init_cmn(struct _lm_device_t * pdev,const struct ecore_func_sp_drv_ops * drv)6230d14abf15SRobert Mustacchi static INLINE int ecore_func_init_cmn(struct _lm_device_t *pdev,
6231d14abf15SRobert Mustacchi 				      const struct ecore_func_sp_drv_ops *drv)
6232d14abf15SRobert Mustacchi {
6233d14abf15SRobert Mustacchi 	int rc = drv->init_hw_cmn(pdev);
6234d14abf15SRobert Mustacchi 	if (rc)
6235d14abf15SRobert Mustacchi 		return rc;
6236d14abf15SRobert Mustacchi 
6237d14abf15SRobert Mustacchi 	return ecore_func_init_port(pdev, drv);
6238d14abf15SRobert Mustacchi }
6239d14abf15SRobert Mustacchi 
ecore_func_hw_init(struct _lm_device_t * pdev,struct ecore_func_state_params * params)6240d14abf15SRobert Mustacchi static int ecore_func_hw_init(struct _lm_device_t *pdev,
6241d14abf15SRobert Mustacchi 			      struct ecore_func_state_params *params)
6242d14abf15SRobert Mustacchi {
6243d14abf15SRobert Mustacchi 	u32 load_code = params->params.hw_init.load_phase;
6244d14abf15SRobert Mustacchi 	struct ecore_func_sp_obj *o = params->f_obj;
6245d14abf15SRobert Mustacchi 	const struct ecore_func_sp_drv_ops *drv = o->drv;
6246d14abf15SRobert Mustacchi 	int rc = 0;
6247d14abf15SRobert Mustacchi 
6248d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "function %d  load_code %x\n",
6249d14abf15SRobert Mustacchi 		  ABS_FUNC_ID(pdev), load_code);
6250d14abf15SRobert Mustacchi 
6251d14abf15SRobert Mustacchi 	/* Prepare buffers for unzipping the FW */
6252d14abf15SRobert Mustacchi 	rc = drv->gunzip_init(pdev);
6253d14abf15SRobert Mustacchi 	if (rc)
6254d14abf15SRobert Mustacchi 		return rc;
6255d14abf15SRobert Mustacchi 
6256d14abf15SRobert Mustacchi 	/* Prepare FW */
6257d14abf15SRobert Mustacchi 	rc = drv->init_fw(pdev);
6258d14abf15SRobert Mustacchi 	if (rc) {
6259d14abf15SRobert Mustacchi 		ECORE_ERR("Error loading firmware\n");
6260d14abf15SRobert Mustacchi 		goto init_err;
6261d14abf15SRobert Mustacchi 	}
6262d14abf15SRobert Mustacchi 
6263d14abf15SRobert Mustacchi 	/* Handle the beginning of COMMON_XXX pases separately... */
6264d14abf15SRobert Mustacchi 	switch (load_code) {
6265d14abf15SRobert Mustacchi 	case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP:
6266d14abf15SRobert Mustacchi 		rc = ecore_func_init_cmn_chip(pdev, drv);
6267d14abf15SRobert Mustacchi 		if (rc)
6268d14abf15SRobert Mustacchi 			goto init_err;
6269d14abf15SRobert Mustacchi 
6270d14abf15SRobert Mustacchi 		break;
6271d14abf15SRobert Mustacchi 	case FW_MSG_CODE_DRV_LOAD_COMMON:
6272d14abf15SRobert Mustacchi 		rc = ecore_func_init_cmn(pdev, drv);
6273d14abf15SRobert Mustacchi 		if (rc)
6274d14abf15SRobert Mustacchi 			goto init_err;
6275d14abf15SRobert Mustacchi 
6276d14abf15SRobert Mustacchi 		break;
6277d14abf15SRobert Mustacchi 	case FW_MSG_CODE_DRV_LOAD_PORT:
6278d14abf15SRobert Mustacchi 		rc = ecore_func_init_port(pdev, drv);
6279d14abf15SRobert Mustacchi 		if (rc)
6280d14abf15SRobert Mustacchi 			goto init_err;
6281d14abf15SRobert Mustacchi 
6282d14abf15SRobert Mustacchi 		break;
6283d14abf15SRobert Mustacchi 	case FW_MSG_CODE_DRV_LOAD_FUNCTION:
6284d14abf15SRobert Mustacchi 		rc = ecore_func_init_func(pdev, drv);
6285d14abf15SRobert Mustacchi 		if (rc)
6286d14abf15SRobert Mustacchi 			goto init_err;
6287d14abf15SRobert Mustacchi 
6288d14abf15SRobert Mustacchi 		break;
6289d14abf15SRobert Mustacchi 	default:
6290d14abf15SRobert Mustacchi 		ECORE_ERR("Unknown load_code (0x%x) from MCP\n", load_code);
6291d14abf15SRobert Mustacchi 		rc = ECORE_INVAL;
6292d14abf15SRobert Mustacchi 	}
6293d14abf15SRobert Mustacchi 
6294d14abf15SRobert Mustacchi init_err:
6295d14abf15SRobert Mustacchi 	drv->gunzip_end(pdev);
6296d14abf15SRobert Mustacchi 
6297d14abf15SRobert Mustacchi 	/* In case of success, complete the command immediately: no ramrods
6298d14abf15SRobert Mustacchi 	 * have been sent.
6299d14abf15SRobert Mustacchi 	 */
6300d14abf15SRobert Mustacchi 	if (!rc)
6301d14abf15SRobert Mustacchi 		o->complete_cmd(pdev, o, ECORE_F_CMD_HW_INIT);
6302d14abf15SRobert Mustacchi 
6303d14abf15SRobert Mustacchi 	return rc;
6304d14abf15SRobert Mustacchi }
6305d14abf15SRobert Mustacchi 
6306d14abf15SRobert Mustacchi /**
6307d14abf15SRobert Mustacchi  * ecore_func_reset_func - reset HW at function stage
6308d14abf15SRobert Mustacchi  *
6309d14abf15SRobert Mustacchi  * @pdev:	device handle
6310d14abf15SRobert Mustacchi  * @drv:
6311d14abf15SRobert Mustacchi  *
6312d14abf15SRobert Mustacchi  * Reset HW at FW_MSG_CODE_DRV_UNLOAD_FUNCTION stage: reset only
6313d14abf15SRobert Mustacchi  * FUNCTION-only HW blocks.
6314d14abf15SRobert Mustacchi  */
ecore_func_reset_func(struct _lm_device_t * pdev,const struct ecore_func_sp_drv_ops * drv)6315d14abf15SRobert Mustacchi static INLINE void ecore_func_reset_func(struct _lm_device_t *pdev,
6316d14abf15SRobert Mustacchi 					const struct ecore_func_sp_drv_ops *drv)
6317d14abf15SRobert Mustacchi {
6318d14abf15SRobert Mustacchi 	drv->reset_hw_func(pdev);
6319d14abf15SRobert Mustacchi }
6320d14abf15SRobert Mustacchi 
6321d14abf15SRobert Mustacchi /**
6322d14abf15SRobert Mustacchi  * ecore_func_reset_port - reser HW at port stage
6323d14abf15SRobert Mustacchi  *
6324d14abf15SRobert Mustacchi  * @pdev:	device handle
6325d14abf15SRobert Mustacchi  * @drv:
6326d14abf15SRobert Mustacchi  *
6327d14abf15SRobert Mustacchi  * Reset HW at FW_MSG_CODE_DRV_UNLOAD_PORT stage: reset
6328d14abf15SRobert Mustacchi  * FUNCTION-only and PORT-only HW blocks.
6329d14abf15SRobert Mustacchi  *
6330d14abf15SRobert Mustacchi  *                 !!!IMPORTANT!!!
6331d14abf15SRobert Mustacchi  *
6332d14abf15SRobert Mustacchi  * It's important to call reset_port before reset_func() as the last thing
6333d14abf15SRobert Mustacchi  * reset_func does is pf_disable() thus disabling PGLUE_B, which
6334d14abf15SRobert Mustacchi  * makes impossible any DMAE transactions.
6335d14abf15SRobert Mustacchi  */
ecore_func_reset_port(struct _lm_device_t * pdev,const struct ecore_func_sp_drv_ops * drv)6336d14abf15SRobert Mustacchi static INLINE void ecore_func_reset_port(struct _lm_device_t *pdev,
6337d14abf15SRobert Mustacchi 					const struct ecore_func_sp_drv_ops *drv)
6338d14abf15SRobert Mustacchi {
6339d14abf15SRobert Mustacchi 	drv->reset_hw_port(pdev);
6340d14abf15SRobert Mustacchi 	ecore_func_reset_func(pdev, drv);
6341d14abf15SRobert Mustacchi }
6342d14abf15SRobert Mustacchi 
6343d14abf15SRobert Mustacchi /**
6344d14abf15SRobert Mustacchi  * ecore_func_reset_cmn - reser HW at common stage
6345d14abf15SRobert Mustacchi  *
6346d14abf15SRobert Mustacchi  * @pdev:	device handle
6347d14abf15SRobert Mustacchi  * @drv:
6348d14abf15SRobert Mustacchi  *
6349d14abf15SRobert Mustacchi  * Reset HW at FW_MSG_CODE_DRV_UNLOAD_COMMON and
6350d14abf15SRobert Mustacchi  * FW_MSG_CODE_DRV_UNLOAD_COMMON_CHIP stages: reset COMMON,
6351d14abf15SRobert Mustacchi  * COMMON_CHIP, FUNCTION-only and PORT-only HW blocks.
6352d14abf15SRobert Mustacchi  */
ecore_func_reset_cmn(struct _lm_device_t * pdev,const struct ecore_func_sp_drv_ops * drv)6353d14abf15SRobert Mustacchi static INLINE void ecore_func_reset_cmn(struct _lm_device_t *pdev,
6354d14abf15SRobert Mustacchi 					const struct ecore_func_sp_drv_ops *drv)
6355d14abf15SRobert Mustacchi {
6356d14abf15SRobert Mustacchi 	ecore_func_reset_port(pdev, drv);
6357d14abf15SRobert Mustacchi 	drv->reset_hw_cmn(pdev);
6358d14abf15SRobert Mustacchi }
6359d14abf15SRobert Mustacchi 
ecore_func_hw_reset(struct _lm_device_t * pdev,struct ecore_func_state_params * params)6360d14abf15SRobert Mustacchi static INLINE int ecore_func_hw_reset(struct _lm_device_t *pdev,
6361d14abf15SRobert Mustacchi 				      struct ecore_func_state_params *params)
6362d14abf15SRobert Mustacchi {
6363d14abf15SRobert Mustacchi 	u32 reset_phase = params->params.hw_reset.reset_phase;
6364d14abf15SRobert Mustacchi 	struct ecore_func_sp_obj *o = params->f_obj;
6365d14abf15SRobert Mustacchi 	const struct ecore_func_sp_drv_ops *drv = o->drv;
6366d14abf15SRobert Mustacchi 
6367d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "function %d  reset_phase %x\n", ABS_FUNC_ID(pdev),
6368d14abf15SRobert Mustacchi 		  reset_phase);
6369d14abf15SRobert Mustacchi 
6370d14abf15SRobert Mustacchi 	switch (reset_phase) {
6371d14abf15SRobert Mustacchi 	case FW_MSG_CODE_DRV_UNLOAD_COMMON:
6372d14abf15SRobert Mustacchi 		ecore_func_reset_cmn(pdev, drv);
6373d14abf15SRobert Mustacchi 		break;
6374d14abf15SRobert Mustacchi 	case FW_MSG_CODE_DRV_UNLOAD_PORT:
6375d14abf15SRobert Mustacchi 		ecore_func_reset_port(pdev, drv);
6376d14abf15SRobert Mustacchi 		break;
6377d14abf15SRobert Mustacchi 	case FW_MSG_CODE_DRV_UNLOAD_FUNCTION:
6378d14abf15SRobert Mustacchi 		ecore_func_reset_func(pdev, drv);
6379d14abf15SRobert Mustacchi 		break;
6380d14abf15SRobert Mustacchi 	default:
6381d14abf15SRobert Mustacchi 		ECORE_ERR("Unknown reset_phase (0x%x) from MCP\n",
6382d14abf15SRobert Mustacchi 			  reset_phase);
6383d14abf15SRobert Mustacchi 		break;
6384d14abf15SRobert Mustacchi 	}
6385d14abf15SRobert Mustacchi 
6386d14abf15SRobert Mustacchi 	/* Complete the command immediately: no ramrods have been sent. */
6387d14abf15SRobert Mustacchi 	o->complete_cmd(pdev, o, ECORE_F_CMD_HW_RESET);
6388d14abf15SRobert Mustacchi 
6389d14abf15SRobert Mustacchi 	return ECORE_SUCCESS;
6390d14abf15SRobert Mustacchi }
6391d14abf15SRobert Mustacchi 
ecore_func_send_start(struct _lm_device_t * pdev,struct ecore_func_state_params * params)6392d14abf15SRobert Mustacchi static INLINE int ecore_func_send_start(struct _lm_device_t *pdev,
6393d14abf15SRobert Mustacchi 					struct ecore_func_state_params *params)
6394d14abf15SRobert Mustacchi {
6395d14abf15SRobert Mustacchi 	struct ecore_func_sp_obj *o = params->f_obj;
6396d14abf15SRobert Mustacchi 	struct function_start_data *rdata =
6397d14abf15SRobert Mustacchi 		(struct function_start_data *)o->rdata;
6398d14abf15SRobert Mustacchi 	lm_address_t data_mapping = o->rdata_mapping;
6399d14abf15SRobert Mustacchi 	struct ecore_func_start_params *start_params = &params->params.start;
6400d14abf15SRobert Mustacchi 
6401d14abf15SRobert Mustacchi 	mm_memset(rdata, 0, sizeof(*rdata));
6402d14abf15SRobert Mustacchi 
6403d14abf15SRobert Mustacchi 	/* Fill the ramrod data with provided parameters */
6404d14abf15SRobert Mustacchi 	rdata->function_mode	= (u8)start_params->mf_mode;
6405d14abf15SRobert Mustacchi 	rdata->sd_vlan_tag	= mm_cpu_to_le16(start_params->sd_vlan_tag);
6406d14abf15SRobert Mustacchi 	rdata->path_id		= PATH_ID(pdev);
6407d14abf15SRobert Mustacchi 	rdata->network_cos_mode	= start_params->network_cos_mode;
6408d14abf15SRobert Mustacchi 	rdata->tunnel_mode	= start_params->tunnel_mode;
6409d14abf15SRobert Mustacchi 	rdata->gre_tunnel_type	= start_params->gre_tunnel_type;
6410d14abf15SRobert Mustacchi 	rdata->inner_gre_rss_en = start_params->inner_gre_rss_en;
6411d14abf15SRobert Mustacchi 	rdata->vxlan_dst_port	= start_params->vxlan_dst_port;
6412d14abf15SRobert Mustacchi 	rdata->sd_accept_mf_clss_fail = start_params->class_fail;
6413d14abf15SRobert Mustacchi 	if (start_params->class_fail_ethtype) {
6414d14abf15SRobert Mustacchi 		rdata->sd_accept_mf_clss_fail_match_ethtype = 1;
6415d14abf15SRobert Mustacchi 		rdata->sd_accept_mf_clss_fail_ethtype =
6416d14abf15SRobert Mustacchi 			mm_cpu_to_le16(start_params->class_fail_ethtype);
6417d14abf15SRobert Mustacchi 	}
6418d14abf15SRobert Mustacchi 	rdata->sd_vlan_force_pri_flg = start_params->sd_vlan_force_pri;
6419d14abf15SRobert Mustacchi 	rdata->sd_vlan_force_pri_val = start_params->sd_vlan_force_pri_val;
6420d14abf15SRobert Mustacchi 
6421d14abf15SRobert Mustacchi 	/** @@@TMP - until FW 7.10.7 (which will introduce an HSI change)
6422d14abf15SRobert Mustacchi 	 * `sd_vlan_eth_type' will replace ethertype in SD mode even if
6423d14abf15SRobert Mustacchi 	 * it's set to 0; This will probably break SD, so we're setting it
6424d14abf15SRobert Mustacchi 	 * to ethertype 0x8100 for now.
6425d14abf15SRobert Mustacchi 	 */
6426d14abf15SRobert Mustacchi 	if (start_params->sd_vlan_eth_type)
6427d14abf15SRobert Mustacchi 		rdata->sd_vlan_eth_type =
6428d14abf15SRobert Mustacchi 			mm_cpu_to_le16(start_params->sd_vlan_eth_type);
6429d14abf15SRobert Mustacchi 	else
6430d14abf15SRobert Mustacchi 		rdata->sd_vlan_eth_type =
6431d14abf15SRobert Mustacchi 			mm_cpu_to_le16((u16) 0x8100);
6432d14abf15SRobert Mustacchi 
6433d14abf15SRobert Mustacchi 	rdata->no_added_tags = start_params->no_added_tags;
6434d14abf15SRobert Mustacchi 
6435d14abf15SRobert Mustacchi 	/* No need for an explicit memory barrier here as long as we
6436d14abf15SRobert Mustacchi 	 * ensure the ordering of writing to the SPQ element
6437d14abf15SRobert Mustacchi 	 * and updating of the SPQ producer which involves a memory
6438d14abf15SRobert Mustacchi 	 * read. If the memory read is removed we will have to put a
6439d14abf15SRobert Mustacchi 	 * full memory barrier there (inside ecore_sp_post()).
6440d14abf15SRobert Mustacchi 	 */
6441d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, RAMROD_CMD_ID_COMMON_FUNCTION_START, 0,
6442d14abf15SRobert Mustacchi 			     data_mapping.as_u64, NONE_CONNECTION_TYPE);
6443d14abf15SRobert Mustacchi }
6444d14abf15SRobert Mustacchi 
ecore_func_send_switch_update(struct _lm_device_t * pdev,struct ecore_func_state_params * params)6445d14abf15SRobert Mustacchi static INLINE int ecore_func_send_switch_update(struct _lm_device_t *pdev,
6446d14abf15SRobert Mustacchi 					struct ecore_func_state_params *params)
6447d14abf15SRobert Mustacchi {
6448d14abf15SRobert Mustacchi 	struct ecore_func_sp_obj *o = params->f_obj;
6449d14abf15SRobert Mustacchi 	struct function_update_data *rdata =
6450d14abf15SRobert Mustacchi 		(struct function_update_data *)o->rdata;
6451d14abf15SRobert Mustacchi 	lm_address_t data_mapping = o->rdata_mapping;
6452d14abf15SRobert Mustacchi 	struct ecore_func_switch_update_params *switch_update_params =
6453d14abf15SRobert Mustacchi 		&params->params.switch_update;
6454d14abf15SRobert Mustacchi 
6455d14abf15SRobert Mustacchi 	mm_memset(rdata, 0, sizeof(*rdata));
6456d14abf15SRobert Mustacchi 
6457d14abf15SRobert Mustacchi 	/* Fill the ramrod data with provided parameters */
6458d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_F_UPDATE_TX_SWITCH_SUSPEND_CHNG,
6459d14abf15SRobert Mustacchi 			   &switch_update_params->changes)) {
6460d14abf15SRobert Mustacchi 		rdata->tx_switch_suspend_change_flg = 1;
6461d14abf15SRobert Mustacchi 		rdata->tx_switch_suspend =
6462d14abf15SRobert Mustacchi 			ECORE_TEST_BIT(ECORE_F_UPDATE_TX_SWITCH_SUSPEND,
6463d14abf15SRobert Mustacchi 				       &switch_update_params->changes);
6464d14abf15SRobert Mustacchi 	}
6465d14abf15SRobert Mustacchi 
6466d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_F_UPDATE_SD_VLAN_TAG_CHNG,
6467d14abf15SRobert Mustacchi 			   &switch_update_params->changes)) {
6468d14abf15SRobert Mustacchi 		rdata->sd_vlan_tag_change_flg = 1;
6469d14abf15SRobert Mustacchi 		rdata->sd_vlan_tag =
6470d14abf15SRobert Mustacchi 			mm_cpu_to_le16(switch_update_params->vlan);
6471d14abf15SRobert Mustacchi 	}
6472d14abf15SRobert Mustacchi 
6473d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_F_UPDATE_SD_VLAN_ETH_TYPE_CHNG,
6474d14abf15SRobert Mustacchi 			   &switch_update_params->changes)) {
6475d14abf15SRobert Mustacchi 		rdata->sd_vlan_eth_type_change_flg = 1;
6476d14abf15SRobert Mustacchi 		rdata->sd_vlan_eth_type =
6477d14abf15SRobert Mustacchi 			mm_cpu_to_le16(switch_update_params->vlan_eth_type);
6478d14abf15SRobert Mustacchi 	}
6479d14abf15SRobert Mustacchi 
6480d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_F_UPDATE_VLAN_FORCE_PRIO_CHNG,
6481d14abf15SRobert Mustacchi 			   &switch_update_params->changes)) {
6482d14abf15SRobert Mustacchi 		rdata->sd_vlan_force_pri_change_flg = 1;
6483d14abf15SRobert Mustacchi 		if (ECORE_TEST_BIT(ECORE_F_UPDATE_VLAN_FORCE_PRIO_FLAG,
6484d14abf15SRobert Mustacchi 				   &switch_update_params->changes))
6485d14abf15SRobert Mustacchi 			rdata->sd_vlan_force_pri_flg = 1;
6486d14abf15SRobert Mustacchi 		rdata->sd_vlan_force_pri_flg =
6487d14abf15SRobert Mustacchi 			switch_update_params->vlan_force_prio;
6488d14abf15SRobert Mustacchi 	}
6489d14abf15SRobert Mustacchi 
6490d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(ECORE_F_UPDATE_TUNNEL_CFG_CHNG,
6491d14abf15SRobert Mustacchi 			   &switch_update_params->changes)) {
6492d14abf15SRobert Mustacchi 		rdata->update_tunn_cfg_flg = 1;
6493d14abf15SRobert Mustacchi 		if (ECORE_TEST_BIT(ECORE_F_UPDATE_TUNNEL_CLSS_EN,
6494d14abf15SRobert Mustacchi 				   &switch_update_params->changes))
6495d14abf15SRobert Mustacchi 			rdata->tunn_clss_en = 1;
6496d14abf15SRobert Mustacchi 		if (ECORE_TEST_BIT(ECORE_F_UPDATE_TUNNEL_INNER_GRE_RSS_EN,
6497d14abf15SRobert Mustacchi 				   &switch_update_params->changes))
6498d14abf15SRobert Mustacchi 			rdata->inner_gre_rss_en = 1;
6499d14abf15SRobert Mustacchi 		rdata->tunnel_mode = switch_update_params->tunnel_mode;
6500d14abf15SRobert Mustacchi 		rdata->gre_tunnel_type = switch_update_params->gre_tunnel_type;
6501d14abf15SRobert Mustacchi 		rdata->vxlan_dst_port =
6502d14abf15SRobert Mustacchi 			mm_cpu_to_le16(switch_update_params->vxlan_dst_port);
6503d14abf15SRobert Mustacchi 	}
6504d14abf15SRobert Mustacchi 
6505d14abf15SRobert Mustacchi 	rdata->echo = SWITCH_UPDATE;
6506d14abf15SRobert Mustacchi 
6507d14abf15SRobert Mustacchi 	/* No need for an explicit memory barrier here as long as we
6508d14abf15SRobert Mustacchi 	 * ensure the ordering of writing to the SPQ element
6509d14abf15SRobert Mustacchi 	 * and updating of the SPQ producer which involves a memory
6510d14abf15SRobert Mustacchi 	 * read. If the memory read is removed we will have to put a
6511d14abf15SRobert Mustacchi 	 * full memory barrier there (inside ecore_sp_post()).
6512d14abf15SRobert Mustacchi 	 */
6513d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE, 0,
6514d14abf15SRobert Mustacchi 			     data_mapping.as_u64, NONE_CONNECTION_TYPE);
6515d14abf15SRobert Mustacchi }
6516d14abf15SRobert Mustacchi 
ecore_func_send_afex_update(struct _lm_device_t * pdev,struct ecore_func_state_params * params)6517d14abf15SRobert Mustacchi static INLINE int ecore_func_send_afex_update(struct _lm_device_t *pdev,
6518d14abf15SRobert Mustacchi 					 struct ecore_func_state_params *params)
6519d14abf15SRobert Mustacchi {
6520d14abf15SRobert Mustacchi 	struct ecore_func_sp_obj *o = params->f_obj;
6521d14abf15SRobert Mustacchi 	struct function_update_data *rdata =
6522d14abf15SRobert Mustacchi 		(struct function_update_data *)o->afex_rdata;
6523d14abf15SRobert Mustacchi 	lm_address_t data_mapping = o->afex_rdata_mapping;
6524d14abf15SRobert Mustacchi 	struct ecore_func_afex_update_params *afex_update_params =
6525d14abf15SRobert Mustacchi 		&params->params.afex_update;
6526d14abf15SRobert Mustacchi 
6527d14abf15SRobert Mustacchi 	mm_memset(rdata, 0, sizeof(*rdata));
6528d14abf15SRobert Mustacchi 
6529d14abf15SRobert Mustacchi 	/* Fill the ramrod data with provided parameters */
6530d14abf15SRobert Mustacchi 	rdata->vif_id_change_flg = 1;
6531d14abf15SRobert Mustacchi 	rdata->vif_id = mm_cpu_to_le16(afex_update_params->vif_id);
6532d14abf15SRobert Mustacchi 	rdata->afex_default_vlan_change_flg = 1;
6533d14abf15SRobert Mustacchi 	rdata->afex_default_vlan =
6534d14abf15SRobert Mustacchi 		mm_cpu_to_le16(afex_update_params->afex_default_vlan);
6535d14abf15SRobert Mustacchi 	rdata->allowed_priorities_change_flg = 1;
6536d14abf15SRobert Mustacchi 	rdata->allowed_priorities = afex_update_params->allowed_priorities;
6537d14abf15SRobert Mustacchi 	rdata->echo = AFEX_UPDATE;
6538d14abf15SRobert Mustacchi 
6539d14abf15SRobert Mustacchi 	/* No need for an explicit memory barrier here as long as we
6540d14abf15SRobert Mustacchi 	 * ensure the ordering of writing to the SPQ element
6541d14abf15SRobert Mustacchi 	 * and updating of the SPQ producer which involves a memory
6542d14abf15SRobert Mustacchi 	 * read. If the memory read is removed we will have to put a
6543d14abf15SRobert Mustacchi 	 * full memory barrier there (inside ecore_sp_post()).
6544d14abf15SRobert Mustacchi 	 */
6545d14abf15SRobert Mustacchi 	ECORE_MSG(pdev,
6546d14abf15SRobert Mustacchi 		  "afex: sending func_update vif_id 0x%x dvlan 0x%x prio 0x%x\n",
6547d14abf15SRobert Mustacchi 		  rdata->vif_id,
6548d14abf15SRobert Mustacchi 		  rdata->afex_default_vlan, rdata->allowed_priorities);
6549d14abf15SRobert Mustacchi 
6550d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE, 0,
6551d14abf15SRobert Mustacchi 			     data_mapping.as_u64, NONE_CONNECTION_TYPE);
6552d14abf15SRobert Mustacchi }
6553d14abf15SRobert Mustacchi 
6554d14abf15SRobert Mustacchi static
ecore_func_send_afex_viflists(struct _lm_device_t * pdev,struct ecore_func_state_params * params)6555d14abf15SRobert Mustacchi INLINE int ecore_func_send_afex_viflists(struct _lm_device_t *pdev,
6556d14abf15SRobert Mustacchi 					 struct ecore_func_state_params *params)
6557d14abf15SRobert Mustacchi {
6558d14abf15SRobert Mustacchi 	struct ecore_func_sp_obj *o = params->f_obj;
6559d14abf15SRobert Mustacchi 	struct afex_vif_list_ramrod_data *rdata =
6560d14abf15SRobert Mustacchi 		(struct afex_vif_list_ramrod_data *)o->afex_rdata;
6561d14abf15SRobert Mustacchi 	struct ecore_func_afex_viflists_params *afex_vif_params =
6562d14abf15SRobert Mustacchi 		&params->params.afex_viflists;
6563d14abf15SRobert Mustacchi 	u64 *p_rdata = (u64 *)rdata;
6564d14abf15SRobert Mustacchi 
6565d14abf15SRobert Mustacchi 	mm_memset(rdata, 0, sizeof(*rdata));
6566d14abf15SRobert Mustacchi 
6567d14abf15SRobert Mustacchi 	/* Fill the ramrod data with provided parameters */
6568d14abf15SRobert Mustacchi 	rdata->vif_list_index = mm_cpu_to_le16(afex_vif_params->vif_list_index);
6569d14abf15SRobert Mustacchi 	rdata->func_bit_map          = afex_vif_params->func_bit_map;
6570d14abf15SRobert Mustacchi 	rdata->afex_vif_list_command = afex_vif_params->afex_vif_list_command;
6571d14abf15SRobert Mustacchi 	rdata->func_to_clear         = afex_vif_params->func_to_clear;
6572d14abf15SRobert Mustacchi 
6573d14abf15SRobert Mustacchi 	/* send in echo type of sub command */
6574d14abf15SRobert Mustacchi 	rdata->echo = afex_vif_params->afex_vif_list_command;
6575d14abf15SRobert Mustacchi 
6576d14abf15SRobert Mustacchi 	ECORE_MSG(pdev, "afex: ramrod lists, cmd 0x%x index 0x%x func_bit_map 0x%x func_to_clr 0x%x\n",
6577d14abf15SRobert Mustacchi 		  rdata->afex_vif_list_command, rdata->vif_list_index,
6578d14abf15SRobert Mustacchi 		  rdata->func_bit_map, rdata->func_to_clear);
6579d14abf15SRobert Mustacchi 
6580d14abf15SRobert Mustacchi 	/* No need for an explicit memory barrier here as long as we
6581d14abf15SRobert Mustacchi 	 * ensure the ordering of writing to the SPQ element
6582d14abf15SRobert Mustacchi 	 * and updating of the SPQ producer which involves a memory
6583d14abf15SRobert Mustacchi 	 * read. If the memory read is removed we will have to put a
6584d14abf15SRobert Mustacchi 	 * full memory barrier there (inside ecore_sp_post()).
6585d14abf15SRobert Mustacchi 	 */
6586d14abf15SRobert Mustacchi 
6587d14abf15SRobert Mustacchi 	/* this ramrod sends data directly and not through DMA mapping */
6588d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, RAMROD_CMD_ID_COMMON_AFEX_VIF_LISTS, 0,
6589d14abf15SRobert Mustacchi 			     *p_rdata, NONE_CONNECTION_TYPE);
6590d14abf15SRobert Mustacchi }
6591d14abf15SRobert Mustacchi 
ecore_func_send_stop(struct _lm_device_t * pdev,struct ecore_func_state_params * params)6592d14abf15SRobert Mustacchi static INLINE int ecore_func_send_stop(struct _lm_device_t *pdev,
6593d14abf15SRobert Mustacchi 				       struct ecore_func_state_params *params)
6594d14abf15SRobert Mustacchi {
6595d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, RAMROD_CMD_ID_COMMON_FUNCTION_STOP, 0, 0,
6596d14abf15SRobert Mustacchi 			     NONE_CONNECTION_TYPE);
6597d14abf15SRobert Mustacchi }
6598d14abf15SRobert Mustacchi 
ecore_func_send_tx_stop(struct _lm_device_t * pdev,struct ecore_func_state_params * params)6599d14abf15SRobert Mustacchi static INLINE int ecore_func_send_tx_stop(struct _lm_device_t *pdev,
6600d14abf15SRobert Mustacchi 				       struct ecore_func_state_params *params)
6601d14abf15SRobert Mustacchi {
6602d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, 0, 0,
6603d14abf15SRobert Mustacchi 			     NONE_CONNECTION_TYPE);
6604d14abf15SRobert Mustacchi }
ecore_func_send_tx_start(struct _lm_device_t * pdev,struct ecore_func_state_params * params)6605d14abf15SRobert Mustacchi static INLINE int ecore_func_send_tx_start(struct _lm_device_t *pdev,
6606d14abf15SRobert Mustacchi 				       struct ecore_func_state_params *params)
6607d14abf15SRobert Mustacchi {
6608d14abf15SRobert Mustacchi 	struct ecore_func_sp_obj *o = params->f_obj;
6609d14abf15SRobert Mustacchi 	struct flow_control_configuration *rdata =
6610d14abf15SRobert Mustacchi 		(struct flow_control_configuration *)o->rdata;
6611d14abf15SRobert Mustacchi 	lm_address_t data_mapping = o->rdata_mapping;
6612d14abf15SRobert Mustacchi 	struct ecore_func_tx_start_params *tx_start_params =
6613d14abf15SRobert Mustacchi 		&params->params.tx_start;
6614d14abf15SRobert Mustacchi 	int i;
6615d14abf15SRobert Mustacchi 
6616d14abf15SRobert Mustacchi 	mm_memset(rdata, 0, sizeof(*rdata));
6617d14abf15SRobert Mustacchi 
6618d14abf15SRobert Mustacchi 	rdata->dcb_enabled = tx_start_params->dcb_enabled;
6619d14abf15SRobert Mustacchi 	rdata->dcb_version = tx_start_params->dcb_version;
6620d14abf15SRobert Mustacchi 	rdata->dont_add_pri_0_en = tx_start_params->dont_add_pri_0_en;
6621d14abf15SRobert Mustacchi 
6622d14abf15SRobert Mustacchi 	for (i = 0; i < ARRAY_SIZE(rdata->traffic_type_to_priority_cos); i++)
6623d14abf15SRobert Mustacchi 		rdata->traffic_type_to_priority_cos[i] =
6624d14abf15SRobert Mustacchi 			tx_start_params->traffic_type_to_priority_cos[i];
6625d14abf15SRobert Mustacchi 
6626d14abf15SRobert Mustacchi 	/* No need for an explicit memory barrier here as long as we
6627d14abf15SRobert Mustacchi 	 * ensure the ordering of writing to the SPQ element
6628d14abf15SRobert Mustacchi 	 * and updating of the SPQ producer which involves a memory
6629d14abf15SRobert Mustacchi 	 * read. If the memory read is removed we will have to put a
6630d14abf15SRobert Mustacchi 	 * full memory barrier there (inside ecore_sp_post()).
6631d14abf15SRobert Mustacchi 	 */
6632d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, RAMROD_CMD_ID_COMMON_START_TRAFFIC, 0,
6633d14abf15SRobert Mustacchi 			     data_mapping.as_u64, NONE_CONNECTION_TYPE);
6634d14abf15SRobert Mustacchi }
6635d14abf15SRobert Mustacchi 
ecore_func_send_set_timesync(struct _lm_device_t * pdev,struct ecore_func_state_params * params)6636d14abf15SRobert Mustacchi static INLINE int ecore_func_send_set_timesync(struct _lm_device_t *pdev,
6637d14abf15SRobert Mustacchi 					struct ecore_func_state_params *params)
6638d14abf15SRobert Mustacchi {
6639d14abf15SRobert Mustacchi 	struct ecore_func_sp_obj *o = params->f_obj;
6640d14abf15SRobert Mustacchi 	struct set_timesync_ramrod_data *rdata =
6641d14abf15SRobert Mustacchi 		(struct set_timesync_ramrod_data *)o->rdata;
6642d14abf15SRobert Mustacchi 	lm_address_t data_mapping = o->rdata_mapping;
6643d14abf15SRobert Mustacchi 	struct ecore_func_set_timesync_params *set_timesync_params =
6644d14abf15SRobert Mustacchi 		&params->params.set_timesync;
6645d14abf15SRobert Mustacchi 
6646d14abf15SRobert Mustacchi 	mm_memset(rdata, 0, sizeof(*rdata));
6647d14abf15SRobert Mustacchi 
6648d14abf15SRobert Mustacchi 	/* Fill the ramrod data with provided parameters */
6649d14abf15SRobert Mustacchi 	rdata->drift_adjust_cmd = set_timesync_params->drift_adjust_cmd;
6650d14abf15SRobert Mustacchi 	rdata->offset_cmd = set_timesync_params->offset_cmd;
6651d14abf15SRobert Mustacchi 	rdata->add_sub_drift_adjust_value =
6652d14abf15SRobert Mustacchi 		set_timesync_params->add_sub_drift_adjust_value;
6653d14abf15SRobert Mustacchi 	rdata->drift_adjust_value = set_timesync_params->drift_adjust_value;
6654d14abf15SRobert Mustacchi 	rdata->drift_adjust_period = set_timesync_params->drift_adjust_period;
6655d14abf15SRobert Mustacchi 	rdata->offset_delta.lo =
6656d14abf15SRobert Mustacchi 		mm_cpu_to_le32(U64_LO(set_timesync_params->offset_delta));
6657d14abf15SRobert Mustacchi 	rdata->offset_delta.hi =
6658d14abf15SRobert Mustacchi 		mm_cpu_to_le32(U64_HI(set_timesync_params->offset_delta));
6659d14abf15SRobert Mustacchi 
6660d14abf15SRobert Mustacchi 	DP(BNX2X_MSG_SP, "Set timesync command params: drift_cmd = %d, offset_cmd = %d, add_sub_drift = %d, drift_val = %d, drift_period = %d, offset_lo = %d, offset_hi = %d\n",
6661d14abf15SRobert Mustacchi 	   rdata->drift_adjust_cmd, rdata->offset_cmd,
6662d14abf15SRobert Mustacchi 	   rdata->add_sub_drift_adjust_value, rdata->drift_adjust_value,
6663d14abf15SRobert Mustacchi 	   rdata->drift_adjust_period, rdata->offset_delta.lo,
6664d14abf15SRobert Mustacchi 	   rdata->offset_delta.hi);
6665d14abf15SRobert Mustacchi 
6666d14abf15SRobert Mustacchi 	return ecore_sp_post(pdev, RAMROD_CMD_ID_COMMON_SET_TIMESYNC, 0,
6667d14abf15SRobert Mustacchi 			     data_mapping.as_u64, NONE_CONNECTION_TYPE);
6668d14abf15SRobert Mustacchi }
6669d14abf15SRobert Mustacchi 
ecore_func_send_cmd(struct _lm_device_t * pdev,struct ecore_func_state_params * params)6670d14abf15SRobert Mustacchi static int ecore_func_send_cmd(struct _lm_device_t *pdev,
6671d14abf15SRobert Mustacchi 			       struct ecore_func_state_params *params)
6672d14abf15SRobert Mustacchi {
6673d14abf15SRobert Mustacchi 	switch (params->cmd) {
6674d14abf15SRobert Mustacchi 	case ECORE_F_CMD_HW_INIT:
6675d14abf15SRobert Mustacchi 		return ecore_func_hw_init(pdev, params);
6676d14abf15SRobert Mustacchi 	case ECORE_F_CMD_START:
6677d14abf15SRobert Mustacchi 		return ecore_func_send_start(pdev, params);
6678d14abf15SRobert Mustacchi 	case ECORE_F_CMD_STOP:
6679d14abf15SRobert Mustacchi 		return ecore_func_send_stop(pdev, params);
6680d14abf15SRobert Mustacchi 	case ECORE_F_CMD_HW_RESET:
6681d14abf15SRobert Mustacchi 		return ecore_func_hw_reset(pdev, params);
6682d14abf15SRobert Mustacchi 	case ECORE_F_CMD_AFEX_UPDATE:
6683d14abf15SRobert Mustacchi 		return ecore_func_send_afex_update(pdev, params);
6684d14abf15SRobert Mustacchi 	case ECORE_F_CMD_AFEX_VIFLISTS:
6685d14abf15SRobert Mustacchi 		return ecore_func_send_afex_viflists(pdev, params);
6686d14abf15SRobert Mustacchi 	case ECORE_F_CMD_TX_STOP:
6687d14abf15SRobert Mustacchi 		return ecore_func_send_tx_stop(pdev, params);
6688d14abf15SRobert Mustacchi 	case ECORE_F_CMD_TX_START:
6689d14abf15SRobert Mustacchi 		return ecore_func_send_tx_start(pdev, params);
6690d14abf15SRobert Mustacchi 	case ECORE_F_CMD_SWITCH_UPDATE:
6691d14abf15SRobert Mustacchi 		return ecore_func_send_switch_update(pdev, params);
6692d14abf15SRobert Mustacchi 	case ECORE_F_CMD_SET_TIMESYNC:
6693d14abf15SRobert Mustacchi 		return ecore_func_send_set_timesync(pdev, params);
6694d14abf15SRobert Mustacchi 	default:
6695d14abf15SRobert Mustacchi 		ECORE_ERR("Unknown command: %d\n", params->cmd);
6696d14abf15SRobert Mustacchi 		return ECORE_INVAL;
6697d14abf15SRobert Mustacchi 	}
6698d14abf15SRobert Mustacchi }
6699d14abf15SRobert Mustacchi 
ecore_init_func_obj(struct _lm_device_t * pdev,struct ecore_func_sp_obj * obj,void * rdata,lm_address_t rdata_mapping,void * afex_rdata,lm_address_t afex_rdata_mapping,struct ecore_func_sp_drv_ops * drv_iface)6700d14abf15SRobert Mustacchi void ecore_init_func_obj(struct _lm_device_t *pdev,
6701d14abf15SRobert Mustacchi 			 struct ecore_func_sp_obj *obj,
6702d14abf15SRobert Mustacchi 			 void *rdata, lm_address_t rdata_mapping,
6703d14abf15SRobert Mustacchi 			 void *afex_rdata, lm_address_t afex_rdata_mapping,
6704d14abf15SRobert Mustacchi 			 struct ecore_func_sp_drv_ops *drv_iface)
6705d14abf15SRobert Mustacchi {
6706d14abf15SRobert Mustacchi 	mm_memset(obj, 0, sizeof(*obj));
6707d14abf15SRobert Mustacchi 
6708d14abf15SRobert Mustacchi 	ECORE_MUTEX_INIT(&obj->one_pending_mutex);
6709d14abf15SRobert Mustacchi 
6710d14abf15SRobert Mustacchi 	obj->rdata = rdata;
6711d14abf15SRobert Mustacchi 	obj->rdata_mapping = rdata_mapping;
6712d14abf15SRobert Mustacchi 	obj->afex_rdata = afex_rdata;
6713d14abf15SRobert Mustacchi 	obj->afex_rdata_mapping = afex_rdata_mapping;
6714d14abf15SRobert Mustacchi 	obj->send_cmd = ecore_func_send_cmd;
6715d14abf15SRobert Mustacchi 	obj->check_transition = ecore_func_chk_transition;
6716d14abf15SRobert Mustacchi 	obj->complete_cmd = ecore_func_comp_cmd;
6717d14abf15SRobert Mustacchi 	obj->wait_comp = ecore_func_wait_comp;
6718d14abf15SRobert Mustacchi 	obj->drv = drv_iface;
6719d14abf15SRobert Mustacchi }
6720d14abf15SRobert Mustacchi 
6721d14abf15SRobert Mustacchi /**
6722d14abf15SRobert Mustacchi  * ecore_func_state_change - perform Function state change transition
6723d14abf15SRobert Mustacchi  *
6724d14abf15SRobert Mustacchi  * @pdev:	device handle
6725d14abf15SRobert Mustacchi  * @params:	parameters to perform the transaction
6726d14abf15SRobert Mustacchi  *
6727d14abf15SRobert Mustacchi  * returns 0 in case of successfully completed transition,
6728d14abf15SRobert Mustacchi  *         negative error code in case of failure, positive
6729d14abf15SRobert Mustacchi  *         (EBUSY) value if there is a completion to that is
6730d14abf15SRobert Mustacchi  *         still pending (possible only if RAMROD_COMP_WAIT is
6731d14abf15SRobert Mustacchi  *         not set in params->ramrod_flags for asynchronous
6732d14abf15SRobert Mustacchi  *         commands).
6733d14abf15SRobert Mustacchi  */
ecore_func_state_change(struct _lm_device_t * pdev,struct ecore_func_state_params * params)6734d14abf15SRobert Mustacchi int ecore_func_state_change(struct _lm_device_t *pdev,
6735d14abf15SRobert Mustacchi 			    struct ecore_func_state_params *params)
6736d14abf15SRobert Mustacchi {
6737d14abf15SRobert Mustacchi 	struct ecore_func_sp_obj *o = params->f_obj;
6738d14abf15SRobert Mustacchi 	int rc, cnt = 300;
6739d14abf15SRobert Mustacchi 	enum ecore_func_cmd cmd = params->cmd;
6740d14abf15SRobert Mustacchi 	unsigned long *pending = &o->pending;
6741d14abf15SRobert Mustacchi 
6742d14abf15SRobert Mustacchi 	ECORE_MUTEX_LOCK(&o->one_pending_mutex);
6743d14abf15SRobert Mustacchi 
6744d14abf15SRobert Mustacchi 	/* Check that the requested transition is legal */
6745d14abf15SRobert Mustacchi 	rc = o->check_transition(pdev, o, params);
6746d14abf15SRobert Mustacchi 	if ((rc == ECORE_BUSY) &&
6747d14abf15SRobert Mustacchi 	    (ECORE_TEST_BIT(RAMROD_RETRY, &params->ramrod_flags))) {
6748d14abf15SRobert Mustacchi 		while ((rc == ECORE_BUSY) && (--cnt > 0)) {
6749d14abf15SRobert Mustacchi 			ECORE_MUTEX_UNLOCK(&o->one_pending_mutex);
6750d14abf15SRobert Mustacchi 			msleep(10);
6751d14abf15SRobert Mustacchi 			ECORE_MUTEX_LOCK(&o->one_pending_mutex);
6752d14abf15SRobert Mustacchi 			rc = o->check_transition(pdev, o, params);
6753d14abf15SRobert Mustacchi 		}
6754d14abf15SRobert Mustacchi 		if (rc == ECORE_BUSY) {
6755d14abf15SRobert Mustacchi 			ECORE_MUTEX_UNLOCK(&o->one_pending_mutex);
6756d14abf15SRobert Mustacchi 			ECORE_ERR("timeout waiting for previous ramrod completion\n");
6757d14abf15SRobert Mustacchi 			return rc;
6758d14abf15SRobert Mustacchi 		}
6759d14abf15SRobert Mustacchi 	} else if (rc) {
6760d14abf15SRobert Mustacchi 		ECORE_MUTEX_UNLOCK(&o->one_pending_mutex);
6761d14abf15SRobert Mustacchi 		return rc;
6762d14abf15SRobert Mustacchi 	}
6763d14abf15SRobert Mustacchi 
6764d14abf15SRobert Mustacchi 	/* Set "pending" bit */
6765d14abf15SRobert Mustacchi 	ECORE_SET_BIT(cmd, pending);
6766d14abf15SRobert Mustacchi 
6767d14abf15SRobert Mustacchi 	/* Don't send a command if only driver cleanup was requested */
6768d14abf15SRobert Mustacchi 	if (ECORE_TEST_BIT(RAMROD_DRV_CLR_ONLY, &params->ramrod_flags)) {
6769d14abf15SRobert Mustacchi 		ecore_func_state_change_comp(pdev, o, cmd);
6770d14abf15SRobert Mustacchi 		ECORE_MUTEX_UNLOCK(&o->one_pending_mutex);
6771d14abf15SRobert Mustacchi 	} else {
6772d14abf15SRobert Mustacchi 		/* Send a ramrod */
6773d14abf15SRobert Mustacchi 		rc = o->send_cmd(pdev, params);
6774d14abf15SRobert Mustacchi 
6775d14abf15SRobert Mustacchi 		ECORE_MUTEX_UNLOCK(&o->one_pending_mutex);
6776d14abf15SRobert Mustacchi 
6777d14abf15SRobert Mustacchi 		if (rc) {
6778d14abf15SRobert Mustacchi 			o->next_state = ECORE_F_STATE_MAX;
6779d14abf15SRobert Mustacchi 			ECORE_CLEAR_BIT(cmd, pending);
6780d14abf15SRobert Mustacchi 			smp_mb__after_atomic();
6781d14abf15SRobert Mustacchi 			return rc;
6782d14abf15SRobert Mustacchi 		}
6783d14abf15SRobert Mustacchi 
6784d14abf15SRobert Mustacchi 		if (ECORE_TEST_BIT(RAMROD_COMP_WAIT, &params->ramrod_flags)) {
6785d14abf15SRobert Mustacchi 			rc = o->wait_comp(pdev, o, cmd);
6786d14abf15SRobert Mustacchi 			if (rc)
6787d14abf15SRobert Mustacchi 				return rc;
6788d14abf15SRobert Mustacchi 
6789d14abf15SRobert Mustacchi 			return ECORE_SUCCESS;
6790d14abf15SRobert Mustacchi 		}
6791d14abf15SRobert Mustacchi 	}
6792d14abf15SRobert Mustacchi 
6793d14abf15SRobert Mustacchi 	return ECORE_RET_PENDING(cmd, pending);
6794d14abf15SRobert Mustacchi }
6795d14abf15SRobert Mustacchi #endif
6796