aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qede/base/ecore_spq.h
blob: 526cff08f7c45b99f0070a515a578c11701c355d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
/*
 * Copyright (c) 2016 QLogic Corporation.
 * All rights reserved.
 * www.qlogic.com
 *
 * See LICENSE.qede_pmd for copyright and licensing details.
 */

#ifndef __ECORE_SPQ_H__
#define __ECORE_SPQ_H__

#include "ecore_hsi_common.h"
#include "ecore_status.h"
#include "ecore_hsi_eth.h"
#include "ecore_chain.h"
#include "ecore_sp_api.h"

union ramrod_data {
	struct pf_start_ramrod_data			pf_start;
	struct pf_update_ramrod_data			pf_update;
	struct rl_update_ramrod_data			rl_update;
	struct rx_queue_start_ramrod_data		rx_queue_start;
	struct rx_queue_update_ramrod_data		rx_queue_update;
	struct rx_queue_stop_ramrod_data		rx_queue_stop;
	struct tx_queue_start_ramrod_data		tx_queue_start;
	struct tx_queue_stop_ramrod_data		tx_queue_stop;
	struct vport_start_ramrod_data			vport_start;
	struct vport_stop_ramrod_data			vport_stop;
	struct rx_update_gft_filter_data		rx_update_gft;
	struct vport_update_ramrod_data			vport_update;
	struct core_rx_start_ramrod_data		core_rx_queue_start;
	struct core_rx_stop_ramrod_data			core_rx_queue_stop;
	struct core_tx_start_ramrod_data		core_tx_queue_start;
	struct core_tx_stop_ramrod_data			core_tx_queue_stop;
	struct vport_filter_update_ramrod_data		vport_filter_update;

	struct vf_start_ramrod_data			vf_start;
	struct vf_stop_ramrod_data			vf_stop;
};

#define EQ_MAX_CREDIT	0xffffffff

enum spq_priority {
	ECORE_SPQ_PRIORITY_NORMAL,
	ECORE_SPQ_PRIORITY_HIGH,
};

union ecore_spq_req_comp {
	struct ecore_spq_comp_cb cb;
	u64			 *done_addr;
};

/* SPQ_MODE_EBLOCK */
struct ecore_spq_comp_done {
	u64 done;
	u8  fw_return_code;
};

struct ecore_spq_entry {
	osal_list_entry_t		list;

	u8				flags;

	/* HSI slow path element */
	struct slow_path_element	elem;

	union ramrod_data		ramrod;

	enum spq_priority		priority;

	/* pending queue for this entry */
	osal_list_t			*queue;

	enum spq_mode			comp_mode;
	struct ecore_spq_comp_cb	comp_cb;
	struct ecore_spq_comp_done	comp_done; /* SPQ_MODE_EBLOCK */
};

struct ecore_eq {
	struct ecore_chain	chain;
	u8			eq_sb_index;	/* index within the SB */
	__le16			*p_fw_cons;	/* ptr to index value */
};

struct ecore_consq {
	struct ecore_chain	chain;
};

typedef enum _ecore_status_t
(*ecore_spq_async_comp_cb)(struct ecore_hwfn *p_hwfn,
			   u8 opcode,
			   u16 echo,
			   union event_ring_data *data,
			   u8 fw_return_code);

enum _ecore_status_t
ecore_spq_register_async_cb(struct ecore_hwfn *p_hwfn,
			    enum protocol_type protocol_id,
			    ecore_spq_async_comp_cb cb);

void
ecore_spq_unregister_async_cb(struct ecore_hwfn *p_hwfn,
			      enum protocol_type protocol_id);

struct ecore_spq {
	osal_spinlock_t			lock;

	osal_list_t			unlimited_pending;
	osal_list_t			pending;
	osal_list_t			completion_pending;
	osal_list_t			free_pool;

	struct ecore_chain		chain;

	/* allocated dma-able memory for spq entries (+ramrod data) */
	dma_addr_t			p_phys;
	struct ecore_spq_entry		*p_virt;

	/* Bitmap for handling out-of-order completions */
#define SPQ_RING_SIZE		\
	(CORE_SPQE_PAGE_SIZE_BYTES / sizeof(struct slow_path_element))
/* BITS_PER_LONG */
#define SPQ_COMP_BMAP_SIZE	(SPQ_RING_SIZE / (sizeof(unsigned long) * 8))
	unsigned long			p_comp_bitmap[SPQ_COMP_BMAP_SIZE];
	u8				comp_bitmap_idx;
#define SPQ_COMP_BMAP_SET_BIT(p_spq, idx)				\
	(OSAL_SET_BIT(((idx) % SPQ_RING_SIZE), (p_spq)->p_comp_bitmap))

#define SPQ_COMP_BMAP_CLEAR_BIT(p_spq, idx)				\
	(OSAL_CLEAR_BIT(((idx) % SPQ_RING_SIZE), (p_spq)->p_comp_bitmap))

#define SPQ_COMP_BMAP_TEST_BIT(p_spq, idx)	\
	(OSAL_TEST_BIT(((idx) % SPQ_RING_SIZE), (p_spq)->p_comp_bitmap))

