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