]>
Commit | Line | Data |
---|---|---|
1ab4434c AE |
1 | /* bnx2x_sriov.h: Broadcom Everest network driver. |
2 | * | |
247fa82b | 3 | * Copyright 2009-2013 Broadcom Corporation |
1ab4434c AE |
4 | * |
5 | * Unless you and Broadcom execute a separate written software license | |
6 | * agreement governing use of this software, this software is licensed to you | |
7 | * under the terms of the GNU General Public License version 2, available | |
8 | * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL"). | |
9 | * | |
10 | * Notwithstanding the above, under no circumstances may you combine this | |
11 | * software in any way with any other Broadcom software provided under a | |
12 | * license other than the GPL, without Broadcom's express prior written | |
13 | * consent. | |
14 | * | |
15 | * Maintained by: Eilon Greenstein <eilong@broadcom.com> | |
16 | * Written by: Shmulik Ravid <shmulikr@broadcom.com> | |
17 | * Ariel Elior <ariele@broadcom.com> | |
18 | */ | |
19 | #ifndef BNX2X_SRIOV_H | |
20 | #define BNX2X_SRIOV_H | |
21 | ||
8ca5e17e | 22 | #include "bnx2x_vfpf.h" |
6411280a AE |
23 | #include "bnx2x.h" |
24 | ||
25 | enum sample_bulletin_result { | |
26 | PFVF_BULLETIN_UNCHANGED, | |
27 | PFVF_BULLETIN_UPDATED, | |
28 | PFVF_BULLETIN_CRC_ERR | |
29 | }; | |
30 | ||
31 | #ifdef CONFIG_BNX2X_SRIOV | |
8ca5e17e | 32 | |
290ca2bb AE |
33 | /* The bnx2x device structure holds vfdb structure described below. |
34 | * The VF array is indexed by the relative vfid. | |
35 | */ | |
8ca5e17e | 36 | #define BNX2X_VF_MAX_QUEUES 16 |
8db573ba AE |
37 | #define BNX2X_VF_MAX_TPA_AGG_QUEUES 8 |
38 | ||
290ca2bb AE |
39 | struct bnx2x_sriov { |
40 | u32 first_vf_in_pf; | |
41 | ||
42 | /* standard SRIOV capability fields, mostly for debugging */ | |
43 | int pos; /* capability position */ | |
44 | int nres; /* number of resources */ | |
45 | u32 cap; /* SR-IOV Capabilities */ | |
46 | u16 ctrl; /* SR-IOV Control */ | |
47 | u16 total; /* total VFs associated with the PF */ | |
48 | u16 initial; /* initial VFs associated with the PF */ | |
49 | u16 nr_virtfn; /* number of VFs available */ | |
50 | u16 offset; /* first VF Routing ID offset */ | |
51 | u16 stride; /* following VF stride */ | |
52 | u32 pgsz; /* page size for BAR alignment */ | |
53 | u8 link; /* Function Dependency Link */ | |
54 | }; | |
55 | ||
56 | /* bars */ | |
57 | struct bnx2x_vf_bar { | |
58 | u64 bar; | |
59 | u32 size; | |
60 | }; | |
61 | ||
f1929b01 AE |
62 | struct bnx2x_vf_bar_info { |
63 | struct bnx2x_vf_bar bars[PCI_SRIOV_NUM_BARS]; | |
64 | u8 nr_bars; | |
65 | }; | |
66 | ||
290ca2bb AE |
67 | /* vf queue (used both for rx or tx) */ |
68 | struct bnx2x_vf_queue { | |
69 | struct eth_context *cxt; | |
70 | ||
71 | /* MACs object */ | |
72 | struct bnx2x_vlan_mac_obj mac_obj; | |
73 | ||
74 | /* VLANs object */ | |
75 | struct bnx2x_vlan_mac_obj vlan_obj; | |
76 | atomic_t vlan_count; /* 0 means vlan-0 is set ~ untagged */ | |
77 | ||
78 | /* Queue Slow-path State object */ | |
79 | struct bnx2x_queue_sp_obj sp_obj; | |
80 | ||
81 | u32 cid; | |
82 | u16 index; | |
83 | u16 sb_idx; | |
b9871bcf | 84 | bool is_leading; |
290ca2bb AE |
85 | }; |
86 | ||
87 | /* struct bnx2x_vfop_qctor_params - prepare queue construction parameters: | |
88 | * q-init, q-setup and SB index | |
89 | */ | |
90 | struct bnx2x_vfop_qctor_params { | |
91 | struct bnx2x_queue_state_params qstate; | |
92 | struct bnx2x_queue_setup_params prep_qsetup; | |
93 | }; | |
94 | ||
95 | /* VFOP parameters (one copy per VF) */ | |
96 | union bnx2x_vfop_params { | |
97 | struct bnx2x_vlan_mac_ramrod_params vlan_mac; | |
98 | struct bnx2x_rx_mode_ramrod_params rx_mode; | |
99 | struct bnx2x_mcast_ramrod_params mcast; | |
100 | struct bnx2x_config_rss_params rss; | |
101 | struct bnx2x_vfop_qctor_params qctor; | |
102 | }; | |
103 | ||
104 | /* forward */ | |
105 | struct bnx2x_virtf; | |
fd1fc79d AE |
106 | |
107 | /* VFOP definitions */ | |
108 | typedef void (*vfop_handler_t)(struct bnx2x *bp, struct bnx2x_virtf *vf); | |
109 | ||
8db573ba AE |
110 | struct bnx2x_vfop_cmd { |
111 | vfop_handler_t done; | |
112 | bool block; | |
113 | }; | |
114 | ||
fd1fc79d AE |
115 | /* VFOP queue filters command additional arguments */ |
116 | struct bnx2x_vfop_filter { | |
117 | struct list_head link; | |
118 | int type; | |
119 | #define BNX2X_VFOP_FILTER_MAC 1 | |
120 | #define BNX2X_VFOP_FILTER_VLAN 2 | |
121 | ||
122 | bool add; | |
123 | u8 *mac; | |
124 | u16 vid; | |
125 | }; | |
126 | ||
127 | struct bnx2x_vfop_filters { | |
128 | int add_cnt; | |
129 | struct list_head head; | |
130 | struct bnx2x_vfop_filter filters[]; | |
131 | }; | |
132 | ||
133 | /* transient list allocated, built and saved until its | |
134 | * passed to the SP-VERBs layer. | |
135 | */ | |
136 | struct bnx2x_vfop_args_mcast { | |
137 | int mc_num; | |
138 | struct bnx2x_mcast_list_elem *mc; | |
139 | }; | |
140 | ||
141 | struct bnx2x_vfop_args_qctor { | |
142 | int qid; | |
143 | u16 sb_idx; | |
144 | }; | |
145 | ||
146 | struct bnx2x_vfop_args_qdtor { | |
147 | int qid; | |
148 | struct eth_context *cxt; | |
149 | }; | |
150 | ||
151 | struct bnx2x_vfop_args_defvlan { | |
152 | int qid; | |
153 | bool enable; | |
154 | u16 vid; | |
155 | u8 prio; | |
156 | }; | |
157 | ||
158 | struct bnx2x_vfop_args_qx { | |
159 | int qid; | |
160 | bool en_add; | |
161 | }; | |
162 | ||
163 | struct bnx2x_vfop_args_filters { | |
164 | struct bnx2x_vfop_filters *multi_filter; | |
165 | atomic_t *credit; /* non NULL means 'don't consume credit' */ | |
166 | }; | |
167 | ||
168 | union bnx2x_vfop_args { | |
169 | struct bnx2x_vfop_args_mcast mc_list; | |
170 | struct bnx2x_vfop_args_qctor qctor; | |
171 | struct bnx2x_vfop_args_qdtor qdtor; | |
172 | struct bnx2x_vfop_args_defvlan defvlan; | |
173 | struct bnx2x_vfop_args_qx qx; | |
174 | struct bnx2x_vfop_args_filters filters; | |
175 | }; | |
176 | ||
177 | struct bnx2x_vfop { | |
178 | struct list_head link; | |
179 | int rc; /* return code */ | |
180 | int state; /* next state */ | |
181 | union bnx2x_vfop_args args; /* extra arguments */ | |
182 | union bnx2x_vfop_params *op_p; /* ramrod params */ | |
183 | ||
184 | /* state machine callbacks */ | |
185 | vfop_handler_t transition; | |
186 | vfop_handler_t done; | |
187 | }; | |
188 | ||
290ca2bb AE |
189 | /* vf context */ |
190 | struct bnx2x_virtf { | |
191 | u16 cfg_flags; | |
192 | #define VF_CFG_STATS 0x0001 | |
193 | #define VF_CFG_FW_FC 0x0002 | |
194 | #define VF_CFG_TPA 0x0004 | |
195 | #define VF_CFG_INT_SIMD 0x0008 | |
196 | #define VF_CACHE_LINE 0x0010 | |
3ec9f9ca | 197 | #define VF_CFG_VLAN 0x0020 |
b9871bcf | 198 | #define VF_CFG_STATS_COALESCE 0x0040 |
290ca2bb AE |
199 | |
200 | u8 state; | |
201 | #define VF_FREE 0 /* VF ready to be acquired holds no resc */ | |
16a5fd92 | 202 | #define VF_ACQUIRED 1 /* VF acquired, but not initialized */ |
290ca2bb AE |
203 | #define VF_ENABLED 2 /* VF Enabled */ |
204 | #define VF_RESET 3 /* VF FLR'd, pending cleanup */ | |
205 | ||
206 | /* non 0 during flr cleanup */ | |
207 | u8 flr_clnup_stage; | |
208 | #define VF_FLR_CLN 1 /* reclaim resources and do 'final cleanup' | |
209 | * sans the end-wait | |
210 | */ | |
211 | #define VF_FLR_ACK 2 /* ACK flr notification */ | |
212 | #define VF_FLR_EPILOG 3 /* wait for VF remnants to dissipate in the HW | |
213 | * ~ final cleanup' end wait | |
214 | */ | |
215 | ||
216 | /* dma */ | |
217 | dma_addr_t fw_stat_map; /* valid iff VF_CFG_STATS */ | |
b9871bcf | 218 | u16 stats_stride; |
290ca2bb AE |
219 | dma_addr_t spq_map; |
220 | dma_addr_t bulletin_map; | |
221 | ||
222 | /* Allocated resources counters. Before the VF is acquired, the | |
223 | * counters hold the following values: | |
224 | * | |
225 | * - xxq_count = 0 as the queues memory is not allocated yet. | |
226 | * | |
227 | * - sb_count = The number of status blocks configured for this VF in | |
228 | * the IGU CAM. Initially read during probe. | |
229 | * | |
230 | * - xx_rules_count = The number of rules statically and equally | |
231 | * allocated for each VF, during PF load. | |
232 | */ | |
233 | struct vf_pf_resc_request alloc_resc; | |
234 | #define vf_rxq_count(vf) ((vf)->alloc_resc.num_rxqs) | |
235 | #define vf_txq_count(vf) ((vf)->alloc_resc.num_txqs) | |
236 | #define vf_sb_count(vf) ((vf)->alloc_resc.num_sbs) | |
237 | #define vf_mac_rules_cnt(vf) ((vf)->alloc_resc.num_mac_filters) | |
238 | #define vf_vlan_rules_cnt(vf) ((vf)->alloc_resc.num_vlan_filters) | |
239 | #define vf_mc_rules_cnt(vf) ((vf)->alloc_resc.num_mc_filters) | |
240 | ||
241 | u8 sb_count; /* actual number of SBs */ | |
242 | u8 igu_base_id; /* base igu status block id */ | |
243 | ||
244 | struct bnx2x_vf_queue *vfqs; | |
b9871bcf AE |
245 | #define LEADING_IDX 0 |
246 | #define bnx2x_vfq_is_leading(vfq) ((vfq)->index == LEADING_IDX) | |
247 | #define bnx2x_vfq(vf, nr, var) ((vf)->vfqs[(nr)].var) | |
248 | #define bnx2x_leading_vfq(vf, var) ((vf)->vfqs[LEADING_IDX].var) | |
290ca2bb AE |
249 | |
250 | u8 index; /* index in the vf array */ | |
251 | u8 abs_vfid; | |
252 | u8 sp_cl_id; | |
253 | u32 error; /* 0 means all's-well */ | |
254 | ||
255 | /* BDF */ | |
256 | unsigned int bus; | |
257 | unsigned int devfn; | |
258 | ||
259 | /* bars */ | |
260 | struct bnx2x_vf_bar bars[PCI_SRIOV_NUM_BARS]; | |
261 | ||
262 | /* set-mac ramrod state 1-pending, 0-done */ | |
263 | unsigned long filter_state; | |
264 | ||
265 | /* leading rss client id ~~ the client id of the first rxq, must be | |
266 | * set for each txq. | |
267 | */ | |
268 | int leading_rss; | |
269 | ||
270 | /* MCAST object */ | |
271 | struct bnx2x_mcast_obj mcast_obj; | |
272 | ||
273 | /* RSS configuration object */ | |
274 | struct bnx2x_rss_config_obj rss_conf_obj; | |
275 | ||
276 | /* slow-path operations */ | |
277 | atomic_t op_in_progress; | |
278 | int op_rc; | |
279 | bool op_wait_blocking; | |
280 | struct list_head op_list_head; | |
281 | union bnx2x_vfop_params op_params; | |
282 | struct mutex op_mutex; /* one vfop at a time mutex */ | |
283 | enum channel_tlvs op_current; | |
284 | }; | |
285 | ||
286 | #define BNX2X_NR_VIRTFN(bp) ((bp)->vfdb->sriov.nr_virtfn) | |
287 | ||
288 | #define for_each_vf(bp, var) \ | |
289 | for ((var) = 0; (var) < BNX2X_NR_VIRTFN(bp); (var)++) | |
290 | ||
8ca5e17e AE |
291 | #define for_each_vfq(vf, var) \ |
292 | for ((var) = 0; (var) < vf_rxq_count(vf); (var)++) | |
293 | ||
294 | #define for_each_vf_sb(vf, var) \ | |
295 | for ((var) = 0; (var) < vf_sb_count(vf); (var)++) | |
296 | ||
b93288d5 AE |
297 | #define is_vf_multi(vf) (vf_rxq_count(vf) > 1) |
298 | ||
b56e9670 AE |
299 | #define HW_VF_HANDLE(bp, abs_vfid) \ |
300 | (u16)(BP_ABS_FUNC((bp)) | (1<<3) | ((u16)(abs_vfid) << 4)) | |
301 | ||
302 | #define FW_PF_MAX_HANDLE 8 | |
303 | ||
304 | #define FW_VF_HANDLE(abs_vfid) \ | |
305 | (abs_vfid + FW_PF_MAX_HANDLE) | |
306 | ||
8ca5e17e AE |
307 | /* locking and unlocking the channel mutex */ |
308 | void bnx2x_lock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf, | |
309 | enum channel_tlvs tlv); | |
310 | ||
311 | void bnx2x_unlock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf, | |
312 | enum channel_tlvs expected_tlv); | |
313 | ||
b56e9670 AE |
314 | /* VF mail box (aka vf-pf channel) */ |
315 | ||
316 | /* a container for the bi-directional vf<-->pf messages. | |
317 | * The actual response will be placed according to the offset parameter | |
318 | * provided in the request | |
319 | */ | |
320 | ||
321 | #define MBX_MSG_ALIGN 8 | |
322 | #define MBX_MSG_ALIGNED_SIZE (roundup(sizeof(struct bnx2x_vf_mbx_msg), \ | |
323 | MBX_MSG_ALIGN)) | |
324 | ||
1ab4434c AE |
325 | struct bnx2x_vf_mbx_msg { |
326 | union vfpf_tlvs req; | |
327 | union pfvf_tlvs resp; | |
328 | }; | |
329 | ||
290ca2bb AE |
330 | struct bnx2x_vf_mbx { |
331 | struct bnx2x_vf_mbx_msg *msg; | |
332 | dma_addr_t msg_mapping; | |
333 | ||
334 | /* VF GPA address */ | |
335 | u32 vf_addr_lo; | |
336 | u32 vf_addr_hi; | |
337 | ||
338 | struct vfpf_first_tlv first_tlv; /* saved VF request header */ | |
339 | ||
340 | u8 flags; | |
341 | #define VF_MSG_INPROCESS 0x1 /* failsafe - the FW should prevent | |
342 | * more then one pending msg | |
343 | */ | |
344 | }; | |
345 | ||
b56e9670 AE |
346 | struct bnx2x_vf_sp { |
347 | union { | |
348 | struct eth_classify_rules_ramrod_data e2; | |
349 | } mac_rdata; | |
350 | ||
351 | union { | |
352 | struct eth_classify_rules_ramrod_data e2; | |
353 | } vlan_rdata; | |
354 | ||
355 | union { | |
356 | struct eth_filter_rules_ramrod_data e2; | |
357 | } rx_mode_rdata; | |
358 | ||
359 | union { | |
360 | struct eth_multicast_rules_ramrod_data e2; | |
361 | } mcast_rdata; | |
362 | ||
363 | union { | |
364 | struct client_init_ramrod_data init_data; | |
365 | struct client_update_ramrod_data update_data; | |
366 | } q_data; | |
b9871bcf AE |
367 | |
368 | union { | |
369 | struct eth_rss_update_ramrod_data e2; | |
370 | } rss_rdata; | |
b56e9670 AE |
371 | }; |
372 | ||
290ca2bb AE |
373 | struct hw_dma { |
374 | void *addr; | |
375 | dma_addr_t mapping; | |
376 | size_t size; | |
377 | }; | |
378 | ||
379 | struct bnx2x_vfdb { | |
380 | #define BP_VFDB(bp) ((bp)->vfdb) | |
381 | /* vf array */ | |
382 | struct bnx2x_virtf *vfs; | |
383 | #define BP_VF(bp, idx) (&((bp)->vfdb->vfs[(idx)])) | |
384 | #define bnx2x_vf(bp, idx, var) ((bp)->vfdb->vfs[(idx)].var) | |
385 | ||
386 | /* queue array - for all vfs */ | |
387 | struct bnx2x_vf_queue *vfqs; | |
388 | ||
389 | /* vf HW contexts */ | |
390 | struct hw_dma context[BNX2X_VF_CIDS/ILT_PAGE_CIDS]; | |
391 | #define BP_VF_CXT_PAGE(bp, i) (&(bp)->vfdb->context[(i)]) | |
392 | ||
393 | /* SR-IOV information */ | |
394 | struct bnx2x_sriov sriov; | |
395 | struct hw_dma mbx_dma; | |
396 | #define BP_VF_MBX_DMA(bp) (&((bp)->vfdb->mbx_dma)) | |
397 | struct bnx2x_vf_mbx mbxs[BNX2X_MAX_NUM_OF_VFS]; | |
398 | #define BP_VF_MBX(bp, vfid) (&((bp)->vfdb->mbxs[(vfid)])) | |
399 | ||
abc5a021 AE |
400 | struct hw_dma bulletin_dma; |
401 | #define BP_VF_BULLETIN_DMA(bp) (&((bp)->vfdb->bulletin_dma)) | |
402 | #define BP_VF_BULLETIN(bp, vf) \ | |
403 | (((struct pf_vf_bulletin_content *)(BP_VF_BULLETIN_DMA(bp)->addr)) \ | |
404 | + (vf)) | |
405 | ||
290ca2bb AE |
406 | struct hw_dma sp_dma; |
407 | #define bnx2x_vf_sp(bp, vf, field) ((bp)->vfdb->sp_dma.addr + \ | |
408 | (vf)->index * sizeof(struct bnx2x_vf_sp) + \ | |
409 | offsetof(struct bnx2x_vf_sp, field)) | |
410 | #define bnx2x_vf_sp_map(bp, vf, field) ((bp)->vfdb->sp_dma.mapping + \ | |
411 | (vf)->index * sizeof(struct bnx2x_vf_sp) + \ | |
412 | offsetof(struct bnx2x_vf_sp, field)) | |
413 | ||
414 | #define FLRD_VFS_DWORDS (BNX2X_MAX_NUM_OF_VFS / 32) | |
415 | u32 flrd_vfs[FLRD_VFS_DWORDS]; | |
b9871bcf AE |
416 | |
417 | /* the number of msix vectors belonging to this PF designated for VFs */ | |
418 | u16 vf_sbs_pool; | |
419 | u16 first_vf_igu_entry; | |
290ca2bb AE |
420 | }; |
421 | ||
fd1fc79d AE |
422 | /* queue access */ |
423 | static inline struct bnx2x_vf_queue *vfq_get(struct bnx2x_virtf *vf, u8 index) | |
424 | { | |
425 | return &(vf->vfqs[index]); | |
426 | } | |
427 | ||
8ca5e17e | 428 | /* FW ids */ |
b56e9670 AE |
429 | static inline u8 vf_igu_sb(struct bnx2x_virtf *vf, u16 sb_idx) |
430 | { | |
431 | return vf->igu_base_id + sb_idx; | |
432 | } | |
433 | ||
8ca5e17e AE |
434 | static inline u8 vf_hc_qzone(struct bnx2x_virtf *vf, u16 sb_idx) |
435 | { | |
436 | return vf_igu_sb(vf, sb_idx); | |
437 | } | |
438 | ||
439 | static u8 vfq_cl_id(struct bnx2x_virtf *vf, struct bnx2x_vf_queue *q) | |
440 | { | |
441 | return vf->igu_base_id + q->index; | |
442 | } | |
443 | ||
8db573ba AE |
444 | static inline u8 vfq_stat_id(struct bnx2x_virtf *vf, struct bnx2x_vf_queue *q) |
445 | { | |
b9871bcf AE |
446 | if (vf->cfg_flags & VF_CFG_STATS_COALESCE) |
447 | return vf->leading_rss; | |
448 | else | |
449 | return vfq_cl_id(vf, q); | |
8db573ba AE |
450 | } |
451 | ||
8ca5e17e AE |
452 | static inline u8 vfq_qzone_id(struct bnx2x_virtf *vf, struct bnx2x_vf_queue *q) |
453 | { | |
454 | return vfq_cl_id(vf, q); | |
455 | } | |
456 | ||
290ca2bb AE |
457 | /* global iov routines */ |
458 | int bnx2x_iov_init_ilt(struct bnx2x *bp, u16 line); | |
459 | int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, int num_vfs_param); | |
460 | void bnx2x_iov_remove_one(struct bnx2x *bp); | |
b56e9670 AE |
461 | void bnx2x_iov_free_mem(struct bnx2x *bp); |
462 | int bnx2x_iov_alloc_mem(struct bnx2x *bp); | |
463 | int bnx2x_iov_nic_init(struct bnx2x *bp); | |
f1929b01 | 464 | int bnx2x_iov_chip_cleanup(struct bnx2x *bp); |
b56e9670 AE |
465 | void bnx2x_iov_init_dq(struct bnx2x *bp); |
466 | void bnx2x_iov_init_dmae(struct bnx2x *bp); | |
fd1fc79d AE |
467 | void bnx2x_iov_set_queue_sp_obj(struct bnx2x *bp, int vf_cid, |
468 | struct bnx2x_queue_sp_obj **q_obj); | |
469 | void bnx2x_iov_sp_event(struct bnx2x *bp, int vf_cid, bool queue_work); | |
470 | int bnx2x_iov_eq_sp_event(struct bnx2x *bp, union event_ring_elem *elem); | |
67c431a5 AE |
471 | void bnx2x_iov_adjust_stats_req(struct bnx2x *bp); |
472 | void bnx2x_iov_storm_stats_update(struct bnx2x *bp); | |
fd1fc79d AE |
473 | void bnx2x_iov_sp_task(struct bnx2x *bp); |
474 | /* global vf mailbox routines */ | |
475 | void bnx2x_vf_mbx(struct bnx2x *bp, struct vf_pf_event_data *vfpf_event); | |
b56e9670 | 476 | void bnx2x_vf_enable_mbx(struct bnx2x *bp, u8 abs_vfid); |
954ea748 AE |
477 | |
478 | /* CORE VF API */ | |
479 | typedef u8 bnx2x_mac_addr_t[ETH_ALEN]; | |
480 | ||
8ca5e17e AE |
481 | /* acquire */ |
482 | int bnx2x_vf_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf, | |
b93288d5 AE |
483 | struct vf_pf_resc_request *resc); |
484 | /* init */ | |
485 | int bnx2x_vf_init(struct bnx2x *bp, struct bnx2x_virtf *vf, | |
486 | dma_addr_t *sb_map); | |
8db573ba AE |
487 | |
488 | /* VFOP generic helpers */ | |
489 | #define bnx2x_vfop_default(state) do { \ | |
490 | BNX2X_ERR("Bad state %d\n", (state)); \ | |
491 | vfop->rc = -EINVAL; \ | |
492 | goto op_err; \ | |
493 | } while (0) | |
494 | ||
495 | enum { | |
496 | VFOP_DONE, | |
497 | VFOP_CONT, | |
498 | VFOP_VERIFY_PEND, | |
499 | }; | |
500 | ||
501 | #define bnx2x_vfop_finalize(vf, rc, next) do { \ | |
502 | if ((rc) < 0) \ | |
503 | goto op_err; \ | |
504 | else if ((rc) > 0) \ | |
505 | goto op_pending; \ | |
506 | else if ((next) == VFOP_DONE) \ | |
507 | goto op_done; \ | |
508 | else if ((next) == VFOP_VERIFY_PEND) \ | |
509 | BNX2X_ERR("expected pending\n"); \ | |
510 | else { \ | |
6bf07b8e | 511 | DP(BNX2X_MSG_IOV, "no ramrod. Scheduling\n"); \ |
8db573ba AE |
512 | atomic_set(&vf->op_in_progress, 1); \ |
513 | queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); \ | |
514 | return; \ | |
515 | } \ | |
516 | } while (0) | |
517 | ||
518 | #define bnx2x_vfop_opset(first_state, trans_hndlr, done_hndlr) \ | |
519 | do { \ | |
520 | vfop->state = first_state; \ | |
521 | vfop->op_p = &vf->op_params; \ | |
522 | vfop->transition = trans_hndlr; \ | |
523 | vfop->done = done_hndlr; \ | |
524 | } while (0) | |
525 | ||
fd1fc79d AE |
526 | static inline struct bnx2x_vfop *bnx2x_vfop_cur(struct bnx2x *bp, |
527 | struct bnx2x_virtf *vf) | |
528 | { | |
529 | WARN(!mutex_is_locked(&vf->op_mutex), "about to access vf op linked list but mutex was not locked!"); | |
530 | WARN_ON(list_empty(&vf->op_list_head)); | |
531 | return list_first_entry(&vf->op_list_head, struct bnx2x_vfop, link); | |
532 | } | |
533 | ||
8db573ba AE |
534 | static inline struct bnx2x_vfop *bnx2x_vfop_add(struct bnx2x *bp, |
535 | struct bnx2x_virtf *vf) | |
536 | { | |
537 | struct bnx2x_vfop *vfop = kzalloc(sizeof(*vfop), GFP_KERNEL); | |
538 | ||
539 | WARN(!mutex_is_locked(&vf->op_mutex), "about to access vf op linked list but mutex was not locked!"); | |
540 | if (vfop) { | |
541 | INIT_LIST_HEAD(&vfop->link); | |
542 | list_add(&vfop->link, &vf->op_list_head); | |
543 | } | |
544 | return vfop; | |
545 | } | |
546 | ||
547 | static inline void bnx2x_vfop_end(struct bnx2x *bp, struct bnx2x_virtf *vf, | |
548 | struct bnx2x_vfop *vfop) | |
549 | { | |
550 | /* rc < 0 - error, otherwise set to 0 */ | |
551 | DP(BNX2X_MSG_IOV, "rc was %d\n", vfop->rc); | |
552 | if (vfop->rc >= 0) | |
553 | vfop->rc = 0; | |
554 | DP(BNX2X_MSG_IOV, "rc is now %d\n", vfop->rc); | |
555 | ||
556 | /* unlink the current op context and propagate error code | |
557 | * must be done before invoking the 'done()' handler | |
558 | */ | |
559 | WARN(!mutex_is_locked(&vf->op_mutex), | |
560 | "about to access vf op linked list but mutex was not locked!"); | |
561 | list_del(&vfop->link); | |
562 | ||
563 | if (list_empty(&vf->op_list_head)) { | |
564 | DP(BNX2X_MSG_IOV, "list was empty %d\n", vfop->rc); | |
565 | vf->op_rc = vfop->rc; | |
566 | DP(BNX2X_MSG_IOV, "copying rc vf->op_rc %d, vfop->rc %d\n", | |
567 | vf->op_rc, vfop->rc); | |
568 | } else { | |
569 | struct bnx2x_vfop *cur_vfop; | |
570 | ||
571 | DP(BNX2X_MSG_IOV, "list not empty %d\n", vfop->rc); | |
572 | cur_vfop = bnx2x_vfop_cur(bp, vf); | |
573 | cur_vfop->rc = vfop->rc; | |
574 | DP(BNX2X_MSG_IOV, "copying rc vf->op_rc %d, vfop->rc %d\n", | |
575 | vf->op_rc, vfop->rc); | |
576 | } | |
577 | ||
578 | /* invoke done handler */ | |
579 | if (vfop->done) { | |
580 | DP(BNX2X_MSG_IOV, "calling done handler\n"); | |
581 | vfop->done(bp, vf); | |
f1929b01 AE |
582 | } else { |
583 | /* there is no done handler for the operation to unlock | |
584 | * the mutex. Must have gotten here from PF initiated VF RELEASE | |
585 | */ | |
586 | bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_RELEASE_VF); | |
8db573ba AE |
587 | } |
588 | ||
589 | DP(BNX2X_MSG_IOV, "done handler complete. vf->op_rc %d, vfop->rc %d\n", | |
590 | vf->op_rc, vfop->rc); | |
591 | ||
592 | /* if this is the last nested op reset the wait_blocking flag | |
593 | * to release any blocking wrappers, only after 'done()' is invoked | |
594 | */ | |
595 | if (list_empty(&vf->op_list_head)) { | |
596 | DP(BNX2X_MSG_IOV, "list was empty after done %d\n", vfop->rc); | |
597 | vf->op_wait_blocking = false; | |
598 | } | |
599 | ||
600 | kfree(vfop); | |
601 | } | |
602 | ||
603 | static inline int bnx2x_vfop_wait_blocking(struct bnx2x *bp, | |
604 | struct bnx2x_virtf *vf) | |
605 | { | |
606 | /* can take a while if any port is running */ | |
607 | int cnt = 5000; | |
608 | ||
609 | might_sleep(); | |
610 | while (cnt--) { | |
611 | if (vf->op_wait_blocking == false) { | |
612 | #ifdef BNX2X_STOP_ON_ERROR | |
613 | DP(BNX2X_MSG_IOV, "exit (cnt %d)\n", 5000 - cnt); | |
614 | #endif | |
615 | return 0; | |
616 | } | |
617 | usleep_range(1000, 2000); | |
618 | ||
619 | if (bp->panic) | |
620 | return -EIO; | |
621 | } | |
622 | ||
623 | /* timeout! */ | |
624 | #ifdef BNX2X_STOP_ON_ERROR | |
625 | bnx2x_panic(); | |
626 | #endif | |
627 | ||
628 | return -EBUSY; | |
629 | } | |
630 | ||
631 | static inline int bnx2x_vfop_transition(struct bnx2x *bp, | |
632 | struct bnx2x_virtf *vf, | |
633 | vfop_handler_t transition, | |
634 | bool block) | |
635 | { | |
636 | if (block) | |
637 | vf->op_wait_blocking = true; | |
638 | transition(bp, vf); | |
639 | if (block) | |
640 | return bnx2x_vfop_wait_blocking(bp, vf); | |
641 | return 0; | |
642 | } | |
643 | ||
644 | /* VFOP queue construction helpers */ | |
645 | void bnx2x_vfop_qctor_dump_tx(struct bnx2x *bp, struct bnx2x_virtf *vf, | |
646 | struct bnx2x_queue_init_params *init_params, | |
647 | struct bnx2x_queue_setup_params *setup_params, | |
648 | u16 q_idx, u16 sb_idx); | |
649 | ||
650 | void bnx2x_vfop_qctor_dump_rx(struct bnx2x *bp, struct bnx2x_virtf *vf, | |
651 | struct bnx2x_queue_init_params *init_params, | |
652 | struct bnx2x_queue_setup_params *setup_params, | |
653 | u16 q_idx, u16 sb_idx); | |
654 | ||
655 | void bnx2x_vfop_qctor_prep(struct bnx2x *bp, | |
656 | struct bnx2x_virtf *vf, | |
657 | struct bnx2x_vf_queue *q, | |
658 | struct bnx2x_vfop_qctor_params *p, | |
659 | unsigned long q_type); | |
954ea748 AE |
660 | int bnx2x_vfop_mac_list_cmd(struct bnx2x *bp, |
661 | struct bnx2x_virtf *vf, | |
662 | struct bnx2x_vfop_cmd *cmd, | |
663 | struct bnx2x_vfop_filters *macs, | |
664 | int qid, bool drv_only); | |
665 | ||
666 | int bnx2x_vfop_vlan_set_cmd(struct bnx2x *bp, | |
667 | struct bnx2x_virtf *vf, | |
668 | struct bnx2x_vfop_cmd *cmd, | |
669 | int qid, u16 vid, bool add); | |
670 | ||
671 | int bnx2x_vfop_vlan_list_cmd(struct bnx2x *bp, | |
672 | struct bnx2x_virtf *vf, | |
673 | struct bnx2x_vfop_cmd *cmd, | |
674 | struct bnx2x_vfop_filters *vlans, | |
675 | int qid, bool drv_only); | |
676 | ||
8db573ba AE |
677 | int bnx2x_vfop_qsetup_cmd(struct bnx2x *bp, |
678 | struct bnx2x_virtf *vf, | |
679 | struct bnx2x_vfop_cmd *cmd, | |
680 | int qid); | |
681 | ||
463a68a7 AE |
682 | int bnx2x_vfop_qdown_cmd(struct bnx2x *bp, |
683 | struct bnx2x_virtf *vf, | |
684 | struct bnx2x_vfop_cmd *cmd, | |
685 | int qid); | |
686 | ||
954ea748 AE |
687 | int bnx2x_vfop_mcast_cmd(struct bnx2x *bp, |
688 | struct bnx2x_virtf *vf, | |
689 | struct bnx2x_vfop_cmd *cmd, | |
690 | bnx2x_mac_addr_t *mcasts, | |
691 | int mcast_num, bool drv_only); | |
692 | ||
693 | int bnx2x_vfop_rxmode_cmd(struct bnx2x *bp, | |
694 | struct bnx2x_virtf *vf, | |
695 | struct bnx2x_vfop_cmd *cmd, | |
696 | int qid, unsigned long accept_flags); | |
697 | ||
99e9d211 AE |
698 | int bnx2x_vfop_close_cmd(struct bnx2x *bp, |
699 | struct bnx2x_virtf *vf, | |
700 | struct bnx2x_vfop_cmd *cmd); | |
701 | ||
f1929b01 AE |
702 | int bnx2x_vfop_release_cmd(struct bnx2x *bp, |
703 | struct bnx2x_virtf *vf, | |
704 | struct bnx2x_vfop_cmd *cmd); | |
705 | ||
b9871bcf AE |
706 | int bnx2x_vfop_rss_cmd(struct bnx2x *bp, |
707 | struct bnx2x_virtf *vf, | |
708 | struct bnx2x_vfop_cmd *cmd); | |
709 | ||
f1929b01 AE |
710 | /* VF release ~ VF close + VF release-resources |
711 | * | |
712 | * Release is the ultimate SW shutdown and is called whenever an | |
713 | * irrecoverable error is encountered. | |
714 | */ | |
715 | void bnx2x_vf_release(struct bnx2x *bp, struct bnx2x_virtf *vf, bool block); | |
290ca2bb | 716 | int bnx2x_vf_idx_by_abs_fid(struct bnx2x *bp, u16 abs_vfid); |
8ca5e17e | 717 | u8 bnx2x_vf_max_queue_cnt(struct bnx2x *bp, struct bnx2x_virtf *vf); |
d16132ce AE |
718 | |
719 | /* FLR routines */ | |
720 | ||
b56e9670 AE |
721 | /* VF FLR helpers */ |
722 | int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid); | |
723 | void bnx2x_vf_enable_access(struct bnx2x *bp, u8 abs_vfid); | |
d16132ce AE |
724 | |
725 | /* Handles an FLR (or VF_DISABLE) notification form the MCP */ | |
726 | void bnx2x_vf_handle_flr_event(struct bnx2x *bp); | |
727 | ||
be1f1ffa AE |
728 | void bnx2x_add_tlv(struct bnx2x *bp, void *tlvs_list, u16 offset, u16 type, |
729 | u16 length); | |
730 | void bnx2x_vfpf_prep(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv, | |
731 | u16 type, u16 length); | |
1d6f3cd8 | 732 | void bnx2x_vfpf_finalize(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv); |
be1f1ffa | 733 | void bnx2x_dp_tlv_list(struct bnx2x *bp, void *tlvs_list); |
fd1fc79d AE |
734 | |
735 | bool bnx2x_tlv_supported(u16 tlvtype); | |
736 | ||
abc5a021 AE |
737 | u32 bnx2x_crc_vf_bulletin(struct bnx2x *bp, |
738 | struct pf_vf_bulletin_content *bulletin); | |
739 | int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf); | |
740 | ||
abc5a021 AE |
741 | enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp); |
742 | ||
6411280a AE |
743 | /* VF side vfpf channel functions */ |
744 | int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count); | |
745 | int bnx2x_vfpf_release(struct bnx2x *bp); | |
746 | int bnx2x_vfpf_release(struct bnx2x *bp); | |
747 | int bnx2x_vfpf_init(struct bnx2x *bp); | |
748 | void bnx2x_vfpf_close_vf(struct bnx2x *bp); | |
749 | int bnx2x_vfpf_setup_q(struct bnx2x *bp, int fp_idx); | |
750 | int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx); | |
f8f4f61a | 751 | int bnx2x_vfpf_config_mac(struct bnx2x *bp, u8 *addr, u8 vf_qid, bool set); |
6411280a AE |
752 | int bnx2x_vfpf_set_mcast(struct net_device *dev); |
753 | int bnx2x_vfpf_storm_rx_mode(struct bnx2x *bp); | |
754 | ||
755 | static inline void bnx2x_vf_fill_fw_str(struct bnx2x *bp, char *buf, | |
756 | size_t buf_len) | |
757 | { | |
758 | strlcpy(buf, bp->acquire_resp.pfdev_info.fw_ver, buf_len); | |
759 | } | |
760 | ||
761 | static inline int bnx2x_vf_ustorm_prods_offset(struct bnx2x *bp, | |
762 | struct bnx2x_fastpath *fp) | |
763 | { | |
764 | return PXP_VF_ADDR_USDM_QUEUES_START + | |
765 | bp->acquire_resp.resc.hw_qid[fp->index] * | |
766 | sizeof(struct ustorm_queue_zone_data); | |
767 | } | |
768 | ||
769 | enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp); | |
37173488 | 770 | void bnx2x_timer_sriov(struct bnx2x *bp); |
1d6f3cd8 | 771 | void __iomem *bnx2x_vf_doorbells(struct bnx2x *bp); |
6411280a | 772 | int bnx2x_vf_pci_alloc(struct bnx2x *bp); |
3c76feff AE |
773 | int bnx2x_enable_sriov(struct bnx2x *bp); |
774 | void bnx2x_disable_sriov(struct bnx2x *bp); | |
6411280a AE |
775 | static inline int bnx2x_vf_headroom(struct bnx2x *bp) |
776 | { | |
b9871bcf | 777 | return bp->vfdb->sriov.nr_virtfn * BNX2X_CIDS_PER_VF; |
6411280a | 778 | } |
3ec9f9ca | 779 | void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp); |
3c76feff | 780 | int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs); |
78c3bcc5 | 781 | void bnx2x_iov_channel_down(struct bnx2x *bp); |
3c76feff | 782 | int bnx2x_open_epilog(struct bnx2x *bp); |
6411280a AE |
783 | |
784 | #else /* CONFIG_BNX2X_SRIOV */ | |
785 | ||
786 | static inline void bnx2x_iov_set_queue_sp_obj(struct bnx2x *bp, int vf_cid, | |
787 | struct bnx2x_queue_sp_obj **q_obj) {} | |
788 | static inline void bnx2x_iov_sp_event(struct bnx2x *bp, int vf_cid, | |
789 | bool queue_work) {} | |
790 | static inline void bnx2x_vf_handle_flr_event(struct bnx2x *bp) {} | |
791 | static inline int bnx2x_iov_eq_sp_event(struct bnx2x *bp, | |
792 | union event_ring_elem *elem) {return 1; } | |
793 | static inline void bnx2x_iov_sp_task(struct bnx2x *bp) {} | |
794 | static inline void bnx2x_vf_mbx(struct bnx2x *bp, | |
795 | struct vf_pf_event_data *vfpf_event) {} | |
796 | static inline int bnx2x_iov_init_ilt(struct bnx2x *bp, u16 line) {return line; } | |
797 | static inline void bnx2x_iov_init_dq(struct bnx2x *bp) {} | |
798 | static inline int bnx2x_iov_alloc_mem(struct bnx2x *bp) {return 0; } | |
580d9d08 | 799 | static inline void bnx2x_iov_free_mem(struct bnx2x *bp) {} |
6411280a AE |
800 | static inline int bnx2x_iov_chip_cleanup(struct bnx2x *bp) {return 0; } |
801 | static inline void bnx2x_iov_init_dmae(struct bnx2x *bp) {} | |
802 | static inline int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, | |
803 | int num_vfs_param) {return 0; } | |
804 | static inline void bnx2x_iov_remove_one(struct bnx2x *bp) {} | |
3c76feff AE |
805 | static inline int bnx2x_enable_sriov(struct bnx2x *bp) {return 0; } |
806 | static inline void bnx2x_disable_sriov(struct bnx2x *bp) {} | |
6411280a AE |
807 | static inline int bnx2x_vfpf_acquire(struct bnx2x *bp, |
808 | u8 tx_count, u8 rx_count) {return 0; } | |
809 | static inline int bnx2x_vfpf_release(struct bnx2x *bp) {return 0; } | |
810 | static inline int bnx2x_vfpf_init(struct bnx2x *bp) {return 0; } | |
811 | static inline void bnx2x_vfpf_close_vf(struct bnx2x *bp) {} | |
812 | static inline int bnx2x_vfpf_setup_q(struct bnx2x *bp, int fp_idx) {return 0; } | |
813 | static inline int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx) {return 0; } | |
f8f4f61a DK |
814 | static inline int bnx2x_vfpf_config_mac(struct bnx2x *bp, u8 *addr, |
815 | u8 vf_qid, bool set) {return 0; } | |
6411280a AE |
816 | static inline int bnx2x_vfpf_set_mcast(struct net_device *dev) {return 0; } |
817 | static inline int bnx2x_vfpf_storm_rx_mode(struct bnx2x *bp) {return 0; } | |
818 | static inline int bnx2x_iov_nic_init(struct bnx2x *bp) {return 0; } | |
819 | static inline int bnx2x_vf_headroom(struct bnx2x *bp) {return 0; } | |
820 | static inline void bnx2x_iov_adjust_stats_req(struct bnx2x *bp) {} | |
821 | static inline void bnx2x_vf_fill_fw_str(struct bnx2x *bp, char *buf, | |
822 | size_t buf_len) {} | |
823 | static inline int bnx2x_vf_ustorm_prods_offset(struct bnx2x *bp, | |
824 | struct bnx2x_fastpath *fp) {return 0; } | |
825 | static inline enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp) | |
826 | { | |
827 | return PFVF_BULLETIN_UNCHANGED; | |
828 | } | |
37173488 | 829 | static inline void bnx2x_timer_sriov(struct bnx2x *bp) {} |
6411280a | 830 | |
1d6f3cd8 DK |
831 | static inline void __iomem *bnx2x_vf_doorbells(struct bnx2x *bp) |
832 | { | |
833 | return NULL; | |
834 | } | |
835 | ||
6411280a | 836 | static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; } |
3ec9f9ca | 837 | static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {} |
3c76feff | 838 | static inline int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs) {return 0; } |
78c3bcc5 | 839 | static inline void bnx2x_iov_channel_down(struct bnx2x *bp) {} |
3c76feff | 840 | static inline int bnx2x_open_epilog(struct bnx2x *bp) {return 0; } |
6411280a AE |
841 | |
842 | #endif /* CONFIG_BNX2X_SRIOV */ | |
1ab4434c | 843 | #endif /* bnx2x_sriov.h */ |