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, ®_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(®_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 ®_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(®_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(®_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(®_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, ¶ms->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, ¶ms->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 ¶ms->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 = ¶ms->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 ¶ms->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 ¶ms->update_flags);
5322d14abf15SRobert Mustacchi data->inner_vlan_removal_change_flg =
5323d14abf15SRobert Mustacchi ECORE_TEST_BIT(ECORE_Q_UPDATE_IN_VLAN_REM_CHNG,
5324d14abf15SRobert Mustacchi ¶ms->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 ¶ms->update_flags);
5330d14abf15SRobert Mustacchi data->outer_vlan_removal_change_flg =
5331d14abf15SRobert Mustacchi ECORE_TEST_BIT(ECORE_Q_UPDATE_OUT_VLAN_REM_CHNG,
5332d14abf15SRobert Mustacchi ¶ms->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 ¶ms->update_flags);
5340d14abf15SRobert Mustacchi data->anti_spoofing_change_flg =
5341d14abf15SRobert Mustacchi ECORE_TEST_BIT(ECORE_Q_UPDATE_ANTI_SPOOF_CHNG,
5342d14abf15SRobert Mustacchi ¶ms->update_flags);
5343d14abf15SRobert Mustacchi
5344d14abf15SRobert Mustacchi /* Activate/Deactivate */
5345d14abf15SRobert Mustacchi data->activate_flg =
5346d14abf15SRobert Mustacchi ECORE_TEST_BIT(ECORE_Q_UPDATE_ACTIVATE, ¶ms->update_flags);
5347d14abf15SRobert Mustacchi data->activate_change_flg =
5348d14abf15SRobert Mustacchi ECORE_TEST_BIT(ECORE_Q_UPDATE_ACTIVATE_CHNG,
5349d14abf15SRobert Mustacchi ¶ms->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 ¶ms->update_flags);
5355d14abf15SRobert Mustacchi data->default_vlan_change_flg =
5356d14abf15SRobert Mustacchi ECORE_TEST_BIT(ECORE_Q_UPDATE_DEF_VLAN_EN_CHNG,
5357d14abf15SRobert Mustacchi ¶ms->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 ¶ms->update_flags);
5363d14abf15SRobert Mustacchi data->silent_vlan_removal_flg =
5364d14abf15SRobert Mustacchi ECORE_TEST_BIT(ECORE_Q_UPDATE_SILENT_VLAN_REM,
5365d14abf15SRobert Mustacchi ¶ms->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 ¶ms->update_flags);
5373d14abf15SRobert Mustacchi data->tx_switching_change_flg =
5374d14abf15SRobert Mustacchi ECORE_TEST_BIT(ECORE_Q_UPDATE_TX_SWITCHING_CHNG,
5375d14abf15SRobert Mustacchi ¶ms->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 ¶ms->update_flags);
5381d14abf15SRobert Mustacchi data->handle_ptp_pkts_change_flg =
5382d14abf15SRobert Mustacchi ECORE_TEST_BIT(ECORE_Q_UPDATE_PTP_PKTS_CHNG,
5383d14abf15SRobert Mustacchi ¶ms->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 ¶ms->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 = ¶ms->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 = ¶ms->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 ¶ms->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 ¶ms->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, ¶ms->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 ¶ms->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 ¶ms->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, ¶ms->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 = ¶ms->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 ¶ms->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 ¶ms->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 ¶ms->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 ¶ms->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 ¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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