1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
4 | * Copyright (c) 2014- QLogic Corporation. |
5 | * All rights reserved |
6 | * www.qlogic.com |
7 | * |
8 | * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. |
9 | */ |
10 | |
11 | #include <linux/uaccess.h> |
12 | #include "bfad_drv.h" |
13 | #include "bfad_im.h" |
14 | #include "bfad_bsg.h" |
15 | |
16 | BFA_TRC_FILE(LDRV, BSG); |
17 | |
18 | static int |
19 | bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd) |
20 | { |
21 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
22 | unsigned long flags; |
23 | |
24 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
25 | /* If IOC is not in disabled state - return */ |
26 | if (!bfa_ioc_is_disabled(ioc: &bfad->bfa.ioc)) { |
27 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
28 | iocmd->status = BFA_STATUS_OK; |
29 | return 0; |
30 | } |
31 | |
32 | init_completion(x: &bfad->enable_comp); |
33 | bfa_iocfc_enable(bfa: &bfad->bfa); |
34 | iocmd->status = BFA_STATUS_OK; |
35 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
36 | wait_for_completion(&bfad->enable_comp); |
37 | |
38 | return 0; |
39 | } |
40 | |
41 | static int |
42 | bfad_iocmd_ioc_disable(struct bfad_s *bfad, void *cmd) |
43 | { |
44 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
45 | unsigned long flags; |
46 | |
47 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
48 | if (bfa_ioc_is_disabled(ioc: &bfad->bfa.ioc)) { |
49 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
50 | iocmd->status = BFA_STATUS_OK; |
51 | return 0; |
52 | } |
53 | |
54 | if (bfad->disable_active) { |
55 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
56 | return -EBUSY; |
57 | } |
58 | |
59 | bfad->disable_active = BFA_TRUE; |
60 | init_completion(x: &bfad->disable_comp); |
61 | bfa_iocfc_disable(bfa: &bfad->bfa); |
62 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
63 | |
64 | wait_for_completion(&bfad->disable_comp); |
65 | bfad->disable_active = BFA_FALSE; |
66 | iocmd->status = BFA_STATUS_OK; |
67 | |
68 | return 0; |
69 | } |
70 | |
71 | static int |
72 | bfad_iocmd_ioc_get_info(struct bfad_s *bfad, void *cmd) |
73 | { |
74 | int i; |
75 | struct bfa_bsg_ioc_info_s *iocmd = (struct bfa_bsg_ioc_info_s *)cmd; |
76 | struct bfad_im_port_s *im_port; |
77 | struct bfa_port_attr_s pattr; |
78 | unsigned long flags; |
79 | |
80 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
81 | bfa_fcport_get_attr(bfa: &bfad->bfa, attr: &pattr); |
82 | iocmd->nwwn = pattr.nwwn; |
83 | iocmd->pwwn = pattr.pwwn; |
84 | iocmd->ioc_type = bfa_get_type(&bfad->bfa); |
85 | iocmd->mac = bfa_get_mac(&bfad->bfa); |
86 | iocmd->factory_mac = bfa_get_mfg_mac(&bfad->bfa); |
87 | bfa_get_adapter_serial_num(&bfad->bfa, iocmd->serialnum); |
88 | iocmd->factorynwwn = pattr.factorynwwn; |
89 | iocmd->factorypwwn = pattr.factorypwwn; |
90 | iocmd->bfad_num = bfad->inst_no; |
91 | im_port = bfad->pport.im_port; |
92 | iocmd->host = im_port->shost->host_no; |
93 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
94 | |
95 | strcpy(p: iocmd->name, q: bfad->adapter_name); |
96 | strcpy(p: iocmd->port_name, q: bfad->port_name); |
97 | strcpy(p: iocmd->hwpath, q: bfad->pci_name); |
98 | |
99 | /* set adapter hw path */ |
100 | strcpy(p: iocmd->adapter_hwpath, q: bfad->pci_name); |
101 | for (i = 0; iocmd->adapter_hwpath[i] != ':' && i < BFA_STRING_32; i++) |
102 | ; |
103 | for (; iocmd->adapter_hwpath[++i] != ':' && i < BFA_STRING_32; ) |
104 | ; |
105 | iocmd->adapter_hwpath[i] = '\0'; |
106 | iocmd->status = BFA_STATUS_OK; |
107 | return 0; |
108 | } |
109 | |
110 | static int |
111 | bfad_iocmd_ioc_get_attr(struct bfad_s *bfad, void *cmd) |
112 | { |
113 | struct bfa_bsg_ioc_attr_s *iocmd = (struct bfa_bsg_ioc_attr_s *)cmd; |
114 | unsigned long flags; |
115 | |
116 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
117 | bfa_ioc_get_attr(ioc: &bfad->bfa.ioc, ioc_attr: &iocmd->ioc_attr); |
118 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
119 | |
120 | /* fill in driver attr info */ |
121 | strcpy(p: iocmd->ioc_attr.driver_attr.driver, BFAD_DRIVER_NAME); |
122 | strscpy(p: iocmd->ioc_attr.driver_attr.driver_ver, |
123 | BFAD_DRIVER_VERSION, BFA_VERSION_LEN); |
124 | strcpy(p: iocmd->ioc_attr.driver_attr.fw_ver, |
125 | q: iocmd->ioc_attr.adapter_attr.fw_ver); |
126 | strcpy(p: iocmd->ioc_attr.driver_attr.bios_ver, |
127 | q: iocmd->ioc_attr.adapter_attr.optrom_ver); |
128 | |
129 | /* copy chip rev info first otherwise it will be overwritten */ |
130 | memcpy(bfad->pci_attr.chip_rev, iocmd->ioc_attr.pci_attr.chip_rev, |
131 | sizeof(bfad->pci_attr.chip_rev)); |
132 | memcpy(&iocmd->ioc_attr.pci_attr, &bfad->pci_attr, |
133 | sizeof(struct bfa_ioc_pci_attr_s)); |
134 | |
135 | iocmd->status = BFA_STATUS_OK; |
136 | return 0; |
137 | } |
138 | |
139 | static int |
140 | bfad_iocmd_ioc_get_stats(struct bfad_s *bfad, void *cmd) |
141 | { |
142 | struct bfa_bsg_ioc_stats_s *iocmd = (struct bfa_bsg_ioc_stats_s *)cmd; |
143 | |
144 | bfa_ioc_get_stats(&bfad->bfa, &iocmd->ioc_stats); |
145 | iocmd->status = BFA_STATUS_OK; |
146 | return 0; |
147 | } |
148 | |
149 | static int |
150 | bfad_iocmd_ioc_get_fwstats(struct bfad_s *bfad, void *cmd, |
151 | unsigned int payload_len) |
152 | { |
153 | struct bfa_bsg_ioc_fwstats_s *iocmd = |
154 | (struct bfa_bsg_ioc_fwstats_s *)cmd; |
155 | void *iocmd_bufptr; |
156 | unsigned long flags; |
157 | |
158 | if (bfad_chk_iocmd_sz(payload_len, |
159 | sizeof(struct bfa_bsg_ioc_fwstats_s), |
160 | sizeof(struct bfa_fw_stats_s)) != BFA_STATUS_OK) { |
161 | iocmd->status = BFA_STATUS_VERSION_FAIL; |
162 | goto out; |
163 | } |
164 | |
165 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_ioc_fwstats_s); |
166 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
167 | iocmd->status = bfa_ioc_fw_stats_get(ioc: &bfad->bfa.ioc, stats: iocmd_bufptr); |
168 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
169 | |
170 | if (iocmd->status != BFA_STATUS_OK) { |
171 | bfa_trc(bfad, iocmd->status); |
172 | goto out; |
173 | } |
174 | out: |
175 | bfa_trc(bfad, 0x6666); |
176 | return 0; |
177 | } |
178 | |
179 | static int |
180 | bfad_iocmd_ioc_reset_stats(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) |
181 | { |
182 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
183 | unsigned long flags; |
184 | |
185 | if (v_cmd == IOCMD_IOC_RESET_STATS) { |
186 | bfa_ioc_clear_stats(&bfad->bfa); |
187 | iocmd->status = BFA_STATUS_OK; |
188 | } else if (v_cmd == IOCMD_IOC_RESET_FWSTATS) { |
189 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
190 | iocmd->status = bfa_ioc_fw_stats_clear(ioc: &bfad->bfa.ioc); |
191 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
192 | } |
193 | |
194 | return 0; |
195 | } |
196 | |
197 | static int |
198 | bfad_iocmd_ioc_set_name(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) |
199 | { |
200 | struct bfa_bsg_ioc_name_s *iocmd = (struct bfa_bsg_ioc_name_s *) cmd; |
201 | |
202 | if (v_cmd == IOCMD_IOC_SET_ADAPTER_NAME) |
203 | strcpy(p: bfad->adapter_name, q: iocmd->name); |
204 | else if (v_cmd == IOCMD_IOC_SET_PORT_NAME) |
205 | strcpy(p: bfad->port_name, q: iocmd->name); |
206 | |
207 | iocmd->status = BFA_STATUS_OK; |
208 | return 0; |
209 | } |
210 | |
211 | static int |
212 | bfad_iocmd_iocfc_get_attr(struct bfad_s *bfad, void *cmd) |
213 | { |
214 | struct bfa_bsg_iocfc_attr_s *iocmd = (struct bfa_bsg_iocfc_attr_s *)cmd; |
215 | |
216 | iocmd->status = BFA_STATUS_OK; |
217 | bfa_iocfc_get_attr(bfa: &bfad->bfa, attr: &iocmd->iocfc_attr); |
218 | |
219 | return 0; |
220 | } |
221 | |
222 | static int |
223 | bfad_iocmd_ioc_fw_sig_inv(struct bfad_s *bfad, void *cmd) |
224 | { |
225 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
226 | unsigned long flags; |
227 | |
228 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
229 | iocmd->status = bfa_ioc_fwsig_invalidate(ioc: &bfad->bfa.ioc); |
230 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
231 | return 0; |
232 | } |
233 | |
234 | static int |
235 | bfad_iocmd_iocfc_set_intr(struct bfad_s *bfad, void *cmd) |
236 | { |
237 | struct bfa_bsg_iocfc_intr_s *iocmd = (struct bfa_bsg_iocfc_intr_s *)cmd; |
238 | unsigned long flags; |
239 | |
240 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
241 | iocmd->status = bfa_iocfc_israttr_set(bfa: &bfad->bfa, attr: &iocmd->attr); |
242 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
243 | |
244 | return 0; |
245 | } |
246 | |
247 | static int |
248 | bfad_iocmd_port_enable(struct bfad_s *bfad, void *cmd) |
249 | { |
250 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
251 | struct bfad_hal_comp fcomp; |
252 | unsigned long flags; |
253 | |
254 | init_completion(x: &fcomp.comp); |
255 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
256 | iocmd->status = bfa_port_enable(port: &bfad->bfa.modules.port, |
257 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
258 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
259 | if (iocmd->status != BFA_STATUS_OK) { |
260 | bfa_trc(bfad, iocmd->status); |
261 | return 0; |
262 | } |
263 | wait_for_completion(&fcomp.comp); |
264 | iocmd->status = fcomp.status; |
265 | return 0; |
266 | } |
267 | |
268 | static int |
269 | bfad_iocmd_port_disable(struct bfad_s *bfad, void *cmd) |
270 | { |
271 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
272 | struct bfad_hal_comp fcomp; |
273 | unsigned long flags; |
274 | |
275 | init_completion(x: &fcomp.comp); |
276 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
277 | iocmd->status = bfa_port_disable(port: &bfad->bfa.modules.port, |
278 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
279 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
280 | |
281 | if (iocmd->status != BFA_STATUS_OK) { |
282 | bfa_trc(bfad, iocmd->status); |
283 | return 0; |
284 | } |
285 | wait_for_completion(&fcomp.comp); |
286 | iocmd->status = fcomp.status; |
287 | return 0; |
288 | } |
289 | |
290 | static int |
291 | bfad_iocmd_port_get_attr(struct bfad_s *bfad, void *cmd) |
292 | { |
293 | struct bfa_bsg_port_attr_s *iocmd = (struct bfa_bsg_port_attr_s *)cmd; |
294 | struct bfa_lport_attr_s port_attr; |
295 | unsigned long flags; |
296 | |
297 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
298 | bfa_fcport_get_attr(bfa: &bfad->bfa, attr: &iocmd->attr); |
299 | bfa_fcs_lport_get_attr(port: &bfad->bfa_fcs.fabric.bport, port_attr: &port_attr); |
300 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
301 | |
302 | if (iocmd->attr.topology != BFA_PORT_TOPOLOGY_NONE) |
303 | iocmd->attr.pid = port_attr.pid; |
304 | else |
305 | iocmd->attr.pid = 0; |
306 | |
307 | iocmd->attr.port_type = port_attr.port_type; |
308 | iocmd->attr.loopback = port_attr.loopback; |
309 | iocmd->attr.authfail = port_attr.authfail; |
310 | strscpy(p: iocmd->attr.port_symname.symname, |
311 | q: port_attr.port_cfg.sym_name.symname, |
312 | size: sizeof(iocmd->attr.port_symname.symname)); |
313 | |
314 | iocmd->status = BFA_STATUS_OK; |
315 | return 0; |
316 | } |
317 | |
318 | static int |
319 | bfad_iocmd_port_get_stats(struct bfad_s *bfad, void *cmd, |
320 | unsigned int payload_len) |
321 | { |
322 | struct bfa_bsg_port_stats_s *iocmd = (struct bfa_bsg_port_stats_s *)cmd; |
323 | struct bfad_hal_comp fcomp; |
324 | void *iocmd_bufptr; |
325 | unsigned long flags; |
326 | |
327 | if (bfad_chk_iocmd_sz(payload_len, |
328 | sizeof(struct bfa_bsg_port_stats_s), |
329 | sizeof(union bfa_port_stats_u)) != BFA_STATUS_OK) { |
330 | iocmd->status = BFA_STATUS_VERSION_FAIL; |
331 | return 0; |
332 | } |
333 | |
334 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_port_stats_s); |
335 | |
336 | init_completion(x: &fcomp.comp); |
337 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
338 | iocmd->status = bfa_port_get_stats(port: &bfad->bfa.modules.port, |
339 | stats: iocmd_bufptr, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
340 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
341 | if (iocmd->status != BFA_STATUS_OK) { |
342 | bfa_trc(bfad, iocmd->status); |
343 | goto out; |
344 | } |
345 | |
346 | wait_for_completion(&fcomp.comp); |
347 | iocmd->status = fcomp.status; |
348 | out: |
349 | return 0; |
350 | } |
351 | |
352 | static int |
353 | bfad_iocmd_port_reset_stats(struct bfad_s *bfad, void *cmd) |
354 | { |
355 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
356 | struct bfad_hal_comp fcomp; |
357 | unsigned long flags; |
358 | |
359 | init_completion(x: &fcomp.comp); |
360 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
361 | iocmd->status = bfa_port_clear_stats(port: &bfad->bfa.modules.port, |
362 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
363 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
364 | if (iocmd->status != BFA_STATUS_OK) { |
365 | bfa_trc(bfad, iocmd->status); |
366 | return 0; |
367 | } |
368 | wait_for_completion(&fcomp.comp); |
369 | iocmd->status = fcomp.status; |
370 | return 0; |
371 | } |
372 | |
373 | static int |
374 | bfad_iocmd_set_port_cfg(struct bfad_s *bfad, void *iocmd, unsigned int v_cmd) |
375 | { |
376 | struct bfa_bsg_port_cfg_s *cmd = (struct bfa_bsg_port_cfg_s *)iocmd; |
377 | unsigned long flags; |
378 | |
379 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
380 | if (v_cmd == IOCMD_PORT_CFG_TOPO) |
381 | cmd->status = bfa_fcport_cfg_topology(bfa: &bfad->bfa, topo: cmd->param); |
382 | else if (v_cmd == IOCMD_PORT_CFG_SPEED) |
383 | cmd->status = bfa_fcport_cfg_speed(bfa: &bfad->bfa, speed: cmd->param); |
384 | else if (v_cmd == IOCMD_PORT_CFG_ALPA) |
385 | cmd->status = bfa_fcport_cfg_hardalpa(bfa: &bfad->bfa, alpa: cmd->param); |
386 | else if (v_cmd == IOCMD_PORT_CLR_ALPA) |
387 | cmd->status = bfa_fcport_clr_hardalpa(bfa: &bfad->bfa); |
388 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
389 | |
390 | return 0; |
391 | } |
392 | |
393 | static int |
394 | bfad_iocmd_port_cfg_maxfrsize(struct bfad_s *bfad, void *cmd) |
395 | { |
396 | struct bfa_bsg_port_cfg_maxfrsize_s *iocmd = |
397 | (struct bfa_bsg_port_cfg_maxfrsize_s *)cmd; |
398 | unsigned long flags; |
399 | |
400 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
401 | iocmd->status = bfa_fcport_cfg_maxfrsize(bfa: &bfad->bfa, maxsize: iocmd->maxfrsize); |
402 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
403 | |
404 | return 0; |
405 | } |
406 | |
407 | static int |
408 | bfad_iocmd_port_cfg_bbcr(struct bfad_s *bfad, unsigned int cmd, void *pcmd) |
409 | { |
410 | struct bfa_bsg_bbcr_enable_s *iocmd = |
411 | (struct bfa_bsg_bbcr_enable_s *)pcmd; |
412 | unsigned long flags; |
413 | int rc; |
414 | |
415 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
416 | if (cmd == IOCMD_PORT_BBCR_ENABLE) |
417 | rc = bfa_fcport_cfg_bbcr(bfa: &bfad->bfa, on_off: BFA_TRUE, bb_scn: iocmd->bb_scn); |
418 | else if (cmd == IOCMD_PORT_BBCR_DISABLE) |
419 | rc = bfa_fcport_cfg_bbcr(bfa: &bfad->bfa, on_off: BFA_FALSE, bb_scn: 0); |
420 | else { |
421 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
422 | return -EINVAL; |
423 | } |
424 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
425 | |
426 | iocmd->status = rc; |
427 | return 0; |
428 | } |
429 | |
430 | static int |
431 | bfad_iocmd_port_get_bbcr_attr(struct bfad_s *bfad, void *pcmd) |
432 | { |
433 | struct bfa_bsg_bbcr_attr_s *iocmd = (struct bfa_bsg_bbcr_attr_s *) pcmd; |
434 | unsigned long flags; |
435 | |
436 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
437 | iocmd->status = |
438 | bfa_fcport_get_bbcr_attr(bfa: &bfad->bfa, bbcr_attr: &iocmd->attr); |
439 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
440 | |
441 | return 0; |
442 | } |
443 | |
444 | |
445 | static int |
446 | bfad_iocmd_lport_get_attr(struct bfad_s *bfad, void *cmd) |
447 | { |
448 | struct bfa_fcs_lport_s *fcs_port; |
449 | struct bfa_bsg_lport_attr_s *iocmd = (struct bfa_bsg_lport_attr_s *)cmd; |
450 | unsigned long flags; |
451 | |
452 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
453 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
454 | vf_id: iocmd->vf_id, lpwwn: iocmd->pwwn); |
455 | if (fcs_port == NULL) { |
456 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
457 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
458 | goto out; |
459 | } |
460 | |
461 | bfa_fcs_lport_get_attr(port: fcs_port, port_attr: &iocmd->port_attr); |
462 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
463 | iocmd->status = BFA_STATUS_OK; |
464 | out: |
465 | return 0; |
466 | } |
467 | |
468 | static int |
469 | bfad_iocmd_lport_get_stats(struct bfad_s *bfad, void *cmd) |
470 | { |
471 | struct bfa_fcs_lport_s *fcs_port; |
472 | struct bfa_bsg_lport_stats_s *iocmd = |
473 | (struct bfa_bsg_lport_stats_s *)cmd; |
474 | unsigned long flags; |
475 | |
476 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
477 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
478 | vf_id: iocmd->vf_id, lpwwn: iocmd->pwwn); |
479 | if (fcs_port == NULL) { |
480 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
481 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
482 | goto out; |
483 | } |
484 | |
485 | bfa_fcs_lport_get_stats(fcs_port, port_stats: &iocmd->port_stats); |
486 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
487 | iocmd->status = BFA_STATUS_OK; |
488 | out: |
489 | return 0; |
490 | } |
491 | |
492 | static int |
493 | bfad_iocmd_lport_reset_stats(struct bfad_s *bfad, void *cmd) |
494 | { |
495 | struct bfa_fcs_lport_s *fcs_port; |
496 | struct bfa_bsg_reset_stats_s *iocmd = |
497 | (struct bfa_bsg_reset_stats_s *)cmd; |
498 | struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa); |
499 | struct list_head *qe, *qen; |
500 | struct bfa_itnim_s *itnim; |
501 | unsigned long flags; |
502 | |
503 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
504 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
505 | vf_id: iocmd->vf_id, lpwwn: iocmd->vpwwn); |
506 | if (fcs_port == NULL) { |
507 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
508 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
509 | goto out; |
510 | } |
511 | |
512 | bfa_fcs_lport_clear_stats(fcs_port); |
513 | /* clear IO stats from all active itnims */ |
514 | list_for_each_safe(qe, qen, &fcpim->itnim_q) { |
515 | itnim = (struct bfa_itnim_s *) qe; |
516 | if (itnim->rport->rport_info.lp_tag != fcs_port->lp_tag) |
517 | continue; |
518 | bfa_itnim_clear_stats(itnim); |
519 | } |
520 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
521 | iocmd->status = BFA_STATUS_OK; |
522 | out: |
523 | return 0; |
524 | } |
525 | |
526 | static int |
527 | bfad_iocmd_lport_get_iostats(struct bfad_s *bfad, void *cmd) |
528 | { |
529 | struct bfa_fcs_lport_s *fcs_port; |
530 | struct bfa_bsg_lport_iostats_s *iocmd = |
531 | (struct bfa_bsg_lport_iostats_s *)cmd; |
532 | unsigned long flags; |
533 | |
534 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
535 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
536 | vf_id: iocmd->vf_id, lpwwn: iocmd->pwwn); |
537 | if (fcs_port == NULL) { |
538 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
539 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
540 | goto out; |
541 | } |
542 | |
543 | bfa_fcpim_port_iostats(bfa: &bfad->bfa, stats: &iocmd->iostats, |
544 | lp_tag: fcs_port->lp_tag); |
545 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
546 | iocmd->status = BFA_STATUS_OK; |
547 | out: |
548 | return 0; |
549 | } |
550 | |
551 | static int |
552 | bfad_iocmd_lport_get_rports(struct bfad_s *bfad, void *cmd, |
553 | unsigned int payload_len) |
554 | { |
555 | struct bfa_bsg_lport_get_rports_s *iocmd = |
556 | (struct bfa_bsg_lport_get_rports_s *)cmd; |
557 | struct bfa_fcs_lport_s *fcs_port; |
558 | unsigned long flags; |
559 | void *iocmd_bufptr; |
560 | |
561 | if (iocmd->nrports == 0) |
562 | return -EINVAL; |
563 | |
564 | if (bfad_chk_iocmd_sz(payload_len, |
565 | sizeof(struct bfa_bsg_lport_get_rports_s), |
566 | sizeof(struct bfa_rport_qualifier_s) * iocmd->nrports) |
567 | != BFA_STATUS_OK) { |
568 | iocmd->status = BFA_STATUS_VERSION_FAIL; |
569 | return 0; |
570 | } |
571 | |
572 | iocmd_bufptr = (char *)iocmd + |
573 | sizeof(struct bfa_bsg_lport_get_rports_s); |
574 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
575 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
576 | vf_id: iocmd->vf_id, lpwwn: iocmd->pwwn); |
577 | if (fcs_port == NULL) { |
578 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
579 | bfa_trc(bfad, 0); |
580 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
581 | goto out; |
582 | } |
583 | |
584 | bfa_fcs_lport_get_rport_quals(port: fcs_port, |
585 | rport: (struct bfa_rport_qualifier_s *)iocmd_bufptr, |
586 | nrports: &iocmd->nrports); |
587 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
588 | iocmd->status = BFA_STATUS_OK; |
589 | out: |
590 | return 0; |
591 | } |
592 | |
593 | static int |
594 | bfad_iocmd_rport_get_attr(struct bfad_s *bfad, void *cmd) |
595 | { |
596 | struct bfa_bsg_rport_attr_s *iocmd = (struct bfa_bsg_rport_attr_s *)cmd; |
597 | struct bfa_fcs_lport_s *fcs_port; |
598 | struct bfa_fcs_rport_s *fcs_rport; |
599 | unsigned long flags; |
600 | |
601 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
602 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
603 | vf_id: iocmd->vf_id, lpwwn: iocmd->pwwn); |
604 | if (fcs_port == NULL) { |
605 | bfa_trc(bfad, 0); |
606 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
607 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
608 | goto out; |
609 | } |
610 | |
611 | if (iocmd->pid) |
612 | fcs_rport = bfa_fcs_lport_get_rport_by_qualifier(port: fcs_port, |
613 | pwwn: iocmd->rpwwn, pid: iocmd->pid); |
614 | else |
615 | fcs_rport = bfa_fcs_rport_lookup(port: fcs_port, rpwwn: iocmd->rpwwn); |
616 | if (fcs_rport == NULL) { |
617 | bfa_trc(bfad, 0); |
618 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
619 | iocmd->status = BFA_STATUS_UNKNOWN_RWWN; |
620 | goto out; |
621 | } |
622 | |
623 | bfa_fcs_rport_get_attr(rport: fcs_rport, attr: &iocmd->attr); |
624 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
625 | iocmd->status = BFA_STATUS_OK; |
626 | out: |
627 | return 0; |
628 | } |
629 | |
630 | static int |
631 | bfad_iocmd_rport_get_addr(struct bfad_s *bfad, void *cmd) |
632 | { |
633 | struct bfa_bsg_rport_scsi_addr_s *iocmd = |
634 | (struct bfa_bsg_rport_scsi_addr_s *)cmd; |
635 | struct bfa_fcs_lport_s *fcs_port; |
636 | struct bfa_fcs_itnim_s *fcs_itnim; |
637 | struct bfad_itnim_s *drv_itnim; |
638 | unsigned long flags; |
639 | |
640 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
641 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
642 | vf_id: iocmd->vf_id, lpwwn: iocmd->pwwn); |
643 | if (fcs_port == NULL) { |
644 | bfa_trc(bfad, 0); |
645 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
646 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
647 | goto out; |
648 | } |
649 | |
650 | fcs_itnim = bfa_fcs_itnim_lookup(port: fcs_port, rpwwn: iocmd->rpwwn); |
651 | if (fcs_itnim == NULL) { |
652 | bfa_trc(bfad, 0); |
653 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
654 | iocmd->status = BFA_STATUS_UNKNOWN_RWWN; |
655 | goto out; |
656 | } |
657 | |
658 | drv_itnim = fcs_itnim->itnim_drv; |
659 | |
660 | if (drv_itnim && drv_itnim->im_port) |
661 | iocmd->host = drv_itnim->im_port->shost->host_no; |
662 | else { |
663 | bfa_trc(bfad, 0); |
664 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
665 | iocmd->status = BFA_STATUS_UNKNOWN_RWWN; |
666 | goto out; |
667 | } |
668 | |
669 | iocmd->target = drv_itnim->scsi_tgt_id; |
670 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
671 | |
672 | iocmd->bus = 0; |
673 | iocmd->lun = 0; |
674 | iocmd->status = BFA_STATUS_OK; |
675 | out: |
676 | return 0; |
677 | } |
678 | |
679 | static int |
680 | bfad_iocmd_rport_get_stats(struct bfad_s *bfad, void *cmd) |
681 | { |
682 | struct bfa_bsg_rport_stats_s *iocmd = |
683 | (struct bfa_bsg_rport_stats_s *)cmd; |
684 | struct bfa_fcs_lport_s *fcs_port; |
685 | struct bfa_fcs_rport_s *fcs_rport; |
686 | unsigned long flags; |
687 | |
688 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
689 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
690 | vf_id: iocmd->vf_id, lpwwn: iocmd->pwwn); |
691 | if (fcs_port == NULL) { |
692 | bfa_trc(bfad, 0); |
693 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
694 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
695 | goto out; |
696 | } |
697 | |
698 | fcs_rport = bfa_fcs_rport_lookup(port: fcs_port, rpwwn: iocmd->rpwwn); |
699 | if (fcs_rport == NULL) { |
700 | bfa_trc(bfad, 0); |
701 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
702 | iocmd->status = BFA_STATUS_UNKNOWN_RWWN; |
703 | goto out; |
704 | } |
705 | |
706 | memcpy((void *)&iocmd->stats, (void *)&fcs_rport->stats, |
707 | sizeof(struct bfa_rport_stats_s)); |
708 | if (bfa_fcs_rport_get_halrport(rport: fcs_rport)) { |
709 | memcpy((void *)&iocmd->stats.hal_stats, |
710 | (void *)&(bfa_fcs_rport_get_halrport(fcs_rport)->stats), |
711 | sizeof(struct bfa_rport_hal_stats_s)); |
712 | } |
713 | |
714 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
715 | iocmd->status = BFA_STATUS_OK; |
716 | out: |
717 | return 0; |
718 | } |
719 | |
720 | static int |
721 | bfad_iocmd_rport_clr_stats(struct bfad_s *bfad, void *cmd) |
722 | { |
723 | struct bfa_bsg_rport_reset_stats_s *iocmd = |
724 | (struct bfa_bsg_rport_reset_stats_s *)cmd; |
725 | struct bfa_fcs_lport_s *fcs_port; |
726 | struct bfa_fcs_rport_s *fcs_rport; |
727 | struct bfa_rport_s *rport; |
728 | unsigned long flags; |
729 | |
730 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
731 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
732 | vf_id: iocmd->vf_id, lpwwn: iocmd->pwwn); |
733 | if (fcs_port == NULL) { |
734 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
735 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
736 | goto out; |
737 | } |
738 | |
739 | fcs_rport = bfa_fcs_rport_lookup(port: fcs_port, rpwwn: iocmd->rpwwn); |
740 | if (fcs_rport == NULL) { |
741 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
742 | iocmd->status = BFA_STATUS_UNKNOWN_RWWN; |
743 | goto out; |
744 | } |
745 | |
746 | memset((char *)&fcs_rport->stats, 0, sizeof(struct bfa_rport_stats_s)); |
747 | rport = bfa_fcs_rport_get_halrport(rport: fcs_rport); |
748 | if (rport) |
749 | memset(&rport->stats, 0, sizeof(rport->stats)); |
750 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
751 | iocmd->status = BFA_STATUS_OK; |
752 | out: |
753 | return 0; |
754 | } |
755 | |
756 | static int |
757 | bfad_iocmd_rport_set_speed(struct bfad_s *bfad, void *cmd) |
758 | { |
759 | struct bfa_bsg_rport_set_speed_s *iocmd = |
760 | (struct bfa_bsg_rport_set_speed_s *)cmd; |
761 | struct bfa_fcs_lport_s *fcs_port; |
762 | struct bfa_fcs_rport_s *fcs_rport; |
763 | unsigned long flags; |
764 | |
765 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
766 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
767 | vf_id: iocmd->vf_id, lpwwn: iocmd->pwwn); |
768 | if (fcs_port == NULL) { |
769 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
770 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
771 | goto out; |
772 | } |
773 | |
774 | fcs_rport = bfa_fcs_rport_lookup(port: fcs_port, rpwwn: iocmd->rpwwn); |
775 | if (fcs_rport == NULL) { |
776 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
777 | iocmd->status = BFA_STATUS_UNKNOWN_RWWN; |
778 | goto out; |
779 | } |
780 | |
781 | fcs_rport->rpf.assigned_speed = iocmd->speed; |
782 | /* Set this speed in f/w only if the RPSC speed is not available */ |
783 | if (fcs_rport->rpf.rpsc_speed == BFA_PORT_SPEED_UNKNOWN) |
784 | if (fcs_rport->bfa_rport) |
785 | bfa_rport_speed(rport: fcs_rport->bfa_rport, speed: iocmd->speed); |
786 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
787 | iocmd->status = BFA_STATUS_OK; |
788 | out: |
789 | return 0; |
790 | } |
791 | |
792 | static int |
793 | bfad_iocmd_vport_get_attr(struct bfad_s *bfad, void *cmd) |
794 | { |
795 | struct bfa_fcs_vport_s *fcs_vport; |
796 | struct bfa_bsg_vport_attr_s *iocmd = (struct bfa_bsg_vport_attr_s *)cmd; |
797 | unsigned long flags; |
798 | |
799 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
800 | fcs_vport = bfa_fcs_vport_lookup(fcs: &bfad->bfa_fcs, |
801 | vf_id: iocmd->vf_id, vpwwn: iocmd->vpwwn); |
802 | if (fcs_vport == NULL) { |
803 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
804 | iocmd->status = BFA_STATUS_UNKNOWN_VWWN; |
805 | goto out; |
806 | } |
807 | |
808 | bfa_fcs_vport_get_attr(vport: fcs_vport, vport_attr: &iocmd->vport_attr); |
809 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
810 | iocmd->status = BFA_STATUS_OK; |
811 | out: |
812 | return 0; |
813 | } |
814 | |
815 | static int |
816 | bfad_iocmd_vport_get_stats(struct bfad_s *bfad, void *cmd) |
817 | { |
818 | struct bfa_fcs_vport_s *fcs_vport; |
819 | struct bfa_bsg_vport_stats_s *iocmd = |
820 | (struct bfa_bsg_vport_stats_s *)cmd; |
821 | unsigned long flags; |
822 | |
823 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
824 | fcs_vport = bfa_fcs_vport_lookup(fcs: &bfad->bfa_fcs, |
825 | vf_id: iocmd->vf_id, vpwwn: iocmd->vpwwn); |
826 | if (fcs_vport == NULL) { |
827 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
828 | iocmd->status = BFA_STATUS_UNKNOWN_VWWN; |
829 | goto out; |
830 | } |
831 | |
832 | memcpy((void *)&iocmd->vport_stats, (void *)&fcs_vport->vport_stats, |
833 | sizeof(struct bfa_vport_stats_s)); |
834 | memcpy((void *)&iocmd->vport_stats.port_stats, |
835 | (void *)&fcs_vport->lport.stats, |
836 | sizeof(struct bfa_lport_stats_s)); |
837 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
838 | iocmd->status = BFA_STATUS_OK; |
839 | out: |
840 | return 0; |
841 | } |
842 | |
843 | static int |
844 | bfad_iocmd_vport_clr_stats(struct bfad_s *bfad, void *cmd) |
845 | { |
846 | struct bfa_fcs_vport_s *fcs_vport; |
847 | struct bfa_bsg_reset_stats_s *iocmd = |
848 | (struct bfa_bsg_reset_stats_s *)cmd; |
849 | unsigned long flags; |
850 | |
851 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
852 | fcs_vport = bfa_fcs_vport_lookup(fcs: &bfad->bfa_fcs, |
853 | vf_id: iocmd->vf_id, vpwwn: iocmd->vpwwn); |
854 | if (fcs_vport == NULL) { |
855 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
856 | iocmd->status = BFA_STATUS_UNKNOWN_VWWN; |
857 | goto out; |
858 | } |
859 | |
860 | memset(&fcs_vport->vport_stats, 0, sizeof(struct bfa_vport_stats_s)); |
861 | memset(&fcs_vport->lport.stats, 0, sizeof(struct bfa_lport_stats_s)); |
862 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
863 | iocmd->status = BFA_STATUS_OK; |
864 | out: |
865 | return 0; |
866 | } |
867 | |
868 | static int |
869 | bfad_iocmd_fabric_get_lports(struct bfad_s *bfad, void *cmd, |
870 | unsigned int payload_len) |
871 | { |
872 | struct bfa_bsg_fabric_get_lports_s *iocmd = |
873 | (struct bfa_bsg_fabric_get_lports_s *)cmd; |
874 | bfa_fcs_vf_t *fcs_vf; |
875 | uint32_t nports = iocmd->nports; |
876 | unsigned long flags; |
877 | void *iocmd_bufptr; |
878 | |
879 | if (nports == 0) { |
880 | iocmd->status = BFA_STATUS_EINVAL; |
881 | goto out; |
882 | } |
883 | |
884 | if (bfad_chk_iocmd_sz(payload_len, |
885 | sizeof(struct bfa_bsg_fabric_get_lports_s), |
886 | sizeof(wwn_t) * iocmd->nports) != BFA_STATUS_OK) { |
887 | iocmd->status = BFA_STATUS_VERSION_FAIL; |
888 | goto out; |
889 | } |
890 | |
891 | iocmd_bufptr = (char *)iocmd + |
892 | sizeof(struct bfa_bsg_fabric_get_lports_s); |
893 | |
894 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
895 | fcs_vf = bfa_fcs_vf_lookup(fcs: &bfad->bfa_fcs, vf_id: iocmd->vf_id); |
896 | if (fcs_vf == NULL) { |
897 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
898 | iocmd->status = BFA_STATUS_UNKNOWN_VFID; |
899 | goto out; |
900 | } |
901 | bfa_fcs_vf_get_ports(vf: fcs_vf, vpwwn: (wwn_t *)iocmd_bufptr, nports: &nports); |
902 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
903 | |
904 | iocmd->nports = nports; |
905 | iocmd->status = BFA_STATUS_OK; |
906 | out: |
907 | return 0; |
908 | } |
909 | |
910 | static int |
911 | bfad_iocmd_qos_set_bw(struct bfad_s *bfad, void *pcmd) |
912 | { |
913 | struct bfa_bsg_qos_bw_s *iocmd = (struct bfa_bsg_qos_bw_s *)pcmd; |
914 | unsigned long flags; |
915 | |
916 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
917 | iocmd->status = bfa_fcport_set_qos_bw(bfa: &bfad->bfa, qos_bw: &iocmd->qos_bw); |
918 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
919 | |
920 | return 0; |
921 | } |
922 | |
923 | static int |
924 | bfad_iocmd_ratelim(struct bfad_s *bfad, unsigned int cmd, void *pcmd) |
925 | { |
926 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; |
927 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); |
928 | unsigned long flags; |
929 | |
930 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
931 | |
932 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
933 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
934 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; |
935 | else { |
936 | if (cmd == IOCMD_RATELIM_ENABLE) |
937 | fcport->cfg.ratelimit = BFA_TRUE; |
938 | else if (cmd == IOCMD_RATELIM_DISABLE) |
939 | fcport->cfg.ratelimit = BFA_FALSE; |
940 | |
941 | if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN) |
942 | fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS; |
943 | |
944 | iocmd->status = BFA_STATUS_OK; |
945 | } |
946 | |
947 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
948 | |
949 | return 0; |
950 | } |
951 | |
952 | static int |
953 | bfad_iocmd_ratelim_speed(struct bfad_s *bfad, unsigned int cmd, void *pcmd) |
954 | { |
955 | struct bfa_bsg_trl_speed_s *iocmd = (struct bfa_bsg_trl_speed_s *)pcmd; |
956 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); |
957 | unsigned long flags; |
958 | |
959 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
960 | |
961 | /* Auto and speeds greater than the supported speed, are invalid */ |
962 | if ((iocmd->speed == BFA_PORT_SPEED_AUTO) || |
963 | (iocmd->speed > fcport->speed_sup)) { |
964 | iocmd->status = BFA_STATUS_UNSUPP_SPEED; |
965 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
966 | return 0; |
967 | } |
968 | |
969 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
970 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
971 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; |
972 | else { |
973 | fcport->cfg.trl_def_speed = iocmd->speed; |
974 | iocmd->status = BFA_STATUS_OK; |
975 | } |
976 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
977 | |
978 | return 0; |
979 | } |
980 | |
981 | static int |
982 | bfad_iocmd_cfg_fcpim(struct bfad_s *bfad, void *cmd) |
983 | { |
984 | struct bfa_bsg_fcpim_s *iocmd = (struct bfa_bsg_fcpim_s *)cmd; |
985 | unsigned long flags; |
986 | |
987 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
988 | bfa_fcpim_path_tov_set(bfa: &bfad->bfa, path_tov: iocmd->param); |
989 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
990 | iocmd->status = BFA_STATUS_OK; |
991 | return 0; |
992 | } |
993 | |
994 | static int |
995 | bfad_iocmd_fcpim_get_modstats(struct bfad_s *bfad, void *cmd) |
996 | { |
997 | struct bfa_bsg_fcpim_modstats_s *iocmd = |
998 | (struct bfa_bsg_fcpim_modstats_s *)cmd; |
999 | struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa); |
1000 | struct list_head *qe, *qen; |
1001 | struct bfa_itnim_s *itnim; |
1002 | unsigned long flags; |
1003 | |
1004 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1005 | /* accumulate IO stats from itnim */ |
1006 | memset((void *)&iocmd->modstats, 0, sizeof(struct bfa_itnim_iostats_s)); |
1007 | list_for_each_safe(qe, qen, &fcpim->itnim_q) { |
1008 | itnim = (struct bfa_itnim_s *) qe; |
1009 | bfa_fcpim_add_stats(fcpim_stats: &iocmd->modstats, itnim_stats: &(itnim->stats)); |
1010 | } |
1011 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1012 | iocmd->status = BFA_STATUS_OK; |
1013 | return 0; |
1014 | } |
1015 | |
1016 | static int |
1017 | bfad_iocmd_fcpim_clr_modstats(struct bfad_s *bfad, void *cmd) |
1018 | { |
1019 | struct bfa_bsg_fcpim_modstatsclr_s *iocmd = |
1020 | (struct bfa_bsg_fcpim_modstatsclr_s *)cmd; |
1021 | struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa); |
1022 | struct list_head *qe, *qen; |
1023 | struct bfa_itnim_s *itnim; |
1024 | unsigned long flags; |
1025 | |
1026 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1027 | list_for_each_safe(qe, qen, &fcpim->itnim_q) { |
1028 | itnim = (struct bfa_itnim_s *) qe; |
1029 | bfa_itnim_clear_stats(itnim); |
1030 | } |
1031 | memset(&fcpim->del_itn_stats, 0, |
1032 | sizeof(struct bfa_fcpim_del_itn_stats_s)); |
1033 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1034 | iocmd->status = BFA_STATUS_OK; |
1035 | return 0; |
1036 | } |
1037 | |
1038 | static int |
1039 | bfad_iocmd_fcpim_get_del_itn_stats(struct bfad_s *bfad, void *cmd) |
1040 | { |
1041 | struct bfa_bsg_fcpim_del_itn_stats_s *iocmd = |
1042 | (struct bfa_bsg_fcpim_del_itn_stats_s *)cmd; |
1043 | struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa); |
1044 | unsigned long flags; |
1045 | |
1046 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1047 | memcpy((void *)&iocmd->modstats, (void *)&fcpim->del_itn_stats, |
1048 | sizeof(struct bfa_fcpim_del_itn_stats_s)); |
1049 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1050 | |
1051 | iocmd->status = BFA_STATUS_OK; |
1052 | return 0; |
1053 | } |
1054 | |
1055 | static int |
1056 | bfad_iocmd_itnim_get_attr(struct bfad_s *bfad, void *cmd) |
1057 | { |
1058 | struct bfa_bsg_itnim_attr_s *iocmd = (struct bfa_bsg_itnim_attr_s *)cmd; |
1059 | struct bfa_fcs_lport_s *fcs_port; |
1060 | unsigned long flags; |
1061 | |
1062 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1063 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
1064 | vf_id: iocmd->vf_id, lpwwn: iocmd->lpwwn); |
1065 | if (!fcs_port) |
1066 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
1067 | else |
1068 | iocmd->status = bfa_fcs_itnim_attr_get(port: fcs_port, |
1069 | rpwwn: iocmd->rpwwn, attr: &iocmd->attr); |
1070 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1071 | return 0; |
1072 | } |
1073 | |
1074 | static int |
1075 | bfad_iocmd_itnim_get_iostats(struct bfad_s *bfad, void *cmd) |
1076 | { |
1077 | struct bfa_bsg_itnim_iostats_s *iocmd = |
1078 | (struct bfa_bsg_itnim_iostats_s *)cmd; |
1079 | struct bfa_fcs_lport_s *fcs_port; |
1080 | struct bfa_fcs_itnim_s *itnim; |
1081 | unsigned long flags; |
1082 | |
1083 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1084 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
1085 | vf_id: iocmd->vf_id, lpwwn: iocmd->lpwwn); |
1086 | if (!fcs_port) { |
1087 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
1088 | bfa_trc(bfad, 0); |
1089 | } else { |
1090 | itnim = bfa_fcs_itnim_lookup(port: fcs_port, rpwwn: iocmd->rpwwn); |
1091 | if (itnim == NULL) |
1092 | iocmd->status = BFA_STATUS_UNKNOWN_RWWN; |
1093 | else { |
1094 | iocmd->status = BFA_STATUS_OK; |
1095 | if (bfa_fcs_itnim_get_halitn(itnim)) |
1096 | memcpy((void *)&iocmd->iostats, (void *) |
1097 | &(bfa_fcs_itnim_get_halitn(itnim)->stats), |
1098 | sizeof(struct bfa_itnim_iostats_s)); |
1099 | } |
1100 | } |
1101 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1102 | return 0; |
1103 | } |
1104 | |
1105 | static int |
1106 | bfad_iocmd_itnim_reset_stats(struct bfad_s *bfad, void *cmd) |
1107 | { |
1108 | struct bfa_bsg_rport_reset_stats_s *iocmd = |
1109 | (struct bfa_bsg_rport_reset_stats_s *)cmd; |
1110 | struct bfa_fcs_lport_s *fcs_port; |
1111 | struct bfa_fcs_itnim_s *itnim; |
1112 | unsigned long flags; |
1113 | |
1114 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1115 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
1116 | vf_id: iocmd->vf_id, lpwwn: iocmd->pwwn); |
1117 | if (!fcs_port) |
1118 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
1119 | else { |
1120 | itnim = bfa_fcs_itnim_lookup(port: fcs_port, rpwwn: iocmd->rpwwn); |
1121 | if (itnim == NULL) |
1122 | iocmd->status = BFA_STATUS_UNKNOWN_RWWN; |
1123 | else { |
1124 | iocmd->status = BFA_STATUS_OK; |
1125 | bfa_fcs_itnim_stats_clear(port: fcs_port, rpwwn: iocmd->rpwwn); |
1126 | bfa_itnim_clear_stats(itnim: bfa_fcs_itnim_get_halitn(itnim)); |
1127 | } |
1128 | } |
1129 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1130 | |
1131 | return 0; |
1132 | } |
1133 | |
1134 | static int |
1135 | bfad_iocmd_itnim_get_itnstats(struct bfad_s *bfad, void *cmd) |
1136 | { |
1137 | struct bfa_bsg_itnim_itnstats_s *iocmd = |
1138 | (struct bfa_bsg_itnim_itnstats_s *)cmd; |
1139 | struct bfa_fcs_lport_s *fcs_port; |
1140 | struct bfa_fcs_itnim_s *itnim; |
1141 | unsigned long flags; |
1142 | |
1143 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1144 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
1145 | vf_id: iocmd->vf_id, lpwwn: iocmd->lpwwn); |
1146 | if (!fcs_port) { |
1147 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
1148 | bfa_trc(bfad, 0); |
1149 | } else { |
1150 | itnim = bfa_fcs_itnim_lookup(port: fcs_port, rpwwn: iocmd->rpwwn); |
1151 | if (itnim == NULL) |
1152 | iocmd->status = BFA_STATUS_UNKNOWN_RWWN; |
1153 | else { |
1154 | iocmd->status = BFA_STATUS_OK; |
1155 | bfa_fcs_itnim_stats_get(port: fcs_port, rpwwn: iocmd->rpwwn, |
1156 | stats: &iocmd->itnstats); |
1157 | } |
1158 | } |
1159 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1160 | return 0; |
1161 | } |
1162 | |
1163 | static int |
1164 | bfad_iocmd_fcport_enable(struct bfad_s *bfad, void *cmd) |
1165 | { |
1166 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
1167 | unsigned long flags; |
1168 | |
1169 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1170 | iocmd->status = bfa_fcport_enable(bfa: &bfad->bfa); |
1171 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1172 | |
1173 | return 0; |
1174 | } |
1175 | |
1176 | static int |
1177 | bfad_iocmd_fcport_disable(struct bfad_s *bfad, void *cmd) |
1178 | { |
1179 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
1180 | unsigned long flags; |
1181 | |
1182 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1183 | iocmd->status = bfa_fcport_disable(bfa: &bfad->bfa); |
1184 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1185 | |
1186 | return 0; |
1187 | } |
1188 | |
1189 | static int |
1190 | bfad_iocmd_ioc_get_pcifn_cfg(struct bfad_s *bfad, void *cmd) |
1191 | { |
1192 | struct bfa_bsg_pcifn_cfg_s *iocmd = (struct bfa_bsg_pcifn_cfg_s *)cmd; |
1193 | struct bfad_hal_comp fcomp; |
1194 | unsigned long flags; |
1195 | |
1196 | init_completion(x: &fcomp.comp); |
1197 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1198 | iocmd->status = bfa_ablk_query(ablk: &bfad->bfa.modules.ablk, |
1199 | ablk_cfg: &iocmd->pcifn_cfg, |
1200 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1201 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1202 | if (iocmd->status != BFA_STATUS_OK) |
1203 | goto out; |
1204 | |
1205 | wait_for_completion(&fcomp.comp); |
1206 | iocmd->status = fcomp.status; |
1207 | out: |
1208 | return 0; |
1209 | } |
1210 | |
1211 | static int |
1212 | bfad_iocmd_pcifn_create(struct bfad_s *bfad, void *cmd) |
1213 | { |
1214 | struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd; |
1215 | struct bfad_hal_comp fcomp; |
1216 | unsigned long flags; |
1217 | |
1218 | init_completion(x: &fcomp.comp); |
1219 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1220 | iocmd->status = bfa_ablk_pf_create(ablk: &bfad->bfa.modules.ablk, |
1221 | pcifn: &iocmd->pcifn_id, port: iocmd->port, |
1222 | personality: iocmd->pcifn_class, bw_min: iocmd->bw_min, |
1223 | bw_max: iocmd->bw_max, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1224 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1225 | if (iocmd->status != BFA_STATUS_OK) |
1226 | goto out; |
1227 | |
1228 | wait_for_completion(&fcomp.comp); |
1229 | iocmd->status = fcomp.status; |
1230 | out: |
1231 | return 0; |
1232 | } |
1233 | |
1234 | static int |
1235 | bfad_iocmd_pcifn_delete(struct bfad_s *bfad, void *cmd) |
1236 | { |
1237 | struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd; |
1238 | struct bfad_hal_comp fcomp; |
1239 | unsigned long flags; |
1240 | |
1241 | init_completion(x: &fcomp.comp); |
1242 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1243 | iocmd->status = bfa_ablk_pf_delete(ablk: &bfad->bfa.modules.ablk, |
1244 | pcifn: iocmd->pcifn_id, |
1245 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1246 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1247 | if (iocmd->status != BFA_STATUS_OK) |
1248 | goto out; |
1249 | |
1250 | wait_for_completion(&fcomp.comp); |
1251 | iocmd->status = fcomp.status; |
1252 | out: |
1253 | return 0; |
1254 | } |
1255 | |
1256 | static int |
1257 | bfad_iocmd_pcifn_bw(struct bfad_s *bfad, void *cmd) |
1258 | { |
1259 | struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd; |
1260 | struct bfad_hal_comp fcomp; |
1261 | unsigned long flags; |
1262 | |
1263 | init_completion(x: &fcomp.comp); |
1264 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1265 | iocmd->status = bfa_ablk_pf_update(ablk: &bfad->bfa.modules.ablk, |
1266 | pcifn: iocmd->pcifn_id, bw_min: iocmd->bw_min, |
1267 | bw_max: iocmd->bw_max, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1268 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1269 | bfa_trc(bfad, iocmd->status); |
1270 | if (iocmd->status != BFA_STATUS_OK) |
1271 | goto out; |
1272 | |
1273 | wait_for_completion(&fcomp.comp); |
1274 | iocmd->status = fcomp.status; |
1275 | bfa_trc(bfad, iocmd->status); |
1276 | out: |
1277 | return 0; |
1278 | } |
1279 | |
1280 | static int |
1281 | bfad_iocmd_adapter_cfg_mode(struct bfad_s *bfad, void *cmd) |
1282 | { |
1283 | struct bfa_bsg_adapter_cfg_mode_s *iocmd = |
1284 | (struct bfa_bsg_adapter_cfg_mode_s *)cmd; |
1285 | struct bfad_hal_comp fcomp; |
1286 | unsigned long flags = 0; |
1287 | |
1288 | init_completion(x: &fcomp.comp); |
1289 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1290 | iocmd->status = bfa_ablk_adapter_config(ablk: &bfad->bfa.modules.ablk, |
1291 | mode: iocmd->cfg.mode, max_pf: iocmd->cfg.max_pf, |
1292 | max_vf: iocmd->cfg.max_vf, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1293 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1294 | if (iocmd->status != BFA_STATUS_OK) |
1295 | goto out; |
1296 | |
1297 | wait_for_completion(&fcomp.comp); |
1298 | iocmd->status = fcomp.status; |
1299 | out: |
1300 | return 0; |
1301 | } |
1302 | |
1303 | static int |
1304 | bfad_iocmd_port_cfg_mode(struct bfad_s *bfad, void *cmd) |
1305 | { |
1306 | struct bfa_bsg_port_cfg_mode_s *iocmd = |
1307 | (struct bfa_bsg_port_cfg_mode_s *)cmd; |
1308 | struct bfad_hal_comp fcomp; |
1309 | unsigned long flags = 0; |
1310 | |
1311 | init_completion(x: &fcomp.comp); |
1312 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1313 | iocmd->status = bfa_ablk_port_config(ablk: &bfad->bfa.modules.ablk, |
1314 | port: iocmd->instance, mode: iocmd->cfg.mode, |
1315 | max_pf: iocmd->cfg.max_pf, max_vf: iocmd->cfg.max_vf, |
1316 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1317 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1318 | if (iocmd->status != BFA_STATUS_OK) |
1319 | goto out; |
1320 | |
1321 | wait_for_completion(&fcomp.comp); |
1322 | iocmd->status = fcomp.status; |
1323 | out: |
1324 | return 0; |
1325 | } |
1326 | |
1327 | static int |
1328 | bfad_iocmd_ablk_optrom(struct bfad_s *bfad, unsigned int cmd, void *pcmd) |
1329 | { |
1330 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; |
1331 | struct bfad_hal_comp fcomp; |
1332 | unsigned long flags; |
1333 | |
1334 | init_completion(x: &fcomp.comp); |
1335 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1336 | if (cmd == IOCMD_FLASH_ENABLE_OPTROM) |
1337 | iocmd->status = bfa_ablk_optrom_en(ablk: &bfad->bfa.modules.ablk, |
1338 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1339 | else |
1340 | iocmd->status = bfa_ablk_optrom_dis(ablk: &bfad->bfa.modules.ablk, |
1341 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1342 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1343 | |
1344 | if (iocmd->status != BFA_STATUS_OK) |
1345 | goto out; |
1346 | |
1347 | wait_for_completion(&fcomp.comp); |
1348 | iocmd->status = fcomp.status; |
1349 | out: |
1350 | return 0; |
1351 | } |
1352 | |
1353 | static int |
1354 | bfad_iocmd_faa_query(struct bfad_s *bfad, void *cmd) |
1355 | { |
1356 | struct bfa_bsg_faa_attr_s *iocmd = (struct bfa_bsg_faa_attr_s *)cmd; |
1357 | struct bfad_hal_comp fcomp; |
1358 | unsigned long flags; |
1359 | |
1360 | init_completion(x: &fcomp.comp); |
1361 | iocmd->status = BFA_STATUS_OK; |
1362 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1363 | iocmd->status = bfa_faa_query(bfa: &bfad->bfa, attr: &iocmd->faa_attr, |
1364 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1365 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1366 | |
1367 | if (iocmd->status != BFA_STATUS_OK) |
1368 | goto out; |
1369 | |
1370 | wait_for_completion(&fcomp.comp); |
1371 | iocmd->status = fcomp.status; |
1372 | out: |
1373 | return 0; |
1374 | } |
1375 | |
1376 | static int |
1377 | bfad_iocmd_cee_attr(struct bfad_s *bfad, void *cmd, unsigned int payload_len) |
1378 | { |
1379 | struct bfa_bsg_cee_attr_s *iocmd = |
1380 | (struct bfa_bsg_cee_attr_s *)cmd; |
1381 | void *iocmd_bufptr; |
1382 | struct bfad_hal_comp cee_comp; |
1383 | unsigned long flags; |
1384 | |
1385 | if (bfad_chk_iocmd_sz(payload_len, |
1386 | sizeof(struct bfa_bsg_cee_attr_s), |
1387 | sizeof(struct bfa_cee_attr_s)) != BFA_STATUS_OK) { |
1388 | iocmd->status = BFA_STATUS_VERSION_FAIL; |
1389 | return 0; |
1390 | } |
1391 | |
1392 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_cee_attr_s); |
1393 | |
1394 | cee_comp.status = 0; |
1395 | init_completion(x: &cee_comp.comp); |
1396 | mutex_lock(&bfad_mutex); |
1397 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1398 | iocmd->status = bfa_cee_get_attr(cee: &bfad->bfa.modules.cee, attr: iocmd_bufptr, |
1399 | cbfn: bfad_hcb_comp, cbarg: &cee_comp); |
1400 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1401 | if (iocmd->status != BFA_STATUS_OK) { |
1402 | mutex_unlock(lock: &bfad_mutex); |
1403 | bfa_trc(bfad, 0x5555); |
1404 | goto out; |
1405 | } |
1406 | wait_for_completion(&cee_comp.comp); |
1407 | mutex_unlock(lock: &bfad_mutex); |
1408 | out: |
1409 | return 0; |
1410 | } |
1411 | |
1412 | static int |
1413 | bfad_iocmd_cee_get_stats(struct bfad_s *bfad, void *cmd, |
1414 | unsigned int payload_len) |
1415 | { |
1416 | struct bfa_bsg_cee_stats_s *iocmd = |
1417 | (struct bfa_bsg_cee_stats_s *)cmd; |
1418 | void *iocmd_bufptr; |
1419 | struct bfad_hal_comp cee_comp; |
1420 | unsigned long flags; |
1421 | |
1422 | if (bfad_chk_iocmd_sz(payload_len, |
1423 | sizeof(struct bfa_bsg_cee_stats_s), |
1424 | sizeof(struct bfa_cee_stats_s)) != BFA_STATUS_OK) { |
1425 | iocmd->status = BFA_STATUS_VERSION_FAIL; |
1426 | return 0; |
1427 | } |
1428 | |
1429 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_cee_stats_s); |
1430 | |
1431 | cee_comp.status = 0; |
1432 | init_completion(x: &cee_comp.comp); |
1433 | mutex_lock(&bfad_mutex); |
1434 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1435 | iocmd->status = bfa_cee_get_stats(cee: &bfad->bfa.modules.cee, stats: iocmd_bufptr, |
1436 | cbfn: bfad_hcb_comp, cbarg: &cee_comp); |
1437 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1438 | if (iocmd->status != BFA_STATUS_OK) { |
1439 | mutex_unlock(lock: &bfad_mutex); |
1440 | bfa_trc(bfad, 0x5555); |
1441 | goto out; |
1442 | } |
1443 | wait_for_completion(&cee_comp.comp); |
1444 | mutex_unlock(lock: &bfad_mutex); |
1445 | out: |
1446 | return 0; |
1447 | } |
1448 | |
1449 | static int |
1450 | bfad_iocmd_cee_reset_stats(struct bfad_s *bfad, void *cmd) |
1451 | { |
1452 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
1453 | unsigned long flags; |
1454 | |
1455 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1456 | iocmd->status = bfa_cee_reset_stats(cee: &bfad->bfa.modules.cee, NULL, NULL); |
1457 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1458 | if (iocmd->status != BFA_STATUS_OK) |
1459 | bfa_trc(bfad, 0x5555); |
1460 | return 0; |
1461 | } |
1462 | |
1463 | static int |
1464 | bfad_iocmd_sfp_media(struct bfad_s *bfad, void *cmd) |
1465 | { |
1466 | struct bfa_bsg_sfp_media_s *iocmd = (struct bfa_bsg_sfp_media_s *)cmd; |
1467 | struct bfad_hal_comp fcomp; |
1468 | unsigned long flags; |
1469 | |
1470 | init_completion(x: &fcomp.comp); |
1471 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1472 | iocmd->status = bfa_sfp_media(BFA_SFP_MOD(&bfad->bfa), media: &iocmd->media, |
1473 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1474 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1475 | bfa_trc(bfad, iocmd->status); |
1476 | if (iocmd->status != BFA_STATUS_SFP_NOT_READY) |
1477 | goto out; |
1478 | |
1479 | wait_for_completion(&fcomp.comp); |
1480 | iocmd->status = fcomp.status; |
1481 | out: |
1482 | return 0; |
1483 | } |
1484 | |
1485 | static int |
1486 | bfad_iocmd_sfp_speed(struct bfad_s *bfad, void *cmd) |
1487 | { |
1488 | struct bfa_bsg_sfp_speed_s *iocmd = (struct bfa_bsg_sfp_speed_s *)cmd; |
1489 | struct bfad_hal_comp fcomp; |
1490 | unsigned long flags; |
1491 | |
1492 | init_completion(x: &fcomp.comp); |
1493 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1494 | iocmd->status = bfa_sfp_speed(BFA_SFP_MOD(&bfad->bfa), portspeed: iocmd->speed, |
1495 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1496 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1497 | bfa_trc(bfad, iocmd->status); |
1498 | if (iocmd->status != BFA_STATUS_SFP_NOT_READY) |
1499 | goto out; |
1500 | wait_for_completion(&fcomp.comp); |
1501 | iocmd->status = fcomp.status; |
1502 | out: |
1503 | return 0; |
1504 | } |
1505 | |
1506 | static int |
1507 | bfad_iocmd_flash_get_attr(struct bfad_s *bfad, void *cmd) |
1508 | { |
1509 | struct bfa_bsg_flash_attr_s *iocmd = |
1510 | (struct bfa_bsg_flash_attr_s *)cmd; |
1511 | struct bfad_hal_comp fcomp; |
1512 | unsigned long flags; |
1513 | |
1514 | init_completion(x: &fcomp.comp); |
1515 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1516 | iocmd->status = bfa_flash_get_attr(BFA_FLASH(&bfad->bfa), attr: &iocmd->attr, |
1517 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1518 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1519 | if (iocmd->status != BFA_STATUS_OK) |
1520 | goto out; |
1521 | wait_for_completion(&fcomp.comp); |
1522 | iocmd->status = fcomp.status; |
1523 | out: |
1524 | return 0; |
1525 | } |
1526 | |
1527 | static int |
1528 | bfad_iocmd_flash_erase_part(struct bfad_s *bfad, void *cmd) |
1529 | { |
1530 | struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd; |
1531 | struct bfad_hal_comp fcomp; |
1532 | unsigned long flags; |
1533 | |
1534 | init_completion(x: &fcomp.comp); |
1535 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1536 | iocmd->status = bfa_flash_erase_part(BFA_FLASH(&bfad->bfa), type: iocmd->type, |
1537 | instance: iocmd->instance, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1538 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1539 | if (iocmd->status != BFA_STATUS_OK) |
1540 | goto out; |
1541 | wait_for_completion(&fcomp.comp); |
1542 | iocmd->status = fcomp.status; |
1543 | out: |
1544 | return 0; |
1545 | } |
1546 | |
1547 | static int |
1548 | bfad_iocmd_flash_update_part(struct bfad_s *bfad, void *cmd, |
1549 | unsigned int payload_len) |
1550 | { |
1551 | struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd; |
1552 | void *iocmd_bufptr; |
1553 | struct bfad_hal_comp fcomp; |
1554 | unsigned long flags; |
1555 | |
1556 | if (bfad_chk_iocmd_sz(payload_len, |
1557 | sizeof(struct bfa_bsg_flash_s), |
1558 | iocmd->bufsz) != BFA_STATUS_OK) { |
1559 | iocmd->status = BFA_STATUS_VERSION_FAIL; |
1560 | return 0; |
1561 | } |
1562 | |
1563 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_flash_s); |
1564 | |
1565 | init_completion(x: &fcomp.comp); |
1566 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1567 | iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), |
1568 | type: iocmd->type, instance: iocmd->instance, buf: iocmd_bufptr, |
1569 | len: iocmd->bufsz, offset: 0, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1570 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1571 | if (iocmd->status != BFA_STATUS_OK) |
1572 | goto out; |
1573 | wait_for_completion(&fcomp.comp); |
1574 | iocmd->status = fcomp.status; |
1575 | out: |
1576 | return 0; |
1577 | } |
1578 | |
1579 | static int |
1580 | bfad_iocmd_flash_read_part(struct bfad_s *bfad, void *cmd, |
1581 | unsigned int payload_len) |
1582 | { |
1583 | struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd; |
1584 | struct bfad_hal_comp fcomp; |
1585 | void *iocmd_bufptr; |
1586 | unsigned long flags; |
1587 | |
1588 | if (bfad_chk_iocmd_sz(payload_len, |
1589 | sizeof(struct bfa_bsg_flash_s), |
1590 | iocmd->bufsz) != BFA_STATUS_OK) { |
1591 | iocmd->status = BFA_STATUS_VERSION_FAIL; |
1592 | return 0; |
1593 | } |
1594 | |
1595 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_flash_s); |
1596 | |
1597 | init_completion(x: &fcomp.comp); |
1598 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1599 | iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), type: iocmd->type, |
1600 | instance: iocmd->instance, buf: iocmd_bufptr, len: iocmd->bufsz, offset: 0, |
1601 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1602 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1603 | if (iocmd->status != BFA_STATUS_OK) |
1604 | goto out; |
1605 | wait_for_completion(&fcomp.comp); |
1606 | iocmd->status = fcomp.status; |
1607 | out: |
1608 | return 0; |
1609 | } |
1610 | |
1611 | static int |
1612 | bfad_iocmd_diag_temp(struct bfad_s *bfad, void *cmd) |
1613 | { |
1614 | struct bfa_bsg_diag_get_temp_s *iocmd = |
1615 | (struct bfa_bsg_diag_get_temp_s *)cmd; |
1616 | struct bfad_hal_comp fcomp; |
1617 | unsigned long flags; |
1618 | |
1619 | init_completion(x: &fcomp.comp); |
1620 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1621 | iocmd->status = bfa_diag_tsensor_query(BFA_DIAG_MOD(&bfad->bfa), |
1622 | result: &iocmd->result, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1623 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1624 | bfa_trc(bfad, iocmd->status); |
1625 | if (iocmd->status != BFA_STATUS_OK) |
1626 | goto out; |
1627 | wait_for_completion(&fcomp.comp); |
1628 | iocmd->status = fcomp.status; |
1629 | out: |
1630 | return 0; |
1631 | } |
1632 | |
1633 | static int |
1634 | bfad_iocmd_diag_memtest(struct bfad_s *bfad, void *cmd) |
1635 | { |
1636 | struct bfa_bsg_diag_memtest_s *iocmd = |
1637 | (struct bfa_bsg_diag_memtest_s *)cmd; |
1638 | struct bfad_hal_comp fcomp; |
1639 | unsigned long flags; |
1640 | |
1641 | init_completion(x: &fcomp.comp); |
1642 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1643 | iocmd->status = bfa_diag_memtest(BFA_DIAG_MOD(&bfad->bfa), |
1644 | memtest: &iocmd->memtest, pattern: iocmd->pat, |
1645 | result: &iocmd->result, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1646 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1647 | bfa_trc(bfad, iocmd->status); |
1648 | if (iocmd->status != BFA_STATUS_OK) |
1649 | goto out; |
1650 | wait_for_completion(&fcomp.comp); |
1651 | iocmd->status = fcomp.status; |
1652 | out: |
1653 | return 0; |
1654 | } |
1655 | |
1656 | static int |
1657 | bfad_iocmd_diag_loopback(struct bfad_s *bfad, void *cmd) |
1658 | { |
1659 | struct bfa_bsg_diag_loopback_s *iocmd = |
1660 | (struct bfa_bsg_diag_loopback_s *)cmd; |
1661 | struct bfad_hal_comp fcomp; |
1662 | unsigned long flags; |
1663 | |
1664 | init_completion(x: &fcomp.comp); |
1665 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1666 | iocmd->status = bfa_fcdiag_loopback(bfa: &bfad->bfa, opmode: iocmd->opmode, |
1667 | speed: iocmd->speed, lpcnt: iocmd->lpcnt, pat: iocmd->pat, |
1668 | result: &iocmd->result, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1669 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1670 | bfa_trc(bfad, iocmd->status); |
1671 | if (iocmd->status != BFA_STATUS_OK) |
1672 | goto out; |
1673 | wait_for_completion(&fcomp.comp); |
1674 | iocmd->status = fcomp.status; |
1675 | out: |
1676 | return 0; |
1677 | } |
1678 | |
1679 | static int |
1680 | bfad_iocmd_diag_fwping(struct bfad_s *bfad, void *cmd) |
1681 | { |
1682 | struct bfa_bsg_diag_fwping_s *iocmd = |
1683 | (struct bfa_bsg_diag_fwping_s *)cmd; |
1684 | struct bfad_hal_comp fcomp; |
1685 | unsigned long flags; |
1686 | |
1687 | init_completion(x: &fcomp.comp); |
1688 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1689 | iocmd->status = bfa_diag_fwping(BFA_DIAG_MOD(&bfad->bfa), cnt: iocmd->cnt, |
1690 | pattern: iocmd->pattern, result: &iocmd->result, |
1691 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1692 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1693 | bfa_trc(bfad, iocmd->status); |
1694 | if (iocmd->status != BFA_STATUS_OK) |
1695 | goto out; |
1696 | bfa_trc(bfad, 0x77771); |
1697 | wait_for_completion(&fcomp.comp); |
1698 | iocmd->status = fcomp.status; |
1699 | out: |
1700 | return 0; |
1701 | } |
1702 | |
1703 | static int |
1704 | bfad_iocmd_diag_queuetest(struct bfad_s *bfad, void *cmd) |
1705 | { |
1706 | struct bfa_bsg_diag_qtest_s *iocmd = (struct bfa_bsg_diag_qtest_s *)cmd; |
1707 | struct bfad_hal_comp fcomp; |
1708 | unsigned long flags; |
1709 | |
1710 | init_completion(x: &fcomp.comp); |
1711 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1712 | iocmd->status = bfa_fcdiag_queuetest(bfa: &bfad->bfa, ignore: iocmd->force, |
1713 | queue: iocmd->queue, result: &iocmd->result, |
1714 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1715 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1716 | if (iocmd->status != BFA_STATUS_OK) |
1717 | goto out; |
1718 | wait_for_completion(&fcomp.comp); |
1719 | iocmd->status = fcomp.status; |
1720 | out: |
1721 | return 0; |
1722 | } |
1723 | |
1724 | static int |
1725 | bfad_iocmd_diag_sfp(struct bfad_s *bfad, void *cmd) |
1726 | { |
1727 | struct bfa_bsg_sfp_show_s *iocmd = |
1728 | (struct bfa_bsg_sfp_show_s *)cmd; |
1729 | struct bfad_hal_comp fcomp; |
1730 | unsigned long flags; |
1731 | |
1732 | init_completion(x: &fcomp.comp); |
1733 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1734 | iocmd->status = bfa_sfp_show(BFA_SFP_MOD(&bfad->bfa), sfpmem: &iocmd->sfp, |
1735 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1736 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1737 | bfa_trc(bfad, iocmd->status); |
1738 | if (iocmd->status != BFA_STATUS_OK) |
1739 | goto out; |
1740 | wait_for_completion(&fcomp.comp); |
1741 | iocmd->status = fcomp.status; |
1742 | bfa_trc(bfad, iocmd->status); |
1743 | out: |
1744 | return 0; |
1745 | } |
1746 | |
1747 | static int |
1748 | bfad_iocmd_diag_led(struct bfad_s *bfad, void *cmd) |
1749 | { |
1750 | struct bfa_bsg_diag_led_s *iocmd = (struct bfa_bsg_diag_led_s *)cmd; |
1751 | unsigned long flags; |
1752 | |
1753 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1754 | iocmd->status = bfa_diag_ledtest(BFA_DIAG_MOD(&bfad->bfa), |
1755 | ledtest: &iocmd->ledtest); |
1756 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1757 | return 0; |
1758 | } |
1759 | |
1760 | static int |
1761 | bfad_iocmd_diag_beacon_lport(struct bfad_s *bfad, void *cmd) |
1762 | { |
1763 | struct bfa_bsg_diag_beacon_s *iocmd = |
1764 | (struct bfa_bsg_diag_beacon_s *)cmd; |
1765 | unsigned long flags; |
1766 | |
1767 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1768 | iocmd->status = bfa_diag_beacon_port(BFA_DIAG_MOD(&bfad->bfa), |
1769 | beacon: iocmd->beacon, link_e2e_beacon: iocmd->link_e2e_beacon, |
1770 | sec: iocmd->second); |
1771 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1772 | return 0; |
1773 | } |
1774 | |
1775 | static int |
1776 | bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd) |
1777 | { |
1778 | struct bfa_bsg_diag_lb_stat_s *iocmd = |
1779 | (struct bfa_bsg_diag_lb_stat_s *)cmd; |
1780 | unsigned long flags; |
1781 | |
1782 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1783 | iocmd->status = bfa_fcdiag_lb_is_running(bfa: &bfad->bfa); |
1784 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1785 | bfa_trc(bfad, iocmd->status); |
1786 | |
1787 | return 0; |
1788 | } |
1789 | |
1790 | static int |
1791 | bfad_iocmd_diag_dport_enable(struct bfad_s *bfad, void *pcmd) |
1792 | { |
1793 | struct bfa_bsg_dport_enable_s *iocmd = |
1794 | (struct bfa_bsg_dport_enable_s *)pcmd; |
1795 | unsigned long flags; |
1796 | struct bfad_hal_comp fcomp; |
1797 | |
1798 | init_completion(x: &fcomp.comp); |
1799 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1800 | iocmd->status = bfa_dport_enable(bfa: &bfad->bfa, lpcnt: iocmd->lpcnt, |
1801 | pat: iocmd->pat, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1802 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1803 | if (iocmd->status != BFA_STATUS_OK) |
1804 | bfa_trc(bfad, iocmd->status); |
1805 | else { |
1806 | wait_for_completion(&fcomp.comp); |
1807 | iocmd->status = fcomp.status; |
1808 | } |
1809 | return 0; |
1810 | } |
1811 | |
1812 | static int |
1813 | bfad_iocmd_diag_dport_disable(struct bfad_s *bfad, void *pcmd) |
1814 | { |
1815 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; |
1816 | unsigned long flags; |
1817 | struct bfad_hal_comp fcomp; |
1818 | |
1819 | init_completion(x: &fcomp.comp); |
1820 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1821 | iocmd->status = bfa_dport_disable(bfa: &bfad->bfa, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1822 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1823 | if (iocmd->status != BFA_STATUS_OK) |
1824 | bfa_trc(bfad, iocmd->status); |
1825 | else { |
1826 | wait_for_completion(&fcomp.comp); |
1827 | iocmd->status = fcomp.status; |
1828 | } |
1829 | return 0; |
1830 | } |
1831 | |
1832 | static int |
1833 | bfad_iocmd_diag_dport_start(struct bfad_s *bfad, void *pcmd) |
1834 | { |
1835 | struct bfa_bsg_dport_enable_s *iocmd = |
1836 | (struct bfa_bsg_dport_enable_s *)pcmd; |
1837 | unsigned long flags; |
1838 | struct bfad_hal_comp fcomp; |
1839 | |
1840 | init_completion(x: &fcomp.comp); |
1841 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1842 | iocmd->status = bfa_dport_start(bfa: &bfad->bfa, lpcnt: iocmd->lpcnt, |
1843 | pat: iocmd->pat, cbfn: bfad_hcb_comp, |
1844 | cbarg: &fcomp); |
1845 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1846 | |
1847 | if (iocmd->status != BFA_STATUS_OK) { |
1848 | bfa_trc(bfad, iocmd->status); |
1849 | } else { |
1850 | wait_for_completion(&fcomp.comp); |
1851 | iocmd->status = fcomp.status; |
1852 | } |
1853 | |
1854 | return 0; |
1855 | } |
1856 | |
1857 | static int |
1858 | bfad_iocmd_diag_dport_show(struct bfad_s *bfad, void *pcmd) |
1859 | { |
1860 | struct bfa_bsg_diag_dport_show_s *iocmd = |
1861 | (struct bfa_bsg_diag_dport_show_s *)pcmd; |
1862 | unsigned long flags; |
1863 | |
1864 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1865 | iocmd->status = bfa_dport_show(bfa: &bfad->bfa, result: &iocmd->result); |
1866 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1867 | |
1868 | return 0; |
1869 | } |
1870 | |
1871 | |
1872 | static int |
1873 | bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd) |
1874 | { |
1875 | struct bfa_bsg_phy_attr_s *iocmd = |
1876 | (struct bfa_bsg_phy_attr_s *)cmd; |
1877 | struct bfad_hal_comp fcomp; |
1878 | unsigned long flags; |
1879 | |
1880 | init_completion(x: &fcomp.comp); |
1881 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1882 | iocmd->status = bfa_phy_get_attr(BFA_PHY(&bfad->bfa), instance: iocmd->instance, |
1883 | attr: &iocmd->attr, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1884 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1885 | if (iocmd->status != BFA_STATUS_OK) |
1886 | goto out; |
1887 | wait_for_completion(&fcomp.comp); |
1888 | iocmd->status = fcomp.status; |
1889 | out: |
1890 | return 0; |
1891 | } |
1892 | |
1893 | static int |
1894 | bfad_iocmd_phy_get_stats(struct bfad_s *bfad, void *cmd) |
1895 | { |
1896 | struct bfa_bsg_phy_stats_s *iocmd = |
1897 | (struct bfa_bsg_phy_stats_s *)cmd; |
1898 | struct bfad_hal_comp fcomp; |
1899 | unsigned long flags; |
1900 | |
1901 | init_completion(x: &fcomp.comp); |
1902 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1903 | iocmd->status = bfa_phy_get_stats(BFA_PHY(&bfad->bfa), instance: iocmd->instance, |
1904 | stats: &iocmd->stats, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1905 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1906 | if (iocmd->status != BFA_STATUS_OK) |
1907 | goto out; |
1908 | wait_for_completion(&fcomp.comp); |
1909 | iocmd->status = fcomp.status; |
1910 | out: |
1911 | return 0; |
1912 | } |
1913 | |
1914 | static int |
1915 | bfad_iocmd_phy_read(struct bfad_s *bfad, void *cmd, unsigned int payload_len) |
1916 | { |
1917 | struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd; |
1918 | struct bfad_hal_comp fcomp; |
1919 | void *iocmd_bufptr; |
1920 | unsigned long flags; |
1921 | |
1922 | if (bfad_chk_iocmd_sz(payload_len, |
1923 | sizeof(struct bfa_bsg_phy_s), |
1924 | iocmd->bufsz) != BFA_STATUS_OK) { |
1925 | iocmd->status = BFA_STATUS_VERSION_FAIL; |
1926 | return 0; |
1927 | } |
1928 | |
1929 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_phy_s); |
1930 | init_completion(x: &fcomp.comp); |
1931 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1932 | iocmd->status = bfa_phy_read(BFA_PHY(&bfad->bfa), |
1933 | instance: iocmd->instance, buf: iocmd_bufptr, len: iocmd->bufsz, |
1934 | offset: 0, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1935 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1936 | if (iocmd->status != BFA_STATUS_OK) |
1937 | goto out; |
1938 | wait_for_completion(&fcomp.comp); |
1939 | iocmd->status = fcomp.status; |
1940 | if (iocmd->status != BFA_STATUS_OK) |
1941 | goto out; |
1942 | out: |
1943 | return 0; |
1944 | } |
1945 | |
1946 | static int |
1947 | bfad_iocmd_vhba_query(struct bfad_s *bfad, void *cmd) |
1948 | { |
1949 | struct bfa_bsg_vhba_attr_s *iocmd = |
1950 | (struct bfa_bsg_vhba_attr_s *)cmd; |
1951 | struct bfa_vhba_attr_s *attr = &iocmd->attr; |
1952 | unsigned long flags; |
1953 | |
1954 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1955 | attr->pwwn = bfad->bfa.ioc.attr->pwwn; |
1956 | attr->nwwn = bfad->bfa.ioc.attr->nwwn; |
1957 | attr->plog_enabled = (bfa_boolean_t)bfad->bfa.plog->plog_enabled; |
1958 | attr->io_profile = bfa_fcpim_get_io_profile(&bfad->bfa); |
1959 | attr->path_tov = bfa_fcpim_path_tov_get(bfa: &bfad->bfa); |
1960 | iocmd->status = BFA_STATUS_OK; |
1961 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1962 | return 0; |
1963 | } |
1964 | |
1965 | static int |
1966 | bfad_iocmd_phy_update(struct bfad_s *bfad, void *cmd, unsigned int payload_len) |
1967 | { |
1968 | struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd; |
1969 | void *iocmd_bufptr; |
1970 | struct bfad_hal_comp fcomp; |
1971 | unsigned long flags; |
1972 | |
1973 | if (bfad_chk_iocmd_sz(payload_len, |
1974 | sizeof(struct bfa_bsg_phy_s), |
1975 | iocmd->bufsz) != BFA_STATUS_OK) { |
1976 | iocmd->status = BFA_STATUS_VERSION_FAIL; |
1977 | return 0; |
1978 | } |
1979 | |
1980 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_phy_s); |
1981 | init_completion(x: &fcomp.comp); |
1982 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1983 | iocmd->status = bfa_phy_update(BFA_PHY(&bfad->bfa), |
1984 | instance: iocmd->instance, buf: iocmd_bufptr, len: iocmd->bufsz, |
1985 | offset: 0, cbfn: bfad_hcb_comp, cbarg: &fcomp); |
1986 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1987 | if (iocmd->status != BFA_STATUS_OK) |
1988 | goto out; |
1989 | wait_for_completion(&fcomp.comp); |
1990 | iocmd->status = fcomp.status; |
1991 | out: |
1992 | return 0; |
1993 | } |
1994 | |
1995 | static int |
1996 | bfad_iocmd_porglog_get(struct bfad_s *bfad, void *cmd) |
1997 | { |
1998 | struct bfa_bsg_debug_s *iocmd = (struct bfa_bsg_debug_s *)cmd; |
1999 | void *iocmd_bufptr; |
2000 | |
2001 | if (iocmd->bufsz < sizeof(struct bfa_plog_s)) { |
2002 | bfa_trc(bfad, sizeof(struct bfa_plog_s)); |
2003 | iocmd->status = BFA_STATUS_EINVAL; |
2004 | goto out; |
2005 | } |
2006 | |
2007 | iocmd->status = BFA_STATUS_OK; |
2008 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_debug_s); |
2009 | memcpy(iocmd_bufptr, (u8 *) &bfad->plog_buf, sizeof(struct bfa_plog_s)); |
2010 | out: |
2011 | return 0; |
2012 | } |
2013 | |
2014 | #define BFA_DEBUG_FW_CORE_CHUNK_SZ 0x4000U /* 16K chunks for FW dump */ |
2015 | static int |
2016 | bfad_iocmd_debug_fw_core(struct bfad_s *bfad, void *cmd, |
2017 | unsigned int payload_len) |
2018 | { |
2019 | struct bfa_bsg_debug_s *iocmd = (struct bfa_bsg_debug_s *)cmd; |
2020 | void *iocmd_bufptr; |
2021 | unsigned long flags; |
2022 | u32 offset; |
2023 | |
2024 | if (bfad_chk_iocmd_sz(payload_len, sizeof(struct bfa_bsg_debug_s), |
2025 | BFA_DEBUG_FW_CORE_CHUNK_SZ) != BFA_STATUS_OK) { |
2026 | iocmd->status = BFA_STATUS_VERSION_FAIL; |
2027 | return 0; |
2028 | } |
2029 | |
2030 | if (iocmd->bufsz < BFA_DEBUG_FW_CORE_CHUNK_SZ || |
2031 | !IS_ALIGNED(iocmd->bufsz, sizeof(u16)) || |
2032 | !IS_ALIGNED(iocmd->offset, sizeof(u32))) { |
2033 | bfa_trc(bfad, BFA_DEBUG_FW_CORE_CHUNK_SZ); |
2034 | iocmd->status = BFA_STATUS_EINVAL; |
2035 | goto out; |
2036 | } |
2037 | |
2038 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_debug_s); |
2039 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2040 | offset = iocmd->offset; |
2041 | iocmd->status = bfa_ioc_debug_fwcore(ioc: &bfad->bfa.ioc, buf: iocmd_bufptr, |
2042 | offset: &offset, buflen: &iocmd->bufsz); |
2043 | iocmd->offset = offset; |
2044 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2045 | out: |
2046 | return 0; |
2047 | } |
2048 | |
2049 | static int |
2050 | bfad_iocmd_debug_ctl(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) |
2051 | { |
2052 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
2053 | unsigned long flags; |
2054 | |
2055 | if (v_cmd == IOCMD_DEBUG_FW_STATE_CLR) { |
2056 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2057 | bfad->bfa.ioc.dbg_fwsave_once = BFA_TRUE; |
2058 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2059 | } else if (v_cmd == IOCMD_DEBUG_PORTLOG_CLR) |
2060 | bfad->plog_buf.head = bfad->plog_buf.tail = 0; |
2061 | else if (v_cmd == IOCMD_DEBUG_START_DTRC) |
2062 | bfa_trc_init(trcm: bfad->trcmod); |
2063 | else if (v_cmd == IOCMD_DEBUG_STOP_DTRC) |
2064 | bfa_trc_stop(trcm: bfad->trcmod); |
2065 | |
2066 | iocmd->status = BFA_STATUS_OK; |
2067 | return 0; |
2068 | } |
2069 | |
2070 | static int |
2071 | bfad_iocmd_porglog_ctl(struct bfad_s *bfad, void *cmd) |
2072 | { |
2073 | struct bfa_bsg_portlogctl_s *iocmd = (struct bfa_bsg_portlogctl_s *)cmd; |
2074 | |
2075 | if (iocmd->ctl == BFA_TRUE) |
2076 | bfad->plog_buf.plog_enabled = 1; |
2077 | else |
2078 | bfad->plog_buf.plog_enabled = 0; |
2079 | |
2080 | iocmd->status = BFA_STATUS_OK; |
2081 | return 0; |
2082 | } |
2083 | |
2084 | static int |
2085 | bfad_iocmd_fcpim_cfg_profile(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) |
2086 | { |
2087 | struct bfa_bsg_fcpim_profile_s *iocmd = |
2088 | (struct bfa_bsg_fcpim_profile_s *)cmd; |
2089 | unsigned long flags; |
2090 | |
2091 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2092 | if (v_cmd == IOCMD_FCPIM_PROFILE_ON) |
2093 | iocmd->status = bfa_fcpim_profile_on(bfa: &bfad->bfa, time: ktime_get_real_seconds()); |
2094 | else if (v_cmd == IOCMD_FCPIM_PROFILE_OFF) |
2095 | iocmd->status = bfa_fcpim_profile_off(bfa: &bfad->bfa); |
2096 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2097 | |
2098 | return 0; |
2099 | } |
2100 | |
2101 | static int |
2102 | bfad_iocmd_itnim_get_ioprofile(struct bfad_s *bfad, void *cmd) |
2103 | { |
2104 | struct bfa_bsg_itnim_ioprofile_s *iocmd = |
2105 | (struct bfa_bsg_itnim_ioprofile_s *)cmd; |
2106 | struct bfa_fcs_lport_s *fcs_port; |
2107 | struct bfa_fcs_itnim_s *itnim; |
2108 | unsigned long flags; |
2109 | |
2110 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2111 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, |
2112 | vf_id: iocmd->vf_id, lpwwn: iocmd->lpwwn); |
2113 | if (!fcs_port) |
2114 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; |
2115 | else { |
2116 | itnim = bfa_fcs_itnim_lookup(port: fcs_port, rpwwn: iocmd->rpwwn); |
2117 | if (itnim == NULL) |
2118 | iocmd->status = BFA_STATUS_UNKNOWN_RWWN; |
2119 | else |
2120 | iocmd->status = bfa_itnim_get_ioprofile( |
2121 | itnim: bfa_fcs_itnim_get_halitn(itnim), |
2122 | ioprofile: &iocmd->ioprofile); |
2123 | } |
2124 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2125 | return 0; |
2126 | } |
2127 | |
2128 | static int |
2129 | bfad_iocmd_fcport_get_stats(struct bfad_s *bfad, void *cmd) |
2130 | { |
2131 | struct bfa_bsg_fcport_stats_s *iocmd = |
2132 | (struct bfa_bsg_fcport_stats_s *)cmd; |
2133 | struct bfad_hal_comp fcomp; |
2134 | unsigned long flags; |
2135 | struct bfa_cb_pending_q_s cb_qe; |
2136 | |
2137 | init_completion(x: &fcomp.comp); |
2138 | bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, |
2139 | &fcomp, &iocmd->stats); |
2140 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2141 | iocmd->status = bfa_fcport_get_stats(bfa: &bfad->bfa, cb: &cb_qe); |
2142 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2143 | if (iocmd->status != BFA_STATUS_OK) { |
2144 | bfa_trc(bfad, iocmd->status); |
2145 | goto out; |
2146 | } |
2147 | wait_for_completion(&fcomp.comp); |
2148 | iocmd->status = fcomp.status; |
2149 | out: |
2150 | return 0; |
2151 | } |
2152 | |
2153 | static int |
2154 | bfad_iocmd_fcport_reset_stats(struct bfad_s *bfad, void *cmd) |
2155 | { |
2156 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
2157 | struct bfad_hal_comp fcomp; |
2158 | unsigned long flags; |
2159 | struct bfa_cb_pending_q_s cb_qe; |
2160 | |
2161 | init_completion(x: &fcomp.comp); |
2162 | bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, &fcomp, NULL); |
2163 | |
2164 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2165 | iocmd->status = bfa_fcport_clear_stats(bfa: &bfad->bfa, cb: &cb_qe); |
2166 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2167 | if (iocmd->status != BFA_STATUS_OK) { |
2168 | bfa_trc(bfad, iocmd->status); |
2169 | goto out; |
2170 | } |
2171 | wait_for_completion(&fcomp.comp); |
2172 | iocmd->status = fcomp.status; |
2173 | out: |
2174 | return 0; |
2175 | } |
2176 | |
2177 | static int |
2178 | bfad_iocmd_boot_cfg(struct bfad_s *bfad, void *cmd) |
2179 | { |
2180 | struct bfa_bsg_boot_s *iocmd = (struct bfa_bsg_boot_s *)cmd; |
2181 | struct bfad_hal_comp fcomp; |
2182 | unsigned long flags; |
2183 | |
2184 | init_completion(x: &fcomp.comp); |
2185 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2186 | iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), |
2187 | type: BFA_FLASH_PART_BOOT, instance: bfad->bfa.ioc.port_id, |
2188 | buf: &iocmd->cfg, len: sizeof(struct bfa_boot_cfg_s), offset: 0, |
2189 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
2190 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2191 | if (iocmd->status != BFA_STATUS_OK) |
2192 | goto out; |
2193 | wait_for_completion(&fcomp.comp); |
2194 | iocmd->status = fcomp.status; |
2195 | out: |
2196 | return 0; |
2197 | } |
2198 | |
2199 | static int |
2200 | bfad_iocmd_boot_query(struct bfad_s *bfad, void *cmd) |
2201 | { |
2202 | struct bfa_bsg_boot_s *iocmd = (struct bfa_bsg_boot_s *)cmd; |
2203 | struct bfad_hal_comp fcomp; |
2204 | unsigned long flags; |
2205 | |
2206 | init_completion(x: &fcomp.comp); |
2207 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2208 | iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), |
2209 | type: BFA_FLASH_PART_BOOT, instance: bfad->bfa.ioc.port_id, |
2210 | buf: &iocmd->cfg, len: sizeof(struct bfa_boot_cfg_s), offset: 0, |
2211 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
2212 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2213 | if (iocmd->status != BFA_STATUS_OK) |
2214 | goto out; |
2215 | wait_for_completion(&fcomp.comp); |
2216 | iocmd->status = fcomp.status; |
2217 | out: |
2218 | return 0; |
2219 | } |
2220 | |
2221 | static int |
2222 | bfad_iocmd_preboot_query(struct bfad_s *bfad, void *cmd) |
2223 | { |
2224 | struct bfa_bsg_preboot_s *iocmd = (struct bfa_bsg_preboot_s *)cmd; |
2225 | struct bfi_iocfc_cfgrsp_s *cfgrsp = bfad->bfa.iocfc.cfgrsp; |
2226 | struct bfa_boot_pbc_s *pbcfg = &iocmd->cfg; |
2227 | unsigned long flags; |
2228 | |
2229 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2230 | pbcfg->enable = cfgrsp->pbc_cfg.boot_enabled; |
2231 | pbcfg->nbluns = cfgrsp->pbc_cfg.nbluns; |
2232 | pbcfg->speed = cfgrsp->pbc_cfg.port_speed; |
2233 | memcpy(pbcfg->pblun, cfgrsp->pbc_cfg.blun, sizeof(pbcfg->pblun)); |
2234 | iocmd->status = BFA_STATUS_OK; |
2235 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2236 | |
2237 | return 0; |
2238 | } |
2239 | |
2240 | static int |
2241 | bfad_iocmd_ethboot_cfg(struct bfad_s *bfad, void *cmd) |
2242 | { |
2243 | struct bfa_bsg_ethboot_s *iocmd = (struct bfa_bsg_ethboot_s *)cmd; |
2244 | struct bfad_hal_comp fcomp; |
2245 | unsigned long flags; |
2246 | |
2247 | init_completion(x: &fcomp.comp); |
2248 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2249 | iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), |
2250 | type: BFA_FLASH_PART_PXECFG, |
2251 | instance: bfad->bfa.ioc.port_id, buf: &iocmd->cfg, |
2252 | len: sizeof(struct bfa_ethboot_cfg_s), offset: 0, |
2253 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
2254 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2255 | if (iocmd->status != BFA_STATUS_OK) |
2256 | goto out; |
2257 | wait_for_completion(&fcomp.comp); |
2258 | iocmd->status = fcomp.status; |
2259 | out: |
2260 | return 0; |
2261 | } |
2262 | |
2263 | static int |
2264 | bfad_iocmd_ethboot_query(struct bfad_s *bfad, void *cmd) |
2265 | { |
2266 | struct bfa_bsg_ethboot_s *iocmd = (struct bfa_bsg_ethboot_s *)cmd; |
2267 | struct bfad_hal_comp fcomp; |
2268 | unsigned long flags; |
2269 | |
2270 | init_completion(x: &fcomp.comp); |
2271 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2272 | iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), |
2273 | type: BFA_FLASH_PART_PXECFG, |
2274 | instance: bfad->bfa.ioc.port_id, buf: &iocmd->cfg, |
2275 | len: sizeof(struct bfa_ethboot_cfg_s), offset: 0, |
2276 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
2277 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2278 | if (iocmd->status != BFA_STATUS_OK) |
2279 | goto out; |
2280 | wait_for_completion(&fcomp.comp); |
2281 | iocmd->status = fcomp.status; |
2282 | out: |
2283 | return 0; |
2284 | } |
2285 | |
2286 | static int |
2287 | bfad_iocmd_cfg_trunk(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) |
2288 | { |
2289 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
2290 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); |
2291 | struct bfa_fcport_trunk_s *trunk = &fcport->trunk; |
2292 | unsigned long flags; |
2293 | |
2294 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2295 | |
2296 | if (bfa_fcport_is_dport(bfa: &bfad->bfa)) { |
2297 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2298 | return BFA_STATUS_DPORT_ERR; |
2299 | } |
2300 | |
2301 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || |
2302 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
2303 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; |
2304 | else { |
2305 | if (v_cmd == IOCMD_TRUNK_ENABLE) { |
2306 | trunk->attr.state = BFA_TRUNK_OFFLINE; |
2307 | bfa_fcport_disable(bfa: &bfad->bfa); |
2308 | fcport->cfg.trunked = BFA_TRUE; |
2309 | } else if (v_cmd == IOCMD_TRUNK_DISABLE) { |
2310 | trunk->attr.state = BFA_TRUNK_DISABLED; |
2311 | bfa_fcport_disable(bfa: &bfad->bfa); |
2312 | fcport->cfg.trunked = BFA_FALSE; |
2313 | } |
2314 | |
2315 | if (!bfa_fcport_is_disabled(bfa: &bfad->bfa)) |
2316 | bfa_fcport_enable(bfa: &bfad->bfa); |
2317 | |
2318 | iocmd->status = BFA_STATUS_OK; |
2319 | } |
2320 | |
2321 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2322 | |
2323 | return 0; |
2324 | } |
2325 | |
2326 | static int |
2327 | bfad_iocmd_trunk_get_attr(struct bfad_s *bfad, void *cmd) |
2328 | { |
2329 | struct bfa_bsg_trunk_attr_s *iocmd = (struct bfa_bsg_trunk_attr_s *)cmd; |
2330 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); |
2331 | struct bfa_fcport_trunk_s *trunk = &fcport->trunk; |
2332 | unsigned long flags; |
2333 | |
2334 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2335 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || |
2336 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
2337 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; |
2338 | else { |
2339 | memcpy((void *)&iocmd->attr, (void *)&trunk->attr, |
2340 | sizeof(struct bfa_trunk_attr_s)); |
2341 | iocmd->attr.port_id = bfa_lps_get_base_pid(bfa: &bfad->bfa); |
2342 | iocmd->status = BFA_STATUS_OK; |
2343 | } |
2344 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2345 | |
2346 | return 0; |
2347 | } |
2348 | |
2349 | static int |
2350 | bfad_iocmd_qos(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) |
2351 | { |
2352 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
2353 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); |
2354 | unsigned long flags; |
2355 | |
2356 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2357 | if (bfa_ioc_get_type(ioc: &bfad->bfa.ioc) == BFA_IOC_TYPE_FC) { |
2358 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
2359 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
2360 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; |
2361 | else { |
2362 | if (v_cmd == IOCMD_QOS_ENABLE) |
2363 | fcport->cfg.qos_enabled = BFA_TRUE; |
2364 | else if (v_cmd == IOCMD_QOS_DISABLE) { |
2365 | fcport->cfg.qos_enabled = BFA_FALSE; |
2366 | fcport->cfg.qos_bw.high = BFA_QOS_BW_HIGH; |
2367 | fcport->cfg.qos_bw.med = BFA_QOS_BW_MED; |
2368 | fcport->cfg.qos_bw.low = BFA_QOS_BW_LOW; |
2369 | } |
2370 | } |
2371 | } |
2372 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2373 | |
2374 | return 0; |
2375 | } |
2376 | |
2377 | static int |
2378 | bfad_iocmd_qos_get_attr(struct bfad_s *bfad, void *cmd) |
2379 | { |
2380 | struct bfa_bsg_qos_attr_s *iocmd = (struct bfa_bsg_qos_attr_s *)cmd; |
2381 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); |
2382 | unsigned long flags; |
2383 | |
2384 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2385 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
2386 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
2387 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; |
2388 | else { |
2389 | iocmd->attr.state = fcport->qos_attr.state; |
2390 | iocmd->attr.total_bb_cr = |
2391 | be32_to_cpu(fcport->qos_attr.total_bb_cr); |
2392 | iocmd->attr.qos_bw.high = fcport->cfg.qos_bw.high; |
2393 | iocmd->attr.qos_bw.med = fcport->cfg.qos_bw.med; |
2394 | iocmd->attr.qos_bw.low = fcport->cfg.qos_bw.low; |
2395 | iocmd->attr.qos_bw_op = fcport->qos_attr.qos_bw_op; |
2396 | iocmd->status = BFA_STATUS_OK; |
2397 | } |
2398 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2399 | |
2400 | return 0; |
2401 | } |
2402 | |
2403 | static int |
2404 | bfad_iocmd_qos_get_vc_attr(struct bfad_s *bfad, void *cmd) |
2405 | { |
2406 | struct bfa_bsg_qos_vc_attr_s *iocmd = |
2407 | (struct bfa_bsg_qos_vc_attr_s *)cmd; |
2408 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); |
2409 | struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr; |
2410 | unsigned long flags; |
2411 | u32 i = 0; |
2412 | |
2413 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2414 | iocmd->attr.total_vc_count = be16_to_cpu(bfa_vc_attr->total_vc_count); |
2415 | iocmd->attr.shared_credit = be16_to_cpu(bfa_vc_attr->shared_credit); |
2416 | iocmd->attr.elp_opmode_flags = |
2417 | be32_to_cpu(bfa_vc_attr->elp_opmode_flags); |
2418 | |
2419 | /* Individual VC info */ |
2420 | while (i < iocmd->attr.total_vc_count) { |
2421 | iocmd->attr.vc_info[i].vc_credit = |
2422 | bfa_vc_attr->vc_info[i].vc_credit; |
2423 | iocmd->attr.vc_info[i].borrow_credit = |
2424 | bfa_vc_attr->vc_info[i].borrow_credit; |
2425 | iocmd->attr.vc_info[i].priority = |
2426 | bfa_vc_attr->vc_info[i].priority; |
2427 | i++; |
2428 | } |
2429 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2430 | |
2431 | iocmd->status = BFA_STATUS_OK; |
2432 | return 0; |
2433 | } |
2434 | |
2435 | static int |
2436 | bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd) |
2437 | { |
2438 | struct bfa_bsg_fcport_stats_s *iocmd = |
2439 | (struct bfa_bsg_fcport_stats_s *)cmd; |
2440 | struct bfad_hal_comp fcomp; |
2441 | unsigned long flags; |
2442 | struct bfa_cb_pending_q_s cb_qe; |
2443 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); |
2444 | |
2445 | init_completion(x: &fcomp.comp); |
2446 | bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, |
2447 | &fcomp, &iocmd->stats); |
2448 | |
2449 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2450 | WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); |
2451 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
2452 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
2453 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; |
2454 | else |
2455 | iocmd->status = bfa_fcport_get_stats(bfa: &bfad->bfa, cb: &cb_qe); |
2456 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2457 | if (iocmd->status != BFA_STATUS_OK) { |
2458 | bfa_trc(bfad, iocmd->status); |
2459 | goto out; |
2460 | } |
2461 | wait_for_completion(&fcomp.comp); |
2462 | iocmd->status = fcomp.status; |
2463 | out: |
2464 | return 0; |
2465 | } |
2466 | |
2467 | static int |
2468 | bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd) |
2469 | { |
2470 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; |
2471 | struct bfad_hal_comp fcomp; |
2472 | unsigned long flags; |
2473 | struct bfa_cb_pending_q_s cb_qe; |
2474 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); |
2475 | |
2476 | init_completion(x: &fcomp.comp); |
2477 | bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, |
2478 | &fcomp, NULL); |
2479 | |
2480 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2481 | WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); |
2482 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
2483 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
2484 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; |
2485 | else |
2486 | iocmd->status = bfa_fcport_clear_stats(bfa: &bfad->bfa, cb: &cb_qe); |
2487 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2488 | if (iocmd->status != BFA_STATUS_OK) { |
2489 | bfa_trc(bfad, iocmd->status); |
2490 | goto out; |
2491 | } |
2492 | wait_for_completion(&fcomp.comp); |
2493 | iocmd->status = fcomp.status; |
2494 | out: |
2495 | return 0; |
2496 | } |
2497 | |
2498 | static int |
2499 | bfad_iocmd_vf_get_stats(struct bfad_s *bfad, void *cmd) |
2500 | { |
2501 | struct bfa_bsg_vf_stats_s *iocmd = |
2502 | (struct bfa_bsg_vf_stats_s *)cmd; |
2503 | struct bfa_fcs_fabric_s *fcs_vf; |
2504 | unsigned long flags; |
2505 | |
2506 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2507 | fcs_vf = bfa_fcs_vf_lookup(fcs: &bfad->bfa_fcs, vf_id: iocmd->vf_id); |
2508 | if (fcs_vf == NULL) { |
2509 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2510 | iocmd->status = BFA_STATUS_UNKNOWN_VFID; |
2511 | goto out; |
2512 | } |
2513 | memcpy((void *)&iocmd->stats, (void *)&fcs_vf->stats, |
2514 | sizeof(struct bfa_vf_stats_s)); |
2515 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2516 | iocmd->status = BFA_STATUS_OK; |
2517 | out: |
2518 | return 0; |
2519 | } |
2520 | |
2521 | static int |
2522 | bfad_iocmd_vf_clr_stats(struct bfad_s *bfad, void *cmd) |
2523 | { |
2524 | struct bfa_bsg_vf_reset_stats_s *iocmd = |
2525 | (struct bfa_bsg_vf_reset_stats_s *)cmd; |
2526 | struct bfa_fcs_fabric_s *fcs_vf; |
2527 | unsigned long flags; |
2528 | |
2529 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2530 | fcs_vf = bfa_fcs_vf_lookup(fcs: &bfad->bfa_fcs, vf_id: iocmd->vf_id); |
2531 | if (fcs_vf == NULL) { |
2532 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2533 | iocmd->status = BFA_STATUS_UNKNOWN_VFID; |
2534 | goto out; |
2535 | } |
2536 | memset((void *)&fcs_vf->stats, 0, sizeof(struct bfa_vf_stats_s)); |
2537 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2538 | iocmd->status = BFA_STATUS_OK; |
2539 | out: |
2540 | return 0; |
2541 | } |
2542 | |
2543 | /* |
2544 | * Set the SCSI device sdev_bflags - sdev_bflags are used by the |
2545 | * SCSI mid-layer to choose LUN Scanning mode REPORT_LUNS vs. Sequential Scan |
2546 | * |
2547 | * Internally iterates over all the ITNIM's part of the im_port & sets the |
2548 | * sdev_bflags for the scsi_device associated with LUN #0. |
2549 | */ |
2550 | static void bfad_reset_sdev_bflags(struct bfad_im_port_s *im_port, |
2551 | int lunmask_cfg) |
2552 | { |
2553 | const u32 scan_flags = BLIST_NOREPORTLUN | BLIST_SPARSELUN; |
2554 | struct bfad_itnim_s *itnim; |
2555 | struct scsi_device *sdev; |
2556 | unsigned long flags; |
2557 | |
2558 | spin_lock_irqsave(im_port->shost->host_lock, flags); |
2559 | list_for_each_entry(itnim, &im_port->itnim_mapped_list, list_entry) { |
2560 | sdev = __scsi_device_lookup(im_port->shost, itnim->channel, |
2561 | itnim->scsi_tgt_id, 0); |
2562 | if (sdev) { |
2563 | if (lunmask_cfg == BFA_TRUE) |
2564 | sdev->sdev_bflags |= scan_flags; |
2565 | else |
2566 | sdev->sdev_bflags &= ~scan_flags; |
2567 | } |
2568 | } |
2569 | spin_unlock_irqrestore(lock: im_port->shost->host_lock, flags); |
2570 | } |
2571 | |
2572 | /* Function to reset the LUN SCAN mode */ |
2573 | static void |
2574 | bfad_iocmd_lunmask_reset_lunscan_mode(struct bfad_s *bfad, int lunmask_cfg) |
2575 | { |
2576 | struct bfad_im_port_s *pport_im = bfad->pport.im_port; |
2577 | struct bfad_vport_s *vport = NULL; |
2578 | |
2579 | /* Set the scsi device LUN SCAN flags for base port */ |
2580 | bfad_reset_sdev_bflags(im_port: pport_im, lunmask_cfg); |
2581 | |
2582 | /* Set the scsi device LUN SCAN flags for the vports */ |
2583 | list_for_each_entry(vport, &bfad->vport_list, list_entry) |
2584 | bfad_reset_sdev_bflags(im_port: vport->drv_port.im_port, lunmask_cfg); |
2585 | } |
2586 | |
2587 | static int |
2588 | bfad_iocmd_lunmask(struct bfad_s *bfad, void *pcmd, unsigned int v_cmd) |
2589 | { |
2590 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; |
2591 | unsigned long flags; |
2592 | |
2593 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2594 | if (v_cmd == IOCMD_FCPIM_LUNMASK_ENABLE) { |
2595 | iocmd->status = bfa_fcpim_lunmask_update(bfa: &bfad->bfa, on_off: BFA_TRUE); |
2596 | /* Set the LUN Scanning mode to be Sequential scan */ |
2597 | if (iocmd->status == BFA_STATUS_OK) |
2598 | bfad_iocmd_lunmask_reset_lunscan_mode(bfad, lunmask_cfg: BFA_TRUE); |
2599 | } else if (v_cmd == IOCMD_FCPIM_LUNMASK_DISABLE) { |
2600 | iocmd->status = bfa_fcpim_lunmask_update(bfa: &bfad->bfa, on_off: BFA_FALSE); |
2601 | /* Set the LUN Scanning mode to default REPORT_LUNS scan */ |
2602 | if (iocmd->status == BFA_STATUS_OK) |
2603 | bfad_iocmd_lunmask_reset_lunscan_mode(bfad, lunmask_cfg: BFA_FALSE); |
2604 | } else if (v_cmd == IOCMD_FCPIM_LUNMASK_CLEAR) |
2605 | iocmd->status = bfa_fcpim_lunmask_clear(bfa: &bfad->bfa); |
2606 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2607 | return 0; |
2608 | } |
2609 | |
2610 | static int |
2611 | bfad_iocmd_fcpim_lunmask_query(struct bfad_s *bfad, void *cmd) |
2612 | { |
2613 | struct bfa_bsg_fcpim_lunmask_query_s *iocmd = |
2614 | (struct bfa_bsg_fcpim_lunmask_query_s *)cmd; |
2615 | struct bfa_lunmask_cfg_s *lun_mask = &iocmd->lun_mask; |
2616 | unsigned long flags; |
2617 | |
2618 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2619 | iocmd->status = bfa_fcpim_lunmask_query(bfa: &bfad->bfa, buf: lun_mask); |
2620 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2621 | return 0; |
2622 | } |
2623 | |
2624 | static int |
2625 | bfad_iocmd_fcpim_cfg_lunmask(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) |
2626 | { |
2627 | struct bfa_bsg_fcpim_lunmask_s *iocmd = |
2628 | (struct bfa_bsg_fcpim_lunmask_s *)cmd; |
2629 | unsigned long flags; |
2630 | |
2631 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2632 | if (v_cmd == IOCMD_FCPIM_LUNMASK_ADD) |
2633 | iocmd->status = bfa_fcpim_lunmask_add(bfa: &bfad->bfa, vf_id: iocmd->vf_id, |
2634 | pwwn: &iocmd->pwwn, rpwwn: iocmd->rpwwn, lun: iocmd->lun); |
2635 | else if (v_cmd == IOCMD_FCPIM_LUNMASK_DELETE) |
2636 | iocmd->status = bfa_fcpim_lunmask_delete(bfa: &bfad->bfa, |
2637 | vf_id: iocmd->vf_id, pwwn: &iocmd->pwwn, |
2638 | rpwwn: iocmd->rpwwn, lun: iocmd->lun); |
2639 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2640 | return 0; |
2641 | } |
2642 | |
2643 | static int |
2644 | bfad_iocmd_fcpim_throttle_query(struct bfad_s *bfad, void *cmd) |
2645 | { |
2646 | struct bfa_bsg_fcpim_throttle_s *iocmd = |
2647 | (struct bfa_bsg_fcpim_throttle_s *)cmd; |
2648 | unsigned long flags; |
2649 | |
2650 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2651 | iocmd->status = bfa_fcpim_throttle_get(bfa: &bfad->bfa, |
2652 | buf: (void *)&iocmd->throttle); |
2653 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2654 | |
2655 | return 0; |
2656 | } |
2657 | |
2658 | static int |
2659 | bfad_iocmd_fcpim_throttle_set(struct bfad_s *bfad, void *cmd) |
2660 | { |
2661 | struct bfa_bsg_fcpim_throttle_s *iocmd = |
2662 | (struct bfa_bsg_fcpim_throttle_s *)cmd; |
2663 | unsigned long flags; |
2664 | |
2665 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2666 | iocmd->status = bfa_fcpim_throttle_set(bfa: &bfad->bfa, |
2667 | value: iocmd->throttle.cfg_value); |
2668 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2669 | |
2670 | return 0; |
2671 | } |
2672 | |
2673 | static int |
2674 | bfad_iocmd_tfru_read(struct bfad_s *bfad, void *cmd) |
2675 | { |
2676 | struct bfa_bsg_tfru_s *iocmd = |
2677 | (struct bfa_bsg_tfru_s *)cmd; |
2678 | struct bfad_hal_comp fcomp; |
2679 | unsigned long flags = 0; |
2680 | |
2681 | init_completion(x: &fcomp.comp); |
2682 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2683 | iocmd->status = bfa_tfru_read(BFA_FRU(&bfad->bfa), |
2684 | buf: &iocmd->data, len: iocmd->len, offset: iocmd->offset, |
2685 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
2686 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2687 | if (iocmd->status == BFA_STATUS_OK) { |
2688 | wait_for_completion(&fcomp.comp); |
2689 | iocmd->status = fcomp.status; |
2690 | } |
2691 | |
2692 | return 0; |
2693 | } |
2694 | |
2695 | static int |
2696 | bfad_iocmd_tfru_write(struct bfad_s *bfad, void *cmd) |
2697 | { |
2698 | struct bfa_bsg_tfru_s *iocmd = |
2699 | (struct bfa_bsg_tfru_s *)cmd; |
2700 | struct bfad_hal_comp fcomp; |
2701 | unsigned long flags = 0; |
2702 | |
2703 | init_completion(x: &fcomp.comp); |
2704 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2705 | iocmd->status = bfa_tfru_write(BFA_FRU(&bfad->bfa), |
2706 | buf: &iocmd->data, len: iocmd->len, offset: iocmd->offset, |
2707 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
2708 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2709 | if (iocmd->status == BFA_STATUS_OK) { |
2710 | wait_for_completion(&fcomp.comp); |
2711 | iocmd->status = fcomp.status; |
2712 | } |
2713 | |
2714 | return 0; |
2715 | } |
2716 | |
2717 | static int |
2718 | bfad_iocmd_fruvpd_read(struct bfad_s *bfad, void *cmd) |
2719 | { |
2720 | struct bfa_bsg_fruvpd_s *iocmd = |
2721 | (struct bfa_bsg_fruvpd_s *)cmd; |
2722 | struct bfad_hal_comp fcomp; |
2723 | unsigned long flags = 0; |
2724 | |
2725 | init_completion(x: &fcomp.comp); |
2726 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2727 | iocmd->status = bfa_fruvpd_read(BFA_FRU(&bfad->bfa), |
2728 | buf: &iocmd->data, len: iocmd->len, offset: iocmd->offset, |
2729 | cbfn: bfad_hcb_comp, cbarg: &fcomp); |
2730 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2731 | if (iocmd->status == BFA_STATUS_OK) { |
2732 | wait_for_completion(&fcomp.comp); |
2733 | iocmd->status = fcomp.status; |
2734 | } |
2735 | |
2736 | return 0; |
2737 | } |
2738 | |
2739 | static int |
2740 | bfad_iocmd_fruvpd_update(struct bfad_s *bfad, void *cmd) |
2741 | { |
2742 | struct bfa_bsg_fruvpd_s *iocmd = |
2743 | (struct bfa_bsg_fruvpd_s *)cmd; |
2744 | struct bfad_hal_comp fcomp; |
2745 | unsigned long flags = 0; |
2746 | |
2747 | init_completion(x: &fcomp.comp); |
2748 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2749 | iocmd->status = bfa_fruvpd_update(BFA_FRU(&bfad->bfa), |
2750 | buf: &iocmd->data, len: iocmd->len, offset: iocmd->offset, |
2751 | cbfn: bfad_hcb_comp, cbarg: &fcomp, trfr_cmpl: iocmd->trfr_cmpl); |
2752 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2753 | if (iocmd->status == BFA_STATUS_OK) { |
2754 | wait_for_completion(&fcomp.comp); |
2755 | iocmd->status = fcomp.status; |
2756 | } |
2757 | |
2758 | return 0; |
2759 | } |
2760 | |
2761 | static int |
2762 | bfad_iocmd_fruvpd_get_max_size(struct bfad_s *bfad, void *cmd) |
2763 | { |
2764 | struct bfa_bsg_fruvpd_max_size_s *iocmd = |
2765 | (struct bfa_bsg_fruvpd_max_size_s *)cmd; |
2766 | unsigned long flags = 0; |
2767 | |
2768 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2769 | iocmd->status = bfa_fruvpd_get_max_size(BFA_FRU(&bfad->bfa), |
2770 | max_size: &iocmd->max_size); |
2771 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
2772 | |
2773 | return 0; |
2774 | } |
2775 | |
2776 | static int |
2777 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, |
2778 | unsigned int payload_len) |
2779 | { |
2780 | int rc = -EINVAL; |
2781 | |
2782 | switch (cmd) { |
2783 | case IOCMD_IOC_ENABLE: |
2784 | rc = bfad_iocmd_ioc_enable(bfad, cmd: iocmd); |
2785 | break; |
2786 | case IOCMD_IOC_DISABLE: |
2787 | rc = bfad_iocmd_ioc_disable(bfad, cmd: iocmd); |
2788 | break; |
2789 | case IOCMD_IOC_GET_INFO: |
2790 | rc = bfad_iocmd_ioc_get_info(bfad, cmd: iocmd); |
2791 | break; |
2792 | case IOCMD_IOC_GET_ATTR: |
2793 | rc = bfad_iocmd_ioc_get_attr(bfad, cmd: iocmd); |
2794 | break; |
2795 | case IOCMD_IOC_GET_STATS: |
2796 | rc = bfad_iocmd_ioc_get_stats(bfad, cmd: iocmd); |
2797 | break; |
2798 | case IOCMD_IOC_GET_FWSTATS: |
2799 | rc = bfad_iocmd_ioc_get_fwstats(bfad, cmd: iocmd, payload_len); |
2800 | break; |
2801 | case IOCMD_IOC_RESET_STATS: |
2802 | case IOCMD_IOC_RESET_FWSTATS: |
2803 | rc = bfad_iocmd_ioc_reset_stats(bfad, cmd: iocmd, v_cmd: cmd); |
2804 | break; |
2805 | case IOCMD_IOC_SET_ADAPTER_NAME: |
2806 | case IOCMD_IOC_SET_PORT_NAME: |
2807 | rc = bfad_iocmd_ioc_set_name(bfad, cmd: iocmd, v_cmd: cmd); |
2808 | break; |
2809 | case IOCMD_IOCFC_GET_ATTR: |
2810 | rc = bfad_iocmd_iocfc_get_attr(bfad, cmd: iocmd); |
2811 | break; |
2812 | case IOCMD_IOCFC_SET_INTR: |
2813 | rc = bfad_iocmd_iocfc_set_intr(bfad, cmd: iocmd); |
2814 | break; |
2815 | case IOCMD_PORT_ENABLE: |
2816 | rc = bfad_iocmd_port_enable(bfad, cmd: iocmd); |
2817 | break; |
2818 | case IOCMD_PORT_DISABLE: |
2819 | rc = bfad_iocmd_port_disable(bfad, cmd: iocmd); |
2820 | break; |
2821 | case IOCMD_PORT_GET_ATTR: |
2822 | rc = bfad_iocmd_port_get_attr(bfad, cmd: iocmd); |
2823 | break; |
2824 | case IOCMD_PORT_GET_STATS: |
2825 | rc = bfad_iocmd_port_get_stats(bfad, cmd: iocmd, payload_len); |
2826 | break; |
2827 | case IOCMD_PORT_RESET_STATS: |
2828 | rc = bfad_iocmd_port_reset_stats(bfad, cmd: iocmd); |
2829 | break; |
2830 | case IOCMD_PORT_CFG_TOPO: |
2831 | case IOCMD_PORT_CFG_SPEED: |
2832 | case IOCMD_PORT_CFG_ALPA: |
2833 | case IOCMD_PORT_CLR_ALPA: |
2834 | rc = bfad_iocmd_set_port_cfg(bfad, iocmd, v_cmd: cmd); |
2835 | break; |
2836 | case IOCMD_PORT_CFG_MAXFRSZ: |
2837 | rc = bfad_iocmd_port_cfg_maxfrsize(bfad, cmd: iocmd); |
2838 | break; |
2839 | case IOCMD_PORT_BBCR_ENABLE: |
2840 | case IOCMD_PORT_BBCR_DISABLE: |
2841 | rc = bfad_iocmd_port_cfg_bbcr(bfad, cmd, pcmd: iocmd); |
2842 | break; |
2843 | case IOCMD_PORT_BBCR_GET_ATTR: |
2844 | rc = bfad_iocmd_port_get_bbcr_attr(bfad, pcmd: iocmd); |
2845 | break; |
2846 | case IOCMD_LPORT_GET_ATTR: |
2847 | rc = bfad_iocmd_lport_get_attr(bfad, cmd: iocmd); |
2848 | break; |
2849 | case IOCMD_LPORT_GET_STATS: |
2850 | rc = bfad_iocmd_lport_get_stats(bfad, cmd: iocmd); |
2851 | break; |
2852 | case IOCMD_LPORT_RESET_STATS: |
2853 | rc = bfad_iocmd_lport_reset_stats(bfad, cmd: iocmd); |
2854 | break; |
2855 | case IOCMD_LPORT_GET_IOSTATS: |
2856 | rc = bfad_iocmd_lport_get_iostats(bfad, cmd: iocmd); |
2857 | break; |
2858 | case IOCMD_LPORT_GET_RPORTS: |
2859 | rc = bfad_iocmd_lport_get_rports(bfad, cmd: iocmd, payload_len); |
2860 | break; |
2861 | case IOCMD_RPORT_GET_ATTR: |
2862 | rc = bfad_iocmd_rport_get_attr(bfad, cmd: iocmd); |
2863 | break; |
2864 | case IOCMD_RPORT_GET_ADDR: |
2865 | rc = bfad_iocmd_rport_get_addr(bfad, cmd: iocmd); |
2866 | break; |
2867 | case IOCMD_RPORT_GET_STATS: |
2868 | rc = bfad_iocmd_rport_get_stats(bfad, cmd: iocmd); |
2869 | break; |
2870 | case IOCMD_RPORT_RESET_STATS: |
2871 | rc = bfad_iocmd_rport_clr_stats(bfad, cmd: iocmd); |
2872 | break; |
2873 | case IOCMD_RPORT_SET_SPEED: |
2874 | rc = bfad_iocmd_rport_set_speed(bfad, cmd: iocmd); |
2875 | break; |
2876 | case IOCMD_VPORT_GET_ATTR: |
2877 | rc = bfad_iocmd_vport_get_attr(bfad, cmd: iocmd); |
2878 | break; |
2879 | case IOCMD_VPORT_GET_STATS: |
2880 | rc = bfad_iocmd_vport_get_stats(bfad, cmd: iocmd); |
2881 | break; |
2882 | case IOCMD_VPORT_RESET_STATS: |
2883 | rc = bfad_iocmd_vport_clr_stats(bfad, cmd: iocmd); |
2884 | break; |
2885 | case IOCMD_FABRIC_GET_LPORTS: |
2886 | rc = bfad_iocmd_fabric_get_lports(bfad, cmd: iocmd, payload_len); |
2887 | break; |
2888 | case IOCMD_RATELIM_ENABLE: |
2889 | case IOCMD_RATELIM_DISABLE: |
2890 | rc = bfad_iocmd_ratelim(bfad, cmd, pcmd: iocmd); |
2891 | break; |
2892 | case IOCMD_RATELIM_DEF_SPEED: |
2893 | rc = bfad_iocmd_ratelim_speed(bfad, cmd, pcmd: iocmd); |
2894 | break; |
2895 | case IOCMD_FCPIM_FAILOVER: |
2896 | rc = bfad_iocmd_cfg_fcpim(bfad, cmd: iocmd); |
2897 | break; |
2898 | case IOCMD_FCPIM_MODSTATS: |
2899 | rc = bfad_iocmd_fcpim_get_modstats(bfad, cmd: iocmd); |
2900 | break; |
2901 | case IOCMD_FCPIM_MODSTATSCLR: |
2902 | rc = bfad_iocmd_fcpim_clr_modstats(bfad, cmd: iocmd); |
2903 | break; |
2904 | case IOCMD_FCPIM_DEL_ITN_STATS: |
2905 | rc = bfad_iocmd_fcpim_get_del_itn_stats(bfad, cmd: iocmd); |
2906 | break; |
2907 | case IOCMD_ITNIM_GET_ATTR: |
2908 | rc = bfad_iocmd_itnim_get_attr(bfad, cmd: iocmd); |
2909 | break; |
2910 | case IOCMD_ITNIM_GET_IOSTATS: |
2911 | rc = bfad_iocmd_itnim_get_iostats(bfad, cmd: iocmd); |
2912 | break; |
2913 | case IOCMD_ITNIM_RESET_STATS: |
2914 | rc = bfad_iocmd_itnim_reset_stats(bfad, cmd: iocmd); |
2915 | break; |
2916 | case IOCMD_ITNIM_GET_ITNSTATS: |
2917 | rc = bfad_iocmd_itnim_get_itnstats(bfad, cmd: iocmd); |
2918 | break; |
2919 | case IOCMD_FCPORT_ENABLE: |
2920 | rc = bfad_iocmd_fcport_enable(bfad, cmd: iocmd); |
2921 | break; |
2922 | case IOCMD_FCPORT_DISABLE: |
2923 | rc = bfad_iocmd_fcport_disable(bfad, cmd: iocmd); |
2924 | break; |
2925 | case IOCMD_IOC_PCIFN_CFG: |
2926 | rc = bfad_iocmd_ioc_get_pcifn_cfg(bfad, cmd: iocmd); |
2927 | break; |
2928 | case IOCMD_IOC_FW_SIG_INV: |
2929 | rc = bfad_iocmd_ioc_fw_sig_inv(bfad, cmd: iocmd); |
2930 | break; |
2931 | case IOCMD_PCIFN_CREATE: |
2932 | rc = bfad_iocmd_pcifn_create(bfad, cmd: iocmd); |
2933 | break; |
2934 | case IOCMD_PCIFN_DELETE: |
2935 | rc = bfad_iocmd_pcifn_delete(bfad, cmd: iocmd); |
2936 | break; |
2937 | case IOCMD_PCIFN_BW: |
2938 | rc = bfad_iocmd_pcifn_bw(bfad, cmd: iocmd); |
2939 | break; |
2940 | case IOCMD_ADAPTER_CFG_MODE: |
2941 | rc = bfad_iocmd_adapter_cfg_mode(bfad, cmd: iocmd); |
2942 | break; |
2943 | case IOCMD_PORT_CFG_MODE: |
2944 | rc = bfad_iocmd_port_cfg_mode(bfad, cmd: iocmd); |
2945 | break; |
2946 | case IOCMD_FLASH_ENABLE_OPTROM: |
2947 | case IOCMD_FLASH_DISABLE_OPTROM: |
2948 | rc = bfad_iocmd_ablk_optrom(bfad, cmd, pcmd: iocmd); |
2949 | break; |
2950 | case IOCMD_FAA_QUERY: |
2951 | rc = bfad_iocmd_faa_query(bfad, cmd: iocmd); |
2952 | break; |
2953 | case IOCMD_CEE_GET_ATTR: |
2954 | rc = bfad_iocmd_cee_attr(bfad, cmd: iocmd, payload_len); |
2955 | break; |
2956 | case IOCMD_CEE_GET_STATS: |
2957 | rc = bfad_iocmd_cee_get_stats(bfad, cmd: iocmd, payload_len); |
2958 | break; |
2959 | case IOCMD_CEE_RESET_STATS: |
2960 | rc = bfad_iocmd_cee_reset_stats(bfad, cmd: iocmd); |
2961 | break; |
2962 | case IOCMD_SFP_MEDIA: |
2963 | rc = bfad_iocmd_sfp_media(bfad, cmd: iocmd); |
2964 | break; |
2965 | case IOCMD_SFP_SPEED: |
2966 | rc = bfad_iocmd_sfp_speed(bfad, cmd: iocmd); |
2967 | break; |
2968 | case IOCMD_FLASH_GET_ATTR: |
2969 | rc = bfad_iocmd_flash_get_attr(bfad, cmd: iocmd); |
2970 | break; |
2971 | case IOCMD_FLASH_ERASE_PART: |
2972 | rc = bfad_iocmd_flash_erase_part(bfad, cmd: iocmd); |
2973 | break; |
2974 | case IOCMD_FLASH_UPDATE_PART: |
2975 | rc = bfad_iocmd_flash_update_part(bfad, cmd: iocmd, payload_len); |
2976 | break; |
2977 | case IOCMD_FLASH_READ_PART: |
2978 | rc = bfad_iocmd_flash_read_part(bfad, cmd: iocmd, payload_len); |
2979 | break; |
2980 | case IOCMD_DIAG_TEMP: |
2981 | rc = bfad_iocmd_diag_temp(bfad, cmd: iocmd); |
2982 | break; |
2983 | case IOCMD_DIAG_MEMTEST: |
2984 | rc = bfad_iocmd_diag_memtest(bfad, cmd: iocmd); |
2985 | break; |
2986 | case IOCMD_DIAG_LOOPBACK: |
2987 | rc = bfad_iocmd_diag_loopback(bfad, cmd: iocmd); |
2988 | break; |
2989 | case IOCMD_DIAG_FWPING: |
2990 | rc = bfad_iocmd_diag_fwping(bfad, cmd: iocmd); |
2991 | break; |
2992 | case IOCMD_DIAG_QUEUETEST: |
2993 | rc = bfad_iocmd_diag_queuetest(bfad, cmd: iocmd); |
2994 | break; |
2995 | case IOCMD_DIAG_SFP: |
2996 | rc = bfad_iocmd_diag_sfp(bfad, cmd: iocmd); |
2997 | break; |
2998 | case IOCMD_DIAG_LED: |
2999 | rc = bfad_iocmd_diag_led(bfad, cmd: iocmd); |
3000 | break; |
3001 | case IOCMD_DIAG_BEACON_LPORT: |
3002 | rc = bfad_iocmd_diag_beacon_lport(bfad, cmd: iocmd); |
3003 | break; |
3004 | case IOCMD_DIAG_LB_STAT: |
3005 | rc = bfad_iocmd_diag_lb_stat(bfad, cmd: iocmd); |
3006 | break; |
3007 | case IOCMD_DIAG_DPORT_ENABLE: |
3008 | rc = bfad_iocmd_diag_dport_enable(bfad, pcmd: iocmd); |
3009 | break; |
3010 | case IOCMD_DIAG_DPORT_DISABLE: |
3011 | rc = bfad_iocmd_diag_dport_disable(bfad, pcmd: iocmd); |
3012 | break; |
3013 | case IOCMD_DIAG_DPORT_SHOW: |
3014 | rc = bfad_iocmd_diag_dport_show(bfad, pcmd: iocmd); |
3015 | break; |
3016 | case IOCMD_DIAG_DPORT_START: |
3017 | rc = bfad_iocmd_diag_dport_start(bfad, pcmd: iocmd); |
3018 | break; |
3019 | case IOCMD_PHY_GET_ATTR: |
3020 | rc = bfad_iocmd_phy_get_attr(bfad, cmd: iocmd); |
3021 | break; |
3022 | case IOCMD_PHY_GET_STATS: |
3023 | rc = bfad_iocmd_phy_get_stats(bfad, cmd: iocmd); |
3024 | break; |
3025 | case IOCMD_PHY_UPDATE_FW: |
3026 | rc = bfad_iocmd_phy_update(bfad, cmd: iocmd, payload_len); |
3027 | break; |
3028 | case IOCMD_PHY_READ_FW: |
3029 | rc = bfad_iocmd_phy_read(bfad, cmd: iocmd, payload_len); |
3030 | break; |
3031 | case IOCMD_VHBA_QUERY: |
3032 | rc = bfad_iocmd_vhba_query(bfad, cmd: iocmd); |
3033 | break; |
3034 | case IOCMD_DEBUG_PORTLOG: |
3035 | rc = bfad_iocmd_porglog_get(bfad, cmd: iocmd); |
3036 | break; |
3037 | case IOCMD_DEBUG_FW_CORE: |
3038 | rc = bfad_iocmd_debug_fw_core(bfad, cmd: iocmd, payload_len); |
3039 | break; |
3040 | case IOCMD_DEBUG_FW_STATE_CLR: |
3041 | case IOCMD_DEBUG_PORTLOG_CLR: |
3042 | case IOCMD_DEBUG_START_DTRC: |
3043 | case IOCMD_DEBUG_STOP_DTRC: |
3044 | rc = bfad_iocmd_debug_ctl(bfad, cmd: iocmd, v_cmd: cmd); |
3045 | break; |
3046 | case IOCMD_DEBUG_PORTLOG_CTL: |
3047 | rc = bfad_iocmd_porglog_ctl(bfad, cmd: iocmd); |
3048 | break; |
3049 | case IOCMD_FCPIM_PROFILE_ON: |
3050 | case IOCMD_FCPIM_PROFILE_OFF: |
3051 | rc = bfad_iocmd_fcpim_cfg_profile(bfad, cmd: iocmd, v_cmd: cmd); |
3052 | break; |
3053 | case IOCMD_ITNIM_GET_IOPROFILE: |
3054 | rc = bfad_iocmd_itnim_get_ioprofile(bfad, cmd: iocmd); |
3055 | break; |
3056 | case IOCMD_FCPORT_GET_STATS: |
3057 | rc = bfad_iocmd_fcport_get_stats(bfad, cmd: iocmd); |
3058 | break; |
3059 | case IOCMD_FCPORT_RESET_STATS: |
3060 | rc = bfad_iocmd_fcport_reset_stats(bfad, cmd: iocmd); |
3061 | break; |
3062 | case IOCMD_BOOT_CFG: |
3063 | rc = bfad_iocmd_boot_cfg(bfad, cmd: iocmd); |
3064 | break; |
3065 | case IOCMD_BOOT_QUERY: |
3066 | rc = bfad_iocmd_boot_query(bfad, cmd: iocmd); |
3067 | break; |
3068 | case IOCMD_PREBOOT_QUERY: |
3069 | rc = bfad_iocmd_preboot_query(bfad, cmd: iocmd); |
3070 | break; |
3071 | case IOCMD_ETHBOOT_CFG: |
3072 | rc = bfad_iocmd_ethboot_cfg(bfad, cmd: iocmd); |
3073 | break; |
3074 | case IOCMD_ETHBOOT_QUERY: |
3075 | rc = bfad_iocmd_ethboot_query(bfad, cmd: iocmd); |
3076 | break; |
3077 | case IOCMD_TRUNK_ENABLE: |
3078 | case IOCMD_TRUNK_DISABLE: |
3079 | rc = bfad_iocmd_cfg_trunk(bfad, cmd: iocmd, v_cmd: cmd); |
3080 | break; |
3081 | case IOCMD_TRUNK_GET_ATTR: |
3082 | rc = bfad_iocmd_trunk_get_attr(bfad, cmd: iocmd); |
3083 | break; |
3084 | case IOCMD_QOS_ENABLE: |
3085 | case IOCMD_QOS_DISABLE: |
3086 | rc = bfad_iocmd_qos(bfad, cmd: iocmd, v_cmd: cmd); |
3087 | break; |
3088 | case IOCMD_QOS_GET_ATTR: |
3089 | rc = bfad_iocmd_qos_get_attr(bfad, cmd: iocmd); |
3090 | break; |
3091 | case IOCMD_QOS_GET_VC_ATTR: |
3092 | rc = bfad_iocmd_qos_get_vc_attr(bfad, cmd: iocmd); |
3093 | break; |
3094 | case IOCMD_QOS_GET_STATS: |
3095 | rc = bfad_iocmd_qos_get_stats(bfad, cmd: iocmd); |
3096 | break; |
3097 | case IOCMD_QOS_RESET_STATS: |
3098 | rc = bfad_iocmd_qos_reset_stats(bfad, cmd: iocmd); |
3099 | break; |
3100 | case IOCMD_QOS_SET_BW: |
3101 | rc = bfad_iocmd_qos_set_bw(bfad, pcmd: iocmd); |
3102 | break; |
3103 | case IOCMD_VF_GET_STATS: |
3104 | rc = bfad_iocmd_vf_get_stats(bfad, cmd: iocmd); |
3105 | break; |
3106 | case IOCMD_VF_RESET_STATS: |
3107 | rc = bfad_iocmd_vf_clr_stats(bfad, cmd: iocmd); |
3108 | break; |
3109 | case IOCMD_FCPIM_LUNMASK_ENABLE: |
3110 | case IOCMD_FCPIM_LUNMASK_DISABLE: |
3111 | case IOCMD_FCPIM_LUNMASK_CLEAR: |
3112 | rc = bfad_iocmd_lunmask(bfad, pcmd: iocmd, v_cmd: cmd); |
3113 | break; |
3114 | case IOCMD_FCPIM_LUNMASK_QUERY: |
3115 | rc = bfad_iocmd_fcpim_lunmask_query(bfad, cmd: iocmd); |
3116 | break; |
3117 | case IOCMD_FCPIM_LUNMASK_ADD: |
3118 | case IOCMD_FCPIM_LUNMASK_DELETE: |
3119 | rc = bfad_iocmd_fcpim_cfg_lunmask(bfad, cmd: iocmd, v_cmd: cmd); |
3120 | break; |
3121 | case IOCMD_FCPIM_THROTTLE_QUERY: |
3122 | rc = bfad_iocmd_fcpim_throttle_query(bfad, cmd: iocmd); |
3123 | break; |
3124 | case IOCMD_FCPIM_THROTTLE_SET: |
3125 | rc = bfad_iocmd_fcpim_throttle_set(bfad, cmd: iocmd); |
3126 | break; |
3127 | /* TFRU */ |
3128 | case IOCMD_TFRU_READ: |
3129 | rc = bfad_iocmd_tfru_read(bfad, cmd: iocmd); |
3130 | break; |
3131 | case IOCMD_TFRU_WRITE: |
3132 | rc = bfad_iocmd_tfru_write(bfad, cmd: iocmd); |
3133 | break; |
3134 | /* FRU */ |
3135 | case IOCMD_FRUVPD_READ: |
3136 | rc = bfad_iocmd_fruvpd_read(bfad, cmd: iocmd); |
3137 | break; |
3138 | case IOCMD_FRUVPD_UPDATE: |
3139 | rc = bfad_iocmd_fruvpd_update(bfad, cmd: iocmd); |
3140 | break; |
3141 | case IOCMD_FRUVPD_GET_MAX_SIZE: |
3142 | rc = bfad_iocmd_fruvpd_get_max_size(bfad, cmd: iocmd); |
3143 | break; |
3144 | default: |
3145 | rc = -EINVAL; |
3146 | break; |
3147 | } |
3148 | return rc; |
3149 | } |
3150 | |
3151 | static int |
3152 | bfad_im_bsg_vendor_request(struct bsg_job *job) |
3153 | { |
3154 | struct fc_bsg_request *bsg_request = job->request; |
3155 | struct fc_bsg_reply *bsg_reply = job->reply; |
3156 | uint32_t vendor_cmd = bsg_request->rqst_data.h_vendor.vendor_cmd[0]; |
3157 | struct Scsi_Host *shost = fc_bsg_to_shost(job); |
3158 | struct bfad_im_port_s *im_port = bfad_get_im_port(host: shost); |
3159 | struct bfad_s *bfad = im_port->bfad; |
3160 | void *payload_kbuf; |
3161 | int rc = -EINVAL; |
3162 | |
3163 | /* Allocate a temp buffer to hold the passed in user space command */ |
3164 | payload_kbuf = kzalloc(size: job->request_payload.payload_len, GFP_KERNEL); |
3165 | if (!payload_kbuf) { |
3166 | rc = -ENOMEM; |
3167 | goto out; |
3168 | } |
3169 | |
3170 | /* Copy the sg_list passed in to a linear buffer: holds the cmnd data */ |
3171 | sg_copy_to_buffer(sgl: job->request_payload.sg_list, |
3172 | nents: job->request_payload.sg_cnt, buf: payload_kbuf, |
3173 | buflen: job->request_payload.payload_len); |
3174 | |
3175 | /* Invoke IOCMD handler - to handle all the vendor command requests */ |
3176 | rc = bfad_iocmd_handler(bfad, cmd: vendor_cmd, iocmd: payload_kbuf, |
3177 | payload_len: job->request_payload.payload_len); |
3178 | if (rc != BFA_STATUS_OK) |
3179 | goto error; |
3180 | |
3181 | /* Copy the response data to the job->reply_payload sg_list */ |
3182 | sg_copy_from_buffer(sgl: job->reply_payload.sg_list, |
3183 | nents: job->reply_payload.sg_cnt, |
3184 | buf: payload_kbuf, |
3185 | buflen: job->reply_payload.payload_len); |
3186 | |
3187 | /* free the command buffer */ |
3188 | kfree(objp: payload_kbuf); |
3189 | |
3190 | /* Fill the BSG job reply data */ |
3191 | job->reply_len = job->reply_payload.payload_len; |
3192 | bsg_reply->reply_payload_rcv_len = job->reply_payload.payload_len; |
3193 | bsg_reply->result = rc; |
3194 | |
3195 | bsg_job_done(job, result: bsg_reply->result, |
3196 | reply_payload_rcv_len: bsg_reply->reply_payload_rcv_len); |
3197 | return rc; |
3198 | error: |
3199 | /* free the command buffer */ |
3200 | kfree(objp: payload_kbuf); |
3201 | out: |
3202 | bsg_reply->result = rc; |
3203 | job->reply_len = sizeof(uint32_t); |
3204 | bsg_reply->reply_payload_rcv_len = 0; |
3205 | return rc; |
3206 | } |
3207 | |
3208 | /* FC passthru call backs */ |
3209 | static u64 |
3210 | bfad_fcxp_get_req_sgaddr_cb(void *bfad_fcxp, int sgeid) |
3211 | { |
3212 | struct bfad_fcxp *drv_fcxp = bfad_fcxp; |
3213 | struct bfa_sge_s *sge; |
3214 | u64 addr; |
3215 | |
3216 | sge = drv_fcxp->req_sge + sgeid; |
3217 | addr = (u64)(size_t) sge->sg_addr; |
3218 | return addr; |
3219 | } |
3220 | |
3221 | static u32 |
3222 | bfad_fcxp_get_req_sglen_cb(void *bfad_fcxp, int sgeid) |
3223 | { |
3224 | struct bfad_fcxp *drv_fcxp = bfad_fcxp; |
3225 | struct bfa_sge_s *sge; |
3226 | |
3227 | sge = drv_fcxp->req_sge + sgeid; |
3228 | return sge->sg_len; |
3229 | } |
3230 | |
3231 | static u64 |
3232 | bfad_fcxp_get_rsp_sgaddr_cb(void *bfad_fcxp, int sgeid) |
3233 | { |
3234 | struct bfad_fcxp *drv_fcxp = bfad_fcxp; |
3235 | struct bfa_sge_s *sge; |
3236 | u64 addr; |
3237 | |
3238 | sge = drv_fcxp->rsp_sge + sgeid; |
3239 | addr = (u64)(size_t) sge->sg_addr; |
3240 | return addr; |
3241 | } |
3242 | |
3243 | static u32 |
3244 | bfad_fcxp_get_rsp_sglen_cb(void *bfad_fcxp, int sgeid) |
3245 | { |
3246 | struct bfad_fcxp *drv_fcxp = bfad_fcxp; |
3247 | struct bfa_sge_s *sge; |
3248 | |
3249 | sge = drv_fcxp->rsp_sge + sgeid; |
3250 | return sge->sg_len; |
3251 | } |
3252 | |
3253 | static void |
3254 | bfad_send_fcpt_cb(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg, |
3255 | bfa_status_t req_status, u32 rsp_len, u32 resid_len, |
3256 | struct fchs_s *rsp_fchs) |
3257 | { |
3258 | struct bfad_fcxp *drv_fcxp = bfad_fcxp; |
3259 | |
3260 | drv_fcxp->req_status = req_status; |
3261 | drv_fcxp->rsp_len = rsp_len; |
3262 | |
3263 | /* bfa_fcxp will be automatically freed by BFA */ |
3264 | drv_fcxp->bfa_fcxp = NULL; |
3265 | complete(&drv_fcxp->comp); |
3266 | } |
3267 | |
3268 | static struct bfad_buf_info * |
3269 | bfad_fcxp_map_sg(struct bfad_s *bfad, void *payload_kbuf, |
3270 | uint32_t payload_len, uint32_t *num_sgles) |
3271 | { |
3272 | struct bfad_buf_info *buf_base, *buf_info; |
3273 | struct bfa_sge_s *sg_table; |
3274 | int sge_num = 1; |
3275 | |
3276 | buf_base = kcalloc(n: sizeof(struct bfad_buf_info) + |
3277 | sizeof(struct bfa_sge_s), |
3278 | size: sge_num, GFP_KERNEL); |
3279 | if (!buf_base) |
3280 | return NULL; |
3281 | |
3282 | sg_table = (struct bfa_sge_s *) (((uint8_t *)buf_base) + |
3283 | (sizeof(struct bfad_buf_info) * sge_num)); |
3284 | |
3285 | /* Allocate dma coherent memory */ |
3286 | buf_info = buf_base; |
3287 | buf_info->size = payload_len; |
3288 | buf_info->virt = dma_alloc_coherent(dev: &bfad->pcidev->dev, |
3289 | size: buf_info->size, dma_handle: &buf_info->phys, |
3290 | GFP_KERNEL); |
3291 | if (!buf_info->virt) |
3292 | goto out_free_mem; |
3293 | |
3294 | /* copy the linear bsg buffer to buf_info */ |
3295 | memcpy(buf_info->virt, payload_kbuf, buf_info->size); |
3296 | |
3297 | /* |
3298 | * Setup SG table |
3299 | */ |
3300 | sg_table->sg_len = buf_info->size; |
3301 | sg_table->sg_addr = (void *)(size_t) buf_info->phys; |
3302 | |
3303 | *num_sgles = sge_num; |
3304 | |
3305 | return buf_base; |
3306 | |
3307 | out_free_mem: |
3308 | kfree(objp: buf_base); |
3309 | return NULL; |
3310 | } |
3311 | |
3312 | static void |
3313 | bfad_fcxp_free_mem(struct bfad_s *bfad, struct bfad_buf_info *buf_base, |
3314 | uint32_t num_sgles) |
3315 | { |
3316 | int i; |
3317 | struct bfad_buf_info *buf_info = buf_base; |
3318 | |
3319 | if (buf_base) { |
3320 | for (i = 0; i < num_sgles; buf_info++, i++) { |
3321 | if (buf_info->virt != NULL) |
3322 | dma_free_coherent(dev: &bfad->pcidev->dev, |
3323 | size: buf_info->size, cpu_addr: buf_info->virt, |
3324 | dma_handle: buf_info->phys); |
3325 | } |
3326 | kfree(objp: buf_base); |
3327 | } |
3328 | } |
3329 | |
3330 | static int |
3331 | bfad_fcxp_bsg_send(struct bsg_job *job, struct bfad_fcxp *drv_fcxp, |
3332 | bfa_bsg_fcpt_t *bsg_fcpt) |
3333 | { |
3334 | struct bfa_fcxp_s *hal_fcxp; |
3335 | struct bfad_s *bfad = drv_fcxp->port->bfad; |
3336 | unsigned long flags; |
3337 | uint8_t lp_tag; |
3338 | |
3339 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
3340 | |
3341 | /* Allocate bfa_fcxp structure */ |
3342 | hal_fcxp = bfa_fcxp_req_rsp_alloc(bfad_fcxp: drv_fcxp, bfa: &bfad->bfa, |
3343 | nreq_sgles: drv_fcxp->num_req_sgles, |
3344 | nrsp_sgles: drv_fcxp->num_rsp_sgles, |
3345 | get_req_sga: bfad_fcxp_get_req_sgaddr_cb, |
3346 | get_req_sglen: bfad_fcxp_get_req_sglen_cb, |
3347 | get_rsp_sga: bfad_fcxp_get_rsp_sgaddr_cb, |
3348 | get_rsp_sglen: bfad_fcxp_get_rsp_sglen_cb, req: BFA_TRUE); |
3349 | if (!hal_fcxp) { |
3350 | bfa_trc(bfad, 0); |
3351 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
3352 | return BFA_STATUS_ENOMEM; |
3353 | } |
3354 | |
3355 | drv_fcxp->bfa_fcxp = hal_fcxp; |
3356 | |
3357 | lp_tag = bfa_lps_get_tag_from_pid(bfa: &bfad->bfa, pid: bsg_fcpt->fchs.s_id); |
3358 | |
3359 | bfa_fcxp_send(fcxp: hal_fcxp, rport: drv_fcxp->bfa_rport, vf_id: bsg_fcpt->vf_id, lp_tag, |
3360 | cts: bsg_fcpt->cts, cos: bsg_fcpt->cos, |
3361 | reqlen: job->request_payload.payload_len, |
3362 | fchs: &bsg_fcpt->fchs, cbfn: bfad_send_fcpt_cb, cbarg: bfad, |
3363 | rsp_maxlen: job->reply_payload.payload_len, rsp_timeout: bsg_fcpt->tsecs); |
3364 | |
3365 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
3366 | |
3367 | return BFA_STATUS_OK; |
3368 | } |
3369 | |
3370 | static int |
3371 | bfad_im_bsg_els_ct_request(struct bsg_job *job) |
3372 | { |
3373 | struct bfa_bsg_data *bsg_data; |
3374 | struct Scsi_Host *shost = fc_bsg_to_shost(job); |
3375 | struct bfad_im_port_s *im_port = bfad_get_im_port(host: shost); |
3376 | struct bfad_s *bfad = im_port->bfad; |
3377 | bfa_bsg_fcpt_t *bsg_fcpt; |
3378 | struct bfad_fcxp *drv_fcxp; |
3379 | struct bfa_fcs_lport_s *fcs_port; |
3380 | struct bfa_fcs_rport_s *fcs_rport; |
3381 | struct fc_bsg_request *bsg_request = job->request; |
3382 | struct fc_bsg_reply *bsg_reply = job->reply; |
3383 | uint32_t command_type = bsg_request->msgcode; |
3384 | unsigned long flags; |
3385 | struct bfad_buf_info *rsp_buf_info; |
3386 | void *req_kbuf = NULL, *rsp_kbuf = NULL; |
3387 | int rc = -EINVAL; |
3388 | |
3389 | job->reply_len = sizeof(uint32_t); /* Atleast uint32_t reply_len */ |
3390 | bsg_reply->reply_payload_rcv_len = 0; |
3391 | |
3392 | /* Get the payload passed in from userspace */ |
3393 | bsg_data = (struct bfa_bsg_data *) (((char *)bsg_request) + |
3394 | sizeof(struct fc_bsg_request)); |
3395 | if (bsg_data == NULL) |
3396 | goto out; |
3397 | |
3398 | /* |
3399 | * Allocate buffer for bsg_fcpt and do a copy_from_user op for payload |
3400 | * buffer of size bsg_data->payload_len |
3401 | */ |
3402 | bsg_fcpt = kzalloc(size: bsg_data->payload_len, GFP_KERNEL); |
3403 | if (!bsg_fcpt) { |
3404 | rc = -ENOMEM; |
3405 | goto out; |
3406 | } |
3407 | |
3408 | if (copy_from_user(to: (uint8_t *)bsg_fcpt, |
3409 | from: (void *)(unsigned long)bsg_data->payload, |
3410 | n: bsg_data->payload_len)) { |
3411 | kfree(objp: bsg_fcpt); |
3412 | rc = -EIO; |
3413 | goto out; |
3414 | } |
3415 | |
3416 | drv_fcxp = kzalloc(size: sizeof(struct bfad_fcxp), GFP_KERNEL); |
3417 | if (drv_fcxp == NULL) { |
3418 | kfree(objp: bsg_fcpt); |
3419 | rc = -ENOMEM; |
3420 | goto out; |
3421 | } |
3422 | |
3423 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
3424 | fcs_port = bfa_fcs_lookup_port(fcs: &bfad->bfa_fcs, vf_id: bsg_fcpt->vf_id, |
3425 | lpwwn: bsg_fcpt->lpwwn); |
3426 | if (fcs_port == NULL) { |
3427 | bsg_fcpt->status = BFA_STATUS_UNKNOWN_LWWN; |
3428 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
3429 | goto out_free_mem; |
3430 | } |
3431 | |
3432 | /* Check if the port is online before sending FC Passthru cmd */ |
3433 | if (!bfa_fcs_lport_is_online(port: fcs_port)) { |
3434 | bsg_fcpt->status = BFA_STATUS_PORT_OFFLINE; |
3435 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
3436 | goto out_free_mem; |
3437 | } |
3438 | |
3439 | drv_fcxp->port = fcs_port->bfad_port; |
3440 | |
3441 | if (!drv_fcxp->port->bfad) |
3442 | drv_fcxp->port->bfad = bfad; |
3443 | |
3444 | /* Fetch the bfa_rport - if nexus needed */ |
3445 | if (command_type == FC_BSG_HST_ELS_NOLOGIN || |
3446 | command_type == FC_BSG_HST_CT) { |
3447 | /* BSG HST commands: no nexus needed */ |
3448 | drv_fcxp->bfa_rport = NULL; |
3449 | |
3450 | } else if (command_type == FC_BSG_RPT_ELS || |
3451 | command_type == FC_BSG_RPT_CT) { |
3452 | /* BSG RPT commands: nexus needed */ |
3453 | fcs_rport = bfa_fcs_lport_get_rport_by_pwwn(port: fcs_port, |
3454 | pwwn: bsg_fcpt->dpwwn); |
3455 | if (fcs_rport == NULL) { |
3456 | bsg_fcpt->status = BFA_STATUS_UNKNOWN_RWWN; |
3457 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
3458 | goto out_free_mem; |
3459 | } |
3460 | |
3461 | drv_fcxp->bfa_rport = fcs_rport->bfa_rport; |
3462 | |
3463 | } else { /* Unknown BSG msgcode; return -EINVAL */ |
3464 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
3465 | goto out_free_mem; |
3466 | } |
3467 | |
3468 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
3469 | |
3470 | /* allocate memory for req / rsp buffers */ |
3471 | req_kbuf = kzalloc(size: job->request_payload.payload_len, GFP_KERNEL); |
3472 | if (!req_kbuf) { |
3473 | printk(KERN_INFO "bfa %s: fcpt request buffer alloc failed\n" , |
3474 | bfad->pci_name); |
3475 | rc = -ENOMEM; |
3476 | goto out_free_mem; |
3477 | } |
3478 | |
3479 | rsp_kbuf = kzalloc(size: job->reply_payload.payload_len, GFP_KERNEL); |
3480 | if (!rsp_kbuf) { |
3481 | printk(KERN_INFO "bfa %s: fcpt response buffer alloc failed\n" , |
3482 | bfad->pci_name); |
3483 | rc = -ENOMEM; |
3484 | goto out_free_mem; |
3485 | } |
3486 | |
3487 | /* map req sg - copy the sg_list passed in to the linear buffer */ |
3488 | sg_copy_to_buffer(sgl: job->request_payload.sg_list, |
3489 | nents: job->request_payload.sg_cnt, buf: req_kbuf, |
3490 | buflen: job->request_payload.payload_len); |
3491 | |
3492 | drv_fcxp->reqbuf_info = bfad_fcxp_map_sg(bfad, payload_kbuf: req_kbuf, |
3493 | payload_len: job->request_payload.payload_len, |
3494 | num_sgles: &drv_fcxp->num_req_sgles); |
3495 | if (!drv_fcxp->reqbuf_info) { |
3496 | printk(KERN_INFO "bfa %s: fcpt request fcxp_map_sg failed\n" , |
3497 | bfad->pci_name); |
3498 | rc = -ENOMEM; |
3499 | goto out_free_mem; |
3500 | } |
3501 | |
3502 | drv_fcxp->req_sge = (struct bfa_sge_s *) |
3503 | (((uint8_t *)drv_fcxp->reqbuf_info) + |
3504 | (sizeof(struct bfad_buf_info) * |
3505 | drv_fcxp->num_req_sgles)); |
3506 | |
3507 | /* map rsp sg */ |
3508 | drv_fcxp->rspbuf_info = bfad_fcxp_map_sg(bfad, payload_kbuf: rsp_kbuf, |
3509 | payload_len: job->reply_payload.payload_len, |
3510 | num_sgles: &drv_fcxp->num_rsp_sgles); |
3511 | if (!drv_fcxp->rspbuf_info) { |
3512 | printk(KERN_INFO "bfa %s: fcpt response fcxp_map_sg failed\n" , |
3513 | bfad->pci_name); |
3514 | rc = -ENOMEM; |
3515 | goto out_free_mem; |
3516 | } |
3517 | |
3518 | rsp_buf_info = (struct bfad_buf_info *)drv_fcxp->rspbuf_info; |
3519 | drv_fcxp->rsp_sge = (struct bfa_sge_s *) |
3520 | (((uint8_t *)drv_fcxp->rspbuf_info) + |
3521 | (sizeof(struct bfad_buf_info) * |
3522 | drv_fcxp->num_rsp_sgles)); |
3523 | |
3524 | /* fcxp send */ |
3525 | init_completion(x: &drv_fcxp->comp); |
3526 | rc = bfad_fcxp_bsg_send(job, drv_fcxp, bsg_fcpt); |
3527 | if (rc == BFA_STATUS_OK) { |
3528 | wait_for_completion(&drv_fcxp->comp); |
3529 | bsg_fcpt->status = drv_fcxp->req_status; |
3530 | } else { |
3531 | bsg_fcpt->status = rc; |
3532 | goto out_free_mem; |
3533 | } |
3534 | |
3535 | /* fill the job->reply data */ |
3536 | if (drv_fcxp->req_status == BFA_STATUS_OK) { |
3537 | job->reply_len = drv_fcxp->rsp_len; |
3538 | bsg_reply->reply_payload_rcv_len = drv_fcxp->rsp_len; |
3539 | bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK; |
3540 | } else { |
3541 | bsg_reply->reply_payload_rcv_len = |
3542 | sizeof(struct fc_bsg_ctels_reply); |
3543 | job->reply_len = sizeof(uint32_t); |
3544 | bsg_reply->reply_data.ctels_reply.status = |
3545 | FC_CTELS_STATUS_REJECT; |
3546 | } |
3547 | |
3548 | /* Copy the response data to the reply_payload sg list */ |
3549 | sg_copy_from_buffer(sgl: job->reply_payload.sg_list, |
3550 | nents: job->reply_payload.sg_cnt, |
3551 | buf: (uint8_t *)rsp_buf_info->virt, |
3552 | buflen: job->reply_payload.payload_len); |
3553 | |
3554 | out_free_mem: |
3555 | bfad_fcxp_free_mem(bfad, buf_base: drv_fcxp->rspbuf_info, |
3556 | num_sgles: drv_fcxp->num_rsp_sgles); |
3557 | bfad_fcxp_free_mem(bfad, buf_base: drv_fcxp->reqbuf_info, |
3558 | num_sgles: drv_fcxp->num_req_sgles); |
3559 | kfree(objp: req_kbuf); |
3560 | kfree(objp: rsp_kbuf); |
3561 | |
3562 | /* Need a copy to user op */ |
3563 | if (copy_to_user(to: (void *)(unsigned long)bsg_data->payload, |
3564 | from: (void *)bsg_fcpt, n: bsg_data->payload_len)) |
3565 | rc = -EIO; |
3566 | |
3567 | kfree(objp: bsg_fcpt); |
3568 | kfree(objp: drv_fcxp); |
3569 | out: |
3570 | bsg_reply->result = rc; |
3571 | |
3572 | if (rc == BFA_STATUS_OK) |
3573 | bsg_job_done(job, result: bsg_reply->result, |
3574 | reply_payload_rcv_len: bsg_reply->reply_payload_rcv_len); |
3575 | |
3576 | return rc; |
3577 | } |
3578 | |
3579 | int |
3580 | bfad_im_bsg_request(struct bsg_job *job) |
3581 | { |
3582 | struct fc_bsg_request *bsg_request = job->request; |
3583 | struct fc_bsg_reply *bsg_reply = job->reply; |
3584 | uint32_t rc = BFA_STATUS_OK; |
3585 | |
3586 | switch (bsg_request->msgcode) { |
3587 | case FC_BSG_HST_VENDOR: |
3588 | /* Process BSG HST Vendor requests */ |
3589 | rc = bfad_im_bsg_vendor_request(job); |
3590 | break; |
3591 | case FC_BSG_HST_ELS_NOLOGIN: |
3592 | case FC_BSG_RPT_ELS: |
3593 | case FC_BSG_HST_CT: |
3594 | case FC_BSG_RPT_CT: |
3595 | /* Process BSG ELS/CT commands */ |
3596 | rc = bfad_im_bsg_els_ct_request(job); |
3597 | break; |
3598 | default: |
3599 | bsg_reply->result = rc = -EINVAL; |
3600 | bsg_reply->reply_payload_rcv_len = 0; |
3601 | break; |
3602 | } |
3603 | |
3604 | return rc; |
3605 | } |
3606 | |
3607 | int |
3608 | bfad_im_bsg_timeout(struct bsg_job *job) |
3609 | { |
3610 | /* Don't complete the BSG job request - return -EAGAIN |
3611 | * to reset bsg job timeout : for ELS/CT pass thru we |
3612 | * already have timer to track the request. |
3613 | */ |
3614 | return -EAGAIN; |
3615 | } |
3616 | |