	/* Statistics */
	u32				unlimited_pending_count;
	u32				normal_count;
	u32				high_count;
	u32				comp_sent_count;
	u32				comp_count;

	u32				cid;

	u32				db_addr_offset;
	struct core_db_data		db_data;
	ecore_spq_async_comp_cb		async_comp_cb[MAX_PROTOCOL_TYPE];
};

struct ecore_port;
struct ecore_hwfn;

/**
 * @brief ecore_spq_post - Posts a Slow hwfn request to FW, or lacking that
 *        Pends it to the future list.
 *
 * @param p_hwfn
 * @param p_req
 *
 * @return enum _ecore_status_t
 */
enum _ecore_status_t ecore_spq_post(struct ecore_hwfn	   *p_hwfn,
				    struct ecore_spq_entry *p_ent,
				    u8                     *fw_return_code);

/**
 * @brief ecore_spq_allocate - Alloocates & initializes the SPQ and EQ.
 *
 * @param p_hwfn
 *
 * @return enum _ecore_status_t
 */
enum _ecore_status_t ecore_spq_alloc(struct ecore_hwfn	*p_hwfn);

/**
 * @brief ecore_spq_setup - Reset the SPQ to its start state.
 *
 * @param p_hwfn
 */
void ecore_spq_setup(struct ecore_hwfn *p_hwfn);

/**
 * @brief ecore_spq_deallocate - Deallocates the given SPQ struct.
 *
 * @param p_hwfn
 */
void ecore_spq_free(struct ecore_hwfn *p_hwfn);

/**
 * @brief ecore_spq_get_entry - Obtain an entrry from the spq
 *        free pool list.
 *
 *
 *
 * @param p_hwfn
 * @param pp_ent
 *
 * @return enum _ecore_status_t
 */
enum _ecore_status_t
ecore_spq_get_entry(struct ecore_hwfn		*p_hwfn,
		    struct ecore_spq_entry	**pp_ent);

/**
 * @brief ecore_spq_return_entry - Return an entry to spq free
 *                                 pool list
 *
 * @param p_hwfn
 * @param p_ent
 */
void ecore_spq_return_entry(struct ecore_hwfn		*p_hwfn,
			    struct ecore_spq_entry      *p_ent);
/**
 * @brief ecore_eq_allocate - Allocates & initializes an EQ struct
 *
 * @param p_hwfn
 * @param num_elem number of elements in the eq
 *
 * @return enum _ecore_status_t
 */
enum _ecore_status_t ecore_eq_alloc(struct ecore_hwfn	*p_hwfn, u16 num_elem);

/**
 * @brief ecore_eq_setup - Reset the EQ to its start state.
 *
 * @param p_hwfn
 */
void ecore_eq_setup(struct ecore_hwfn *p_hwfn);

/**
 * @brief ecore_eq_free - deallocates the given EQ struct.
 *
 * @param p_hwfn
 */
void ecore_eq_free(struct ecore_hwfn *p_hwfn);

/**
 * @brief ecore_eq_prod_update - update the FW with default EQ producer
 *
 * @param p_hwfn
 * @param prod
 */
void ecore_eq_prod_update(struct ecore_hwfn	*p_hwfn,
			  u16			prod);

/**
 * @brief ecore_eq_completion - Completes currently pending EQ elements
 *
 * @param p_hwfn
 * @param cookie
 *
 * @return enum _ecore_status_t
 */
enum _ecore_status_t ecore_eq_completion(struct ecore_hwfn	*p_hwfn,
					 void			*cookie);

/**
 * @brief ecore_spq_completion - Completes a single event
 *
 * @param p_hwfn
 * @param echo - echo value from cookie (used for determining completion)
 * @param p_data - data from cookie (used in callback function if applicable)
 *
 * @return enum _ecore_status_t
 */
enum _ecore_status_t ecore_spq_completion(struct ecore_hwfn	*p_hwfn,
					  __le16		echo,
					  u8                    fw_return_code,
					  union event_ring_data	*p_data);

/**
 * @brief ecore_spq_get_cid - Given p_hwfn, return cid for the hwfn's SPQ
 *
 * @param p_hwfn
 *
 * @return u32 - SPQ CID
 */
u32 ecore_spq_get_cid(struct ecore_hwfn *p_hwfn);

/**
 * @brief ecore_consq_alloc - Allocates & initializes an ConsQ struct
 *
 * @param p_hwfn
 *
 * @return enum _ecore_status_t
 */
enum _ecore_status_t ecore_consq_alloc(struct ecore_hwfn *p_hwfn);

/**
 * @brief ecore_consq_setup - Reset the ConsQ to its start state.
 *
 * @param p_hwfn
 */
void ecore_consq_setup(struct ecore_hwfn *p_hwfn);

/**
 * @brief ecore_consq_free - deallocates the given ConsQ struct.
 *
 * @param p_hwfn
 */
void ecore_consq_free(struct ecore_hwfn *p_hwfn);

#endif /* __ECORE_SPQ_H__ */