Commit | Line | Data |
---|---|---|
52fa7bf9 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
b85daafe | 2 | /* |
889d0d42 AG |
3 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
4 | * Copyright (c) 2014- QLogic Corporation. | |
b85daafe | 5 | * All rights reserved |
889d0d42 | 6 | * www.qlogic.com |
b85daafe | 7 | * |
31e1d569 | 8 | * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. |
b85daafe KG |
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 | ||
3bbd8ef9 | 18 | static int |
60138066 KG |
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; | |
60138066 KG |
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(&bfad->bfa.ioc)) { | |
27 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1a1297c6 | 28 | iocmd->status = BFA_STATUS_OK; |
0e772b33 | 29 | return 0; |
60138066 KG |
30 | } |
31 | ||
32 | init_completion(&bfad->enable_comp); | |
33 | bfa_iocfc_enable(&bfad->bfa); | |
34 | iocmd->status = BFA_STATUS_OK; | |
35 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
36 | wait_for_completion(&bfad->enable_comp); | |
37 | ||
0e772b33 | 38 | return 0; |
60138066 KG |
39 | } |
40 | ||
3bbd8ef9 | 41 | static int |
60138066 KG |
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; | |
60138066 KG |
45 | unsigned long flags; |
46 | ||
47 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1a1297c6 KG |
48 | if (bfa_ioc_is_disabled(&bfad->bfa.ioc)) { |
49 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
50 | iocmd->status = BFA_STATUS_OK; | |
0e772b33 | 51 | return 0; |
1a1297c6 KG |
52 | } |
53 | ||
60138066 KG |
54 | if (bfad->disable_active) { |
55 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
9afbcfab | 56 | return -EBUSY; |
60138066 KG |
57 | } |
58 | ||
59 | bfad->disable_active = BFA_TRUE; | |
60 | init_completion(&bfad->disable_comp); | |
61 | bfa_iocfc_disable(&bfad->bfa); | |
62 | spin_unlock_irqrestore(&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 | ||
0e772b33 | 68 | return 0; |
60138066 KG |
69 | } |
70 | ||
b85daafe KG |
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(&bfad->bfa, &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; | |
7826f304 | 90 | iocmd->bfad_num = bfad->inst_no; |
b85daafe KG |
91 | im_port = bfad->pport.im_port; |
92 | iocmd->host = im_port->shost->host_no; | |
93 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
94 | ||
95 | strcpy(iocmd->name, bfad->adapter_name); | |
96 | strcpy(iocmd->port_name, bfad->port_name); | |
97 | strcpy(iocmd->hwpath, bfad->pci_name); | |
98 | ||
99 | /* set adapter hw path */ | |
100 | strcpy(iocmd->adapter_hwpath, bfad->pci_name); | |
e6826c96 KG |
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 | ; | |
b85daafe KG |
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(&bfad->bfa.ioc, &iocmd->ioc_attr); | |
118 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
119 | ||
120 | /* fill in driver attr info */ | |
121 | strcpy(iocmd->ioc_attr.driver_attr.driver, BFAD_DRIVER_NAME); | |
973464fd | 122 | strscpy(iocmd->ioc_attr.driver_attr.driver_ver, |
b85daafe KG |
123 | BFAD_DRIVER_VERSION, BFA_VERSION_LEN); |
124 | strcpy(iocmd->ioc_attr.driver_attr.fw_ver, | |
125 | iocmd->ioc_attr.adapter_attr.fw_ver); | |
126 | strcpy(iocmd->ioc_attr.driver_attr.bios_ver, | |
127 | 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 | ||
10202648 | 139 | static int |
60138066 KG |
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 | ||
3bbd8ef9 | 149 | static int |
60138066 KG |
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(&bfad->bfa.ioc, iocmd_bufptr); | |
168 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 179 | static int |
f2ee7601 KG |
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(&bfad->bfa.ioc); | |
191 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
192 | } | |
193 | ||
194 | return 0; | |
195 | } | |
196 | ||
3bbd8ef9 | 197 | static int |
f2ee7601 KG |
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(bfad->adapter_name, iocmd->name); | |
204 | else if (v_cmd == IOCMD_IOC_SET_PORT_NAME) | |
205 | strcpy(bfad->port_name, iocmd->name); | |
206 | ||
207 | iocmd->status = BFA_STATUS_OK; | |
208 | return 0; | |
209 | } | |
210 | ||
3bbd8ef9 | 211 | static int |
60138066 KG |
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(&bfad->bfa, &iocmd->iocfc_attr); | |
218 | ||
219 | return 0; | |
220 | } | |
221 | ||
3bbd8ef9 | 222 | static int |
28d358d0 VMG |
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(&bfad->bfa.ioc); | |
230 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
231 | return 0; | |
232 | } | |
233 | ||
3bbd8ef9 | 234 | static int |
60138066 KG |
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(&bfad->bfa, &iocmd->attr); | |
242 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
243 | ||
244 | return 0; | |
245 | } | |
246 | ||
3bbd8ef9 | 247 | static int |
60138066 KG |
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(&fcomp.comp); | |
255 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
256 | iocmd->status = bfa_port_enable(&bfad->bfa.modules.port, | |
257 | bfad_hcb_comp, &fcomp); | |
258 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 268 | static int |
60138066 KG |
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(&fcomp.comp); | |
276 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
277 | iocmd->status = bfa_port_disable(&bfad->bfa.modules.port, | |
278 | bfad_hcb_comp, &fcomp); | |
279 | spin_unlock_irqrestore(&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 | ||
b85daafe KG |
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(&bfad->bfa, &iocmd->attr); | |
299 | bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr); | |
300 | spin_unlock_irqrestore(&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; | |
973464fd | 310 | strscpy(iocmd->attr.port_symname.symname, |
b85daafe | 311 | port_attr.port_cfg.sym_name.symname, |
8c5a50e8 | 312 | sizeof(iocmd->attr.port_symname.symname)); |
b85daafe KG |
313 | |
314 | iocmd->status = BFA_STATUS_OK; | |
315 | return 0; | |
316 | } | |
317 | ||
3bbd8ef9 | 318 | static int |
60138066 KG |
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(&fcomp.comp); | |
337 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
338 | iocmd->status = bfa_port_get_stats(&bfad->bfa.modules.port, | |
339 | iocmd_bufptr, bfad_hcb_comp, &fcomp); | |
340 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 352 | static int |
f2ee7601 KG |
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(&fcomp.comp); | |
360 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
361 | iocmd->status = bfa_port_clear_stats(&bfad->bfa.modules.port, | |
362 | bfad_hcb_comp, &fcomp); | |
363 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 373 | static int |
f2ee7601 KG |
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(&bfad->bfa, cmd->param); | |
382 | else if (v_cmd == IOCMD_PORT_CFG_SPEED) | |
383 | cmd->status = bfa_fcport_cfg_speed(&bfad->bfa, cmd->param); | |
384 | else if (v_cmd == IOCMD_PORT_CFG_ALPA) | |
385 | cmd->status = bfa_fcport_cfg_hardalpa(&bfad->bfa, cmd->param); | |
386 | else if (v_cmd == IOCMD_PORT_CLR_ALPA) | |
387 | cmd->status = bfa_fcport_clr_hardalpa(&bfad->bfa); | |
388 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
389 | ||
390 | return 0; | |
391 | } | |
392 | ||
3bbd8ef9 | 393 | static int |
f2ee7601 KG |
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(&bfad->bfa, iocmd->maxfrsize); | |
402 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
403 | ||
404 | return 0; | |
405 | } | |
406 | ||
3bbd8ef9 | 407 | static int |
bbe37a67 | 408 | bfad_iocmd_port_cfg_bbcr(struct bfad_s *bfad, unsigned int cmd, void *pcmd) |
f2ee7601 | 409 | { |
bbe37a67 VMG |
410 | struct bfa_bsg_bbcr_enable_s *iocmd = |
411 | (struct bfa_bsg_bbcr_enable_s *)pcmd; | |
412 | unsigned long flags; | |
413 | int rc; | |
f2ee7601 KG |
414 | |
415 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
bbe37a67 VMG |
416 | if (cmd == IOCMD_PORT_BBCR_ENABLE) |
417 | rc = bfa_fcport_cfg_bbcr(&bfad->bfa, BFA_TRUE, iocmd->bb_scn); | |
418 | else if (cmd == IOCMD_PORT_BBCR_DISABLE) | |
419 | rc = bfa_fcport_cfg_bbcr(&bfad->bfa, BFA_FALSE, 0); | |
420 | else { | |
421 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
422 | return -EINVAL; | |
f2ee7601 KG |
423 | } |
424 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
425 | ||
bbe37a67 | 426 | iocmd->status = rc; |
f2ee7601 KG |
427 | return 0; |
428 | } | |
429 | ||
3bbd8ef9 | 430 | static int |
bbe37a67 VMG |
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(&bfad->bfa, &iocmd->attr); | |
439 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
440 | ||
441 | return 0; | |
442 | } | |
443 | ||
444 | ||
b85daafe KG |
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(&bfad->bfa_fcs, | |
454 | iocmd->vf_id, iocmd->pwwn); | |
455 | if (fcs_port == NULL) { | |
456 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
457 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; | |
458 | goto out; | |
459 | } | |
460 | ||
461 | bfa_fcs_lport_get_attr(fcs_port, &iocmd->port_attr); | |
462 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
463 | iocmd->status = BFA_STATUS_OK; | |
464 | out: | |
465 | return 0; | |
466 | } | |
467 | ||
3bbd8ef9 | 468 | static int |
60138066 KG |
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(&bfad->bfa_fcs, | |
478 | iocmd->vf_id, iocmd->pwwn); | |
479 | if (fcs_port == NULL) { | |
480 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
481 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; | |
482 | goto out; | |
483 | } | |
484 | ||
485 | bfa_fcs_lport_get_stats(fcs_port, &iocmd->port_stats); | |
486 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
487 | iocmd->status = BFA_STATUS_OK; | |
488 | out: | |
489 | return 0; | |
490 | } | |
491 | ||
3bbd8ef9 | 492 | static int |
f2ee7601 KG |
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(&bfad->bfa_fcs, | |
505 | iocmd->vf_id, iocmd->vpwwn); | |
506 | if (fcs_port == NULL) { | |
507 | spin_unlock_irqrestore(&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(&bfad->bfad_lock, flags); | |
521 | iocmd->status = BFA_STATUS_OK; | |
522 | out: | |
523 | return 0; | |
524 | } | |
525 | ||
3bbd8ef9 | 526 | static int |
60138066 KG |
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(&bfad->bfa_fcs, | |
536 | iocmd->vf_id, iocmd->pwwn); | |
537 | if (fcs_port == NULL) { | |
538 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
539 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; | |
540 | goto out; | |
541 | } | |
542 | ||
543 | bfa_fcpim_port_iostats(&bfad->bfa, &iocmd->iostats, | |
544 | fcs_port->lp_tag); | |
545 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
546 | iocmd->status = BFA_STATUS_OK; | |
547 | out: | |
548 | return 0; | |
549 | } | |
550 | ||
3bbd8ef9 | 551 | static int |
60138066 KG |
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) | |
9afbcfab | 562 | return -EINVAL; |
60138066 KG |
563 | |
564 | if (bfad_chk_iocmd_sz(payload_len, | |
565 | sizeof(struct bfa_bsg_lport_get_rports_s), | |
ee1a4a42 KG |
566 | sizeof(struct bfa_rport_qualifier_s) * iocmd->nrports) |
567 | != BFA_STATUS_OK) { | |
60138066 KG |
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(&bfad->bfa_fcs, | |
576 | iocmd->vf_id, iocmd->pwwn); | |
577 | if (fcs_port == NULL) { | |
578 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
579 | bfa_trc(bfad, 0); | |
580 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; | |
581 | goto out; | |
582 | } | |
583 | ||
ee1a4a42 KG |
584 | bfa_fcs_lport_get_rport_quals(fcs_port, |
585 | (struct bfa_rport_qualifier_s *)iocmd_bufptr, | |
586 | &iocmd->nrports); | |
60138066 KG |
587 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
588 | iocmd->status = BFA_STATUS_OK; | |
589 | out: | |
590 | return 0; | |
591 | } | |
592 | ||
3bbd8ef9 | 593 | static int |
60138066 KG |
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(&bfad->bfa_fcs, | |
603 | iocmd->vf_id, iocmd->pwwn); | |
604 | if (fcs_port == NULL) { | |
605 | bfa_trc(bfad, 0); | |
606 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
607 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; | |
608 | goto out; | |
609 | } | |
610 | ||
ee1a4a42 KG |
611 | if (iocmd->pid) |
612 | fcs_rport = bfa_fcs_lport_get_rport_by_qualifier(fcs_port, | |
613 | iocmd->rpwwn, iocmd->pid); | |
614 | else | |
615 | fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn); | |
60138066 KG |
616 | if (fcs_rport == NULL) { |
617 | bfa_trc(bfad, 0); | |
618 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
619 | iocmd->status = BFA_STATUS_UNKNOWN_RWWN; | |
620 | goto out; | |
621 | } | |
622 | ||
623 | bfa_fcs_rport_get_attr(fcs_rport, &iocmd->attr); | |
624 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
625 | iocmd->status = BFA_STATUS_OK; | |
626 | out: | |
627 | return 0; | |
628 | } | |
629 | ||
b85daafe KG |
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(&bfad->bfa_fcs, | |
642 | iocmd->vf_id, iocmd->pwwn); | |
643 | if (fcs_port == NULL) { | |
644 | bfa_trc(bfad, 0); | |
645 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
646 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; | |
647 | goto out; | |
648 | } | |
649 | ||
650 | fcs_itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn); | |
651 | if (fcs_itnim == NULL) { | |
652 | bfa_trc(bfad, 0); | |
653 | spin_unlock_irqrestore(&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(&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(&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 | ||
3bbd8ef9 | 679 | static int |
60138066 KG |
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(&bfad->bfa_fcs, | |
690 | iocmd->vf_id, iocmd->pwwn); | |
691 | if (fcs_port == NULL) { | |
692 | bfa_trc(bfad, 0); | |
693 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
694 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; | |
695 | goto out; | |
696 | } | |
697 | ||
698 | fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn); | |
699 | if (fcs_rport == NULL) { | |
700 | bfa_trc(bfad, 0); | |
701 | spin_unlock_irqrestore(&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)); | |
61ba4394 KG |
708 | if (bfa_fcs_rport_get_halrport(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 | } | |
60138066 KG |
713 | |
714 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
715 | iocmd->status = BFA_STATUS_OK; | |
716 | out: | |
717 | return 0; | |
718 | } | |
719 | ||
3bbd8ef9 | 720 | static int |
f2ee7601 KG |
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(&bfad->bfa_fcs, | |
732 | iocmd->vf_id, iocmd->pwwn); | |
733 | if (fcs_port == NULL) { | |
734 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
735 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; | |
736 | goto out; | |
737 | } | |
738 | ||
739 | fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn); | |
740 | if (fcs_rport == NULL) { | |
741 | spin_unlock_irqrestore(&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(fcs_rport); | |
61ba4394 KG |
748 | if (rport) |
749 | memset(&rport->stats, 0, sizeof(rport->stats)); | |
f2ee7601 KG |
750 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
751 | iocmd->status = BFA_STATUS_OK; | |
752 | out: | |
753 | return 0; | |
754 | } | |
755 | ||
3bbd8ef9 | 756 | static int |
f2ee7601 KG |
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(&bfad->bfa_fcs, | |
767 | iocmd->vf_id, iocmd->pwwn); | |
768 | if (fcs_port == NULL) { | |
769 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
770 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; | |
771 | goto out; | |
772 | } | |
773 | ||
774 | fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn); | |
775 | if (fcs_rport == NULL) { | |
776 | spin_unlock_irqrestore(&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) | |
61ba4394 KG |
784 | if (fcs_rport->bfa_rport) |
785 | bfa_rport_speed(fcs_rport->bfa_rport, iocmd->speed); | |
f2ee7601 KG |
786 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
787 | iocmd->status = BFA_STATUS_OK; | |
788 | out: | |
789 | return 0; | |
790 | } | |
791 | ||
3bbd8ef9 | 792 | static int |
f2ee7601 KG |
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(&bfad->bfa_fcs, | |
801 | iocmd->vf_id, iocmd->vpwwn); | |
802 | if (fcs_vport == NULL) { | |
803 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
804 | iocmd->status = BFA_STATUS_UNKNOWN_VWWN; | |
805 | goto out; | |
806 | } | |
807 | ||
808 | bfa_fcs_vport_get_attr(fcs_vport, &iocmd->vport_attr); | |
809 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
810 | iocmd->status = BFA_STATUS_OK; | |
811 | out: | |
812 | return 0; | |
813 | } | |
814 | ||
3bbd8ef9 | 815 | static int |
f2ee7601 KG |
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(&bfad->bfa_fcs, | |
825 | iocmd->vf_id, iocmd->vpwwn); | |
826 | if (fcs_vport == NULL) { | |
827 | spin_unlock_irqrestore(&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(&bfad->bfad_lock, flags); | |
838 | iocmd->status = BFA_STATUS_OK; | |
839 | out: | |
840 | return 0; | |
841 | } | |
842 | ||
3bbd8ef9 | 843 | static int |
f2ee7601 KG |
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(&bfad->bfa_fcs, | |
853 | iocmd->vf_id, iocmd->vpwwn); | |
854 | if (fcs_vport == NULL) { | |
855 | spin_unlock_irqrestore(&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(&bfad->bfad_lock, flags); | |
863 | iocmd->status = BFA_STATUS_OK; | |
864 | out: | |
865 | return 0; | |
866 | } | |
867 | ||
b85daafe KG |
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), | |
1929e82e | 886 | sizeof(wwn_t) * iocmd->nports) != BFA_STATUS_OK) { |
b85daafe KG |
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(&bfad->bfa_fcs, iocmd->vf_id); | |
896 | if (fcs_vf == NULL) { | |
897 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
898 | iocmd->status = BFA_STATUS_UNKNOWN_VFID; | |
899 | goto out; | |
900 | } | |
901 | bfa_fcs_vf_get_ports(fcs_vf, (wwn_t *)iocmd_bufptr, &nports); | |
902 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
903 | ||
904 | iocmd->nports = nports; | |
905 | iocmd->status = BFA_STATUS_OK; | |
906 | out: | |
907 | return 0; | |
908 | } | |
909 | ||
3bbd8ef9 | 910 | static int |
6894f013 KG |
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(&bfad->bfa, &iocmd->qos_bw); | |
918 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
919 | ||
920 | return 0; | |
921 | } | |
922 | ||
3bbd8ef9 | 923 | static int |
f2ee7601 KG |
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 | ||
bc0e2c2a KG |
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; | |
f2ee7601 | 940 | |
bc0e2c2a KG |
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 | } | |
f2ee7601 KG |
946 | |
947 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
f2ee7601 KG |
948 | |
949 | return 0; | |
950 | } | |
951 | ||
3bbd8ef9 | 952 | static int |
f2ee7601 KG |
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(&bfad->bfad_lock, flags); | |
966 | return 0; | |
967 | } | |
968 | ||
bc0e2c2a KG |
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 | } | |
f2ee7601 KG |
976 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
977 | ||
978 | return 0; | |
979 | } | |
980 | ||
3bbd8ef9 | 981 | static int |
f2ee7601 KG |
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(&bfad->bfa, iocmd->param); | |
989 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
990 | iocmd->status = BFA_STATUS_OK; | |
991 | return 0; | |
992 | } | |
993 | ||
3bbd8ef9 | 994 | static int |
60138066 KG |
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(&iocmd->modstats, &(itnim->stats)); | |
1010 | } | |
1011 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1012 | iocmd->status = BFA_STATUS_OK; | |
1013 | return 0; | |
1014 | } | |
1015 | ||
3bbd8ef9 | 1016 | static int |
f2ee7601 KG |
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(&bfad->bfad_lock, flags); | |
1034 | iocmd->status = BFA_STATUS_OK; | |
1035 | return 0; | |
1036 | } | |
1037 | ||
3bbd8ef9 | 1038 | static int |
60138066 KG |
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(&bfad->bfad_lock, flags); | |
1050 | ||
1051 | iocmd->status = BFA_STATUS_OK; | |
1052 | return 0; | |
1053 | } | |
1054 | ||
b85daafe KG |
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(&bfad->bfa_fcs, | |
1064 | iocmd->vf_id, iocmd->lpwwn); | |
1065 | if (!fcs_port) | |
1066 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; | |
1067 | else | |
1068 | iocmd->status = bfa_fcs_itnim_attr_get(fcs_port, | |
1069 | iocmd->rpwwn, &iocmd->attr); | |
1070 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1071 | return 0; | |
1072 | } | |
1073 | ||
60138066 KG |
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(&bfad->bfa_fcs, | |
1085 | iocmd->vf_id, 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(fcs_port, iocmd->rpwwn); | |
1091 | if (itnim == NULL) | |
1092 | iocmd->status = BFA_STATUS_UNKNOWN_RWWN; | |
1093 | else { | |
1094 | iocmd->status = BFA_STATUS_OK; | |
61ba4394 KG |
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)); | |
60138066 KG |
1099 | } |
1100 | } | |
1101 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1102 | return 0; | |
1103 | } | |
1104 | ||
f2ee7601 KG |
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(&bfad->bfa_fcs, | |
1116 | iocmd->vf_id, iocmd->pwwn); | |
1117 | if (!fcs_port) | |
1118 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; | |
1119 | else { | |
1120 | itnim = bfa_fcs_itnim_lookup(fcs_port, 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(fcs_port, iocmd->rpwwn); | |
1126 | bfa_itnim_clear_stats(bfa_fcs_itnim_get_halitn(itnim)); | |
1127 | } | |
1128 | } | |
1129 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1130 | ||
1131 | return 0; | |
1132 | } | |
1133 | ||
60138066 KG |
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(&bfad->bfa_fcs, | |
1145 | iocmd->vf_id, 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(fcs_port, 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(fcs_port, iocmd->rpwwn, | |
1156 | &iocmd->itnstats); | |
1157 | } | |
1158 | } | |
1159 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1160 | return 0; | |
1161 | } | |
1162 | ||
3bbd8ef9 | 1163 | static int |
60138066 KG |
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(&bfad->bfa); | |
1171 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1172 | ||
1173 | return 0; | |
1174 | } | |
1175 | ||
3bbd8ef9 | 1176 | static int |
60138066 KG |
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(&bfad->bfa); | |
1184 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1185 | ||
1186 | return 0; | |
1187 | } | |
1188 | ||
3bbd8ef9 | 1189 | static int |
1a4d8e1b KG |
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(&fcomp.comp); | |
1197 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1198 | iocmd->status = bfa_ablk_query(&bfad->bfa.modules.ablk, | |
1199 | &iocmd->pcifn_cfg, | |
1200 | bfad_hcb_comp, &fcomp); | |
1201 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1211 | static int |
1a4d8e1b KG |
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(&fcomp.comp); | |
1219 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1220 | iocmd->status = bfa_ablk_pf_create(&bfad->bfa.modules.ablk, | |
1221 | &iocmd->pcifn_id, iocmd->port, | |
1a1297c6 KG |
1222 | iocmd->pcifn_class, iocmd->bw_min, |
1223 | iocmd->bw_max, bfad_hcb_comp, &fcomp); | |
1a4d8e1b KG |
1224 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1234 | static int |
1a4d8e1b KG |
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(&fcomp.comp); | |
1242 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1243 | iocmd->status = bfa_ablk_pf_delete(&bfad->bfa.modules.ablk, | |
1244 | iocmd->pcifn_id, | |
1245 | bfad_hcb_comp, &fcomp); | |
1246 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1256 | static int |
1a4d8e1b KG |
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(&fcomp.comp); | |
1264 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1265 | iocmd->status = bfa_ablk_pf_update(&bfad->bfa.modules.ablk, | |
1a1297c6 KG |
1266 | iocmd->pcifn_id, iocmd->bw_min, |
1267 | iocmd->bw_max, bfad_hcb_comp, &fcomp); | |
1a4d8e1b KG |
1268 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1280 | static int |
1a4d8e1b KG |
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(&fcomp.comp); | |
1289 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1290 | iocmd->status = bfa_ablk_adapter_config(&bfad->bfa.modules.ablk, | |
1291 | iocmd->cfg.mode, iocmd->cfg.max_pf, | |
1292 | iocmd->cfg.max_vf, bfad_hcb_comp, &fcomp); | |
1293 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1303 | static int |
1a4d8e1b KG |
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(&fcomp.comp); | |
1312 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1313 | iocmd->status = bfa_ablk_port_config(&bfad->bfa.modules.ablk, | |
1314 | iocmd->instance, iocmd->cfg.mode, | |
1315 | iocmd->cfg.max_pf, iocmd->cfg.max_vf, | |
1316 | bfad_hcb_comp, &fcomp); | |
1317 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1327 | static int |
1a4d8e1b KG |
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(&fcomp.comp); | |
1335 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1336 | if (cmd == IOCMD_FLASH_ENABLE_OPTROM) | |
1337 | iocmd->status = bfa_ablk_optrom_en(&bfad->bfa.modules.ablk, | |
1338 | bfad_hcb_comp, &fcomp); | |
1339 | else | |
1340 | iocmd->status = bfa_ablk_optrom_dis(&bfad->bfa.modules.ablk, | |
1341 | bfad_hcb_comp, &fcomp); | |
1342 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1353 | static int |
a714134a KG |
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(&fcomp.comp); | |
1361 | iocmd->status = BFA_STATUS_OK; | |
1362 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1363 | iocmd->status = bfa_faa_query(&bfad->bfa, &iocmd->faa_attr, | |
1364 | bfad_hcb_comp, &fcomp); | |
1365 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1376 | static int |
148d6103 KG |
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(&cee_comp.comp); | |
1396 | mutex_lock(&bfad_mutex); | |
1397 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1398 | iocmd->status = bfa_cee_get_attr(&bfad->bfa.modules.cee, iocmd_bufptr, | |
1399 | bfad_hcb_comp, &cee_comp); | |
1400 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1401 | if (iocmd->status != BFA_STATUS_OK) { | |
1402 | mutex_unlock(&bfad_mutex); | |
1403 | bfa_trc(bfad, 0x5555); | |
1404 | goto out; | |
1405 | } | |
1406 | wait_for_completion(&cee_comp.comp); | |
1407 | mutex_unlock(&bfad_mutex); | |
1408 | out: | |
1409 | return 0; | |
1410 | } | |
1411 | ||
3bbd8ef9 | 1412 | static int |
148d6103 KG |
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(&cee_comp.comp); | |
1433 | mutex_lock(&bfad_mutex); | |
1434 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1435 | iocmd->status = bfa_cee_get_stats(&bfad->bfa.modules.cee, iocmd_bufptr, | |
1436 | bfad_hcb_comp, &cee_comp); | |
1437 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1438 | if (iocmd->status != BFA_STATUS_OK) { | |
1439 | mutex_unlock(&bfad_mutex); | |
1440 | bfa_trc(bfad, 0x5555); | |
1441 | goto out; | |
1442 | } | |
1443 | wait_for_completion(&cee_comp.comp); | |
1444 | mutex_unlock(&bfad_mutex); | |
1445 | out: | |
1446 | return 0; | |
1447 | } | |
1448 | ||
3bbd8ef9 | 1449 | static int |
148d6103 KG |
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(&bfad->bfa.modules.cee, NULL, NULL); | |
1457 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1458 | if (iocmd->status != BFA_STATUS_OK) | |
1459 | bfa_trc(bfad, 0x5555); | |
1460 | return 0; | |
1461 | } | |
1462 | ||
3bbd8ef9 | 1463 | static int |
51e569aa KG |
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(&fcomp.comp); | |
1471 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1472 | iocmd->status = bfa_sfp_media(BFA_SFP_MOD(&bfad->bfa), &iocmd->media, | |
1473 | bfad_hcb_comp, &fcomp); | |
1474 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1485 | static int |
51e569aa KG |
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(&fcomp.comp); | |
1493 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1494 | iocmd->status = bfa_sfp_speed(BFA_SFP_MOD(&bfad->bfa), iocmd->speed, | |
1495 | bfad_hcb_comp, &fcomp); | |
1496 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1506 | static int |
5a54b1d5 KG |
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(&fcomp.comp); | |
1515 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1516 | iocmd->status = bfa_flash_get_attr(BFA_FLASH(&bfad->bfa), &iocmd->attr, | |
1517 | bfad_hcb_comp, &fcomp); | |
1518 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1527 | static int |
5a54b1d5 KG |
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(&fcomp.comp); | |
1535 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1536 | iocmd->status = bfa_flash_erase_part(BFA_FLASH(&bfad->bfa), iocmd->type, | |
1537 | iocmd->instance, bfad_hcb_comp, &fcomp); | |
1538 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1547 | static int |
5a54b1d5 KG |
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(&fcomp.comp); | |
1566 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1567 | iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), | |
1568 | iocmd->type, iocmd->instance, iocmd_bufptr, | |
1569 | iocmd->bufsz, 0, bfad_hcb_comp, &fcomp); | |
1570 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1579 | static int |
5a54b1d5 KG |
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(&fcomp.comp); | |
1598 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1599 | iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), iocmd->type, | |
1600 | iocmd->instance, iocmd_bufptr, iocmd->bufsz, 0, | |
1601 | bfad_hcb_comp, &fcomp); | |
1602 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1611 | static int |
3d7fc66d KG |
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(&fcomp.comp); | |
1620 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1621 | iocmd->status = bfa_diag_tsensor_query(BFA_DIAG_MOD(&bfad->bfa), | |
1622 | &iocmd->result, bfad_hcb_comp, &fcomp); | |
1623 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1633 | static int |
3d7fc66d KG |
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(&fcomp.comp); | |
1642 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1643 | iocmd->status = bfa_diag_memtest(BFA_DIAG_MOD(&bfad->bfa), | |
1644 | &iocmd->memtest, iocmd->pat, | |
1645 | &iocmd->result, bfad_hcb_comp, &fcomp); | |
1646 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1656 | static int |
3d7fc66d KG |
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(&fcomp.comp); | |
1665 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1666 | iocmd->status = bfa_fcdiag_loopback(&bfad->bfa, iocmd->opmode, | |
1667 | iocmd->speed, iocmd->lpcnt, iocmd->pat, | |
1668 | &iocmd->result, bfad_hcb_comp, &fcomp); | |
1669 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1679 | static int |
3d7fc66d KG |
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(&fcomp.comp); | |
1688 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1689 | iocmd->status = bfa_diag_fwping(BFA_DIAG_MOD(&bfad->bfa), iocmd->cnt, | |
1690 | iocmd->pattern, &iocmd->result, | |
1691 | bfad_hcb_comp, &fcomp); | |
1692 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1703 | static int |
3d7fc66d KG |
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(&fcomp.comp); | |
1711 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1712 | iocmd->status = bfa_fcdiag_queuetest(&bfad->bfa, iocmd->force, | |
1713 | iocmd->queue, &iocmd->result, | |
1714 | bfad_hcb_comp, &fcomp); | |
1715 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1724 | static int |
3d7fc66d KG |
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(&fcomp.comp); | |
1733 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1734 | iocmd->status = bfa_sfp_show(BFA_SFP_MOD(&bfad->bfa), &iocmd->sfp, | |
1735 | bfad_hcb_comp, &fcomp); | |
1736 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1747 | static int |
3d7fc66d KG |
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 | &iocmd->ledtest); | |
1756 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1757 | return 0; | |
1758 | } | |
1759 | ||
3bbd8ef9 | 1760 | static int |
3d7fc66d KG |
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 | iocmd->beacon, iocmd->link_e2e_beacon, | |
1770 | iocmd->second); | |
1771 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1772 | return 0; | |
1773 | } | |
1774 | ||
3bbd8ef9 | 1775 | static int |
3d7fc66d KG |
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(&bfad->bfa); | |
1784 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1785 | bfa_trc(bfad, iocmd->status); | |
1786 | ||
1787 | return 0; | |
1788 | } | |
1789 | ||
3bbd8ef9 | 1790 | static int |
1a898a79 | 1791 | bfad_iocmd_diag_dport_enable(struct bfad_s *bfad, void *pcmd) |
e353546e | 1792 | { |
1a898a79 VMG |
1793 | struct bfa_bsg_dport_enable_s *iocmd = |
1794 | (struct bfa_bsg_dport_enable_s *)pcmd; | |
e353546e KG |
1795 | unsigned long flags; |
1796 | struct bfad_hal_comp fcomp; | |
1797 | ||
1798 | init_completion(&fcomp.comp); | |
1799 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1a898a79 VMG |
1800 | iocmd->status = bfa_dport_enable(&bfad->bfa, iocmd->lpcnt, |
1801 | iocmd->pat, bfad_hcb_comp, &fcomp); | |
1802 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1803 | if (iocmd->status != BFA_STATUS_OK) | |
1804 | bfa_trc(bfad, iocmd->status); | |
e353546e | 1805 | else { |
1a898a79 VMG |
1806 | wait_for_completion(&fcomp.comp); |
1807 | iocmd->status = fcomp.status; | |
e353546e | 1808 | } |
1a898a79 VMG |
1809 | return 0; |
1810 | } | |
e353546e | 1811 | |
3bbd8ef9 | 1812 | static int |
1a898a79 VMG |
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(&fcomp.comp); | |
1820 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1821 | iocmd->status = bfa_dport_disable(&bfad->bfa, bfad_hcb_comp, &fcomp); | |
1822 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
e353546e KG |
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 | } | |
1a898a79 VMG |
1829 | return 0; |
1830 | } | |
1831 | ||
3bbd8ef9 | 1832 | static int |
1a898a79 VMG |
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(&fcomp.comp); | |
1841 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1842 | iocmd->status = bfa_dport_start(&bfad->bfa, iocmd->lpcnt, | |
1843 | iocmd->pat, bfad_hcb_comp, | |
1844 | &fcomp); | |
1845 | spin_unlock_irqrestore(&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 | } | |
e353546e KG |
1853 | |
1854 | return 0; | |
1855 | } | |
1856 | ||
3bbd8ef9 | 1857 | static int |
1a898a79 | 1858 | bfad_iocmd_diag_dport_show(struct bfad_s *bfad, void *pcmd) |
e353546e | 1859 | { |
1a898a79 VMG |
1860 | struct bfa_bsg_diag_dport_show_s *iocmd = |
1861 | (struct bfa_bsg_diag_dport_show_s *)pcmd; | |
1862 | unsigned long flags; | |
e353546e KG |
1863 | |
1864 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1a898a79 | 1865 | iocmd->status = bfa_dport_show(&bfad->bfa, &iocmd->result); |
e353546e KG |
1866 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
1867 | ||
1868 | return 0; | |
1869 | } | |
1870 | ||
1a898a79 | 1871 | |
3bbd8ef9 | 1872 | static int |
3350d98d KG |
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(&fcomp.comp); | |
1881 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1882 | iocmd->status = bfa_phy_get_attr(BFA_PHY(&bfad->bfa), iocmd->instance, | |
1883 | &iocmd->attr, bfad_hcb_comp, &fcomp); | |
1884 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1893 | static int |
3350d98d KG |
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(&fcomp.comp); | |
1902 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1903 | iocmd->status = bfa_phy_get_stats(BFA_PHY(&bfad->bfa), iocmd->instance, | |
1904 | &iocmd->stats, bfad_hcb_comp, &fcomp); | |
1905 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1914 | static int |
3350d98d KG |
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(&fcomp.comp); | |
1931 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1932 | iocmd->status = bfa_phy_read(BFA_PHY(&bfad->bfa), | |
1933 | iocmd->instance, iocmd_bufptr, iocmd->bufsz, | |
1934 | 0, bfad_hcb_comp, &fcomp); | |
1935 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1946 | static int |
61e62e21 KG |
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(&bfad->bfa); | |
1960 | iocmd->status = BFA_STATUS_OK; | |
1961 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
1962 | return 0; | |
1963 | } | |
1964 | ||
3bbd8ef9 | 1965 | static int |
3350d98d KG |
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(&fcomp.comp); | |
1982 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
1983 | iocmd->status = bfa_phy_update(BFA_PHY(&bfad->bfa), | |
1984 | iocmd->instance, iocmd_bufptr, iocmd->bufsz, | |
1985 | 0, bfad_hcb_comp, &fcomp); | |
1986 | spin_unlock_irqrestore(&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 | ||
3bbd8ef9 | 1995 | static int |
61e62e21 KG |
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 | ||
f2ee7601 | 2014 | #define BFA_DEBUG_FW_CORE_CHUNK_SZ 0x4000U /* 16K chunks for FW dump */ |
3bbd8ef9 | 2015 | static int |
f2ee7601 KG |
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; | |
76c8ae4b | 2022 | u32 offset; |
f2ee7601 KG |
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); | |
76c8ae4b | 2040 | offset = iocmd->offset; |
f2ee7601 | 2041 | iocmd->status = bfa_ioc_debug_fwcore(&bfad->bfa.ioc, iocmd_bufptr, |
76c8ae4b SN |
2042 | &offset, &iocmd->bufsz); |
2043 | iocmd->offset = offset; | |
f2ee7601 KG |
2044 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
2045 | out: | |
2046 | return 0; | |
2047 | } | |
2048 | ||
3bbd8ef9 | 2049 | static int |
f2ee7601 KG |
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(&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(bfad->trcmod); | |
2063 | else if (v_cmd == IOCMD_DEBUG_STOP_DTRC) | |
2064 | bfa_trc_stop(bfad->trcmod); | |
2065 | ||
2066 | iocmd->status = BFA_STATUS_OK; | |
2067 | return 0; | |
2068 | } | |
2069 | ||
3bbd8ef9 | 2070 | static int |
f2ee7601 KG |
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 | ||
3bbd8ef9 | 2084 | static int |
42a8e6e2 KG |
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; | |
42a8e6e2 KG |
2089 | unsigned long flags; |
2090 | ||
42a8e6e2 KG |
2091 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2092 | if (v_cmd == IOCMD_FCPIM_PROFILE_ON) | |
aa22a52e | 2093 | iocmd->status = bfa_fcpim_profile_on(&bfad->bfa, ktime_get_real_seconds()); |
42a8e6e2 KG |
2094 | else if (v_cmd == IOCMD_FCPIM_PROFILE_OFF) |
2095 | iocmd->status = bfa_fcpim_profile_off(&bfad->bfa); | |
2096 | spin_unlock_irqrestore(&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(&bfad->bfa_fcs, | |
2112 | iocmd->vf_id, iocmd->lpwwn); | |
2113 | if (!fcs_port) | |
2114 | iocmd->status = BFA_STATUS_UNKNOWN_LWWN; | |
2115 | else { | |
2116 | itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn); | |
2117 | if (itnim == NULL) | |
2118 | iocmd->status = BFA_STATUS_UNKNOWN_RWWN; | |
2119 | else | |
2120 | iocmd->status = bfa_itnim_get_ioprofile( | |
2121 | bfa_fcs_itnim_get_halitn(itnim), | |
2122 | &iocmd->ioprofile); | |
2123 | } | |
2124 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2125 | return 0; | |
2126 | } | |
2127 | ||
3bbd8ef9 | 2128 | static int |
37ea0558 KG |
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(&fcomp.comp); | |
b6960023 | 2138 | bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, &iocmd->stats); |
37ea0558 KG |
2139 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
2140 | iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); | |
2141 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2142 | if (iocmd->status != BFA_STATUS_OK) { | |
2143 | bfa_trc(bfad, iocmd->status); | |
2144 | goto out; | |
2145 | } | |
2146 | wait_for_completion(&fcomp.comp); | |
2147 | iocmd->status = fcomp.status; | |
2148 | out: | |
2149 | return 0; | |
2150 | } | |
2151 | ||
3bbd8ef9 | 2152 | static int |
37ea0558 KG |
2153 | bfad_iocmd_fcport_reset_stats(struct bfad_s *bfad, void *cmd) |
2154 | { | |
2155 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; | |
2156 | struct bfad_hal_comp fcomp; | |
2157 | unsigned long flags; | |
2158 | struct bfa_cb_pending_q_s cb_qe; | |
2159 | ||
2160 | init_completion(&fcomp.comp); | |
b6960023 | 2161 | bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, NULL); |
37ea0558 KG |
2162 | |
2163 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2164 | iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); | |
2165 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2166 | if (iocmd->status != BFA_STATUS_OK) { | |
2167 | bfa_trc(bfad, iocmd->status); | |
2168 | goto out; | |
2169 | } | |
2170 | wait_for_completion(&fcomp.comp); | |
2171 | iocmd->status = fcomp.status; | |
2172 | out: | |
2173 | return 0; | |
2174 | } | |
2175 | ||
3bbd8ef9 | 2176 | static int |
a46bd300 KG |
2177 | bfad_iocmd_boot_cfg(struct bfad_s *bfad, void *cmd) |
2178 | { | |
2179 | struct bfa_bsg_boot_s *iocmd = (struct bfa_bsg_boot_s *)cmd; | |
2180 | struct bfad_hal_comp fcomp; | |
2181 | unsigned long flags; | |
2182 | ||
2183 | init_completion(&fcomp.comp); | |
2184 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2185 | iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), | |
1a1297c6 | 2186 | BFA_FLASH_PART_BOOT, bfad->bfa.ioc.port_id, |
a46bd300 KG |
2187 | &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0, |
2188 | bfad_hcb_comp, &fcomp); | |
2189 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2190 | if (iocmd->status != BFA_STATUS_OK) | |
2191 | goto out; | |
2192 | wait_for_completion(&fcomp.comp); | |
2193 | iocmd->status = fcomp.status; | |
2194 | out: | |
2195 | return 0; | |
2196 | } | |
2197 | ||
3bbd8ef9 | 2198 | static int |
a46bd300 KG |
2199 | bfad_iocmd_boot_query(struct bfad_s *bfad, void *cmd) |
2200 | { | |
2201 | struct bfa_bsg_boot_s *iocmd = (struct bfa_bsg_boot_s *)cmd; | |
2202 | struct bfad_hal_comp fcomp; | |
2203 | unsigned long flags; | |
2204 | ||
2205 | init_completion(&fcomp.comp); | |
2206 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2207 | iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), | |
1a1297c6 | 2208 | BFA_FLASH_PART_BOOT, bfad->bfa.ioc.port_id, |
a46bd300 KG |
2209 | &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0, |
2210 | bfad_hcb_comp, &fcomp); | |
2211 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2212 | if (iocmd->status != BFA_STATUS_OK) | |
2213 | goto out; | |
2214 | wait_for_completion(&fcomp.comp); | |
2215 | iocmd->status = fcomp.status; | |
2216 | out: | |
2217 | return 0; | |
2218 | } | |
2219 | ||
3bbd8ef9 | 2220 | static int |
a46bd300 KG |
2221 | bfad_iocmd_preboot_query(struct bfad_s *bfad, void *cmd) |
2222 | { | |
2223 | struct bfa_bsg_preboot_s *iocmd = (struct bfa_bsg_preboot_s *)cmd; | |
2224 | struct bfi_iocfc_cfgrsp_s *cfgrsp = bfad->bfa.iocfc.cfgrsp; | |
2225 | struct bfa_boot_pbc_s *pbcfg = &iocmd->cfg; | |
2226 | unsigned long flags; | |
2227 | ||
2228 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2229 | pbcfg->enable = cfgrsp->pbc_cfg.boot_enabled; | |
2230 | pbcfg->nbluns = cfgrsp->pbc_cfg.nbluns; | |
2231 | pbcfg->speed = cfgrsp->pbc_cfg.port_speed; | |
2232 | memcpy(pbcfg->pblun, cfgrsp->pbc_cfg.blun, sizeof(pbcfg->pblun)); | |
2233 | iocmd->status = BFA_STATUS_OK; | |
2234 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2235 | ||
2236 | return 0; | |
2237 | } | |
2238 | ||
3bbd8ef9 | 2239 | static int |
a46bd300 KG |
2240 | bfad_iocmd_ethboot_cfg(struct bfad_s *bfad, void *cmd) |
2241 | { | |
2242 | struct bfa_bsg_ethboot_s *iocmd = (struct bfa_bsg_ethboot_s *)cmd; | |
2243 | struct bfad_hal_comp fcomp; | |
2244 | unsigned long flags; | |
2245 | ||
2246 | init_completion(&fcomp.comp); | |
2247 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2248 | iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), | |
2249 | BFA_FLASH_PART_PXECFG, | |
2250 | bfad->bfa.ioc.port_id, &iocmd->cfg, | |
2251 | sizeof(struct bfa_ethboot_cfg_s), 0, | |
2252 | bfad_hcb_comp, &fcomp); | |
2253 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2254 | if (iocmd->status != BFA_STATUS_OK) | |
2255 | goto out; | |
2256 | wait_for_completion(&fcomp.comp); | |
2257 | iocmd->status = fcomp.status; | |
2258 | out: | |
2259 | return 0; | |
2260 | } | |
2261 | ||
3bbd8ef9 | 2262 | static int |
a46bd300 KG |
2263 | bfad_iocmd_ethboot_query(struct bfad_s *bfad, void *cmd) |
2264 | { | |
2265 | struct bfa_bsg_ethboot_s *iocmd = (struct bfa_bsg_ethboot_s *)cmd; | |
2266 | struct bfad_hal_comp fcomp; | |
2267 | unsigned long flags; | |
2268 | ||
2269 | init_completion(&fcomp.comp); | |
2270 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2271 | iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), | |
2272 | BFA_FLASH_PART_PXECFG, | |
2273 | bfad->bfa.ioc.port_id, &iocmd->cfg, | |
2274 | sizeof(struct bfa_ethboot_cfg_s), 0, | |
2275 | bfad_hcb_comp, &fcomp); | |
2276 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2277 | if (iocmd->status != BFA_STATUS_OK) | |
2278 | goto out; | |
2279 | wait_for_completion(&fcomp.comp); | |
2280 | iocmd->status = fcomp.status; | |
2281 | out: | |
2282 | return 0; | |
2283 | } | |
2284 | ||
3bbd8ef9 | 2285 | static int |
45191236 KG |
2286 | bfad_iocmd_cfg_trunk(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) |
2287 | { | |
2288 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; | |
2289 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); | |
2290 | struct bfa_fcport_trunk_s *trunk = &fcport->trunk; | |
2291 | unsigned long flags; | |
2292 | ||
2293 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2294 | ||
e39a8b4f WY |
2295 | if (bfa_fcport_is_dport(&bfad->bfa)) { |
2296 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
e353546e | 2297 | return BFA_STATUS_DPORT_ERR; |
e39a8b4f | 2298 | } |
e353546e | 2299 | |
bc0e2c2a KG |
2300 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || |
2301 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) | |
2302 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; | |
2303 | else { | |
2304 | if (v_cmd == IOCMD_TRUNK_ENABLE) { | |
2305 | trunk->attr.state = BFA_TRUNK_OFFLINE; | |
2306 | bfa_fcport_disable(&bfad->bfa); | |
2307 | fcport->cfg.trunked = BFA_TRUE; | |
2308 | } else if (v_cmd == IOCMD_TRUNK_DISABLE) { | |
2309 | trunk->attr.state = BFA_TRUNK_DISABLED; | |
2310 | bfa_fcport_disable(&bfad->bfa); | |
2311 | fcport->cfg.trunked = BFA_FALSE; | |
2312 | } | |
2313 | ||
2314 | if (!bfa_fcport_is_disabled(&bfad->bfa)) | |
2315 | bfa_fcport_enable(&bfad->bfa); | |
45191236 | 2316 | |
bc0e2c2a KG |
2317 | iocmd->status = BFA_STATUS_OK; |
2318 | } | |
45191236 KG |
2319 | |
2320 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2321 | ||
45191236 KG |
2322 | return 0; |
2323 | } | |
2324 | ||
3bbd8ef9 | 2325 | static int |
45191236 KG |
2326 | bfad_iocmd_trunk_get_attr(struct bfad_s *bfad, void *cmd) |
2327 | { | |
2328 | struct bfa_bsg_trunk_attr_s *iocmd = (struct bfa_bsg_trunk_attr_s *)cmd; | |
2329 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); | |
2330 | struct bfa_fcport_trunk_s *trunk = &fcport->trunk; | |
2331 | unsigned long flags; | |
2332 | ||
2333 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
bc0e2c2a KG |
2334 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || |
2335 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) | |
2336 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; | |
2337 | else { | |
2338 | memcpy((void *)&iocmd->attr, (void *)&trunk->attr, | |
2339 | sizeof(struct bfa_trunk_attr_s)); | |
2340 | iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa); | |
2341 | iocmd->status = BFA_STATUS_OK; | |
2342 | } | |
45191236 KG |
2343 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
2344 | ||
45191236 KG |
2345 | return 0; |
2346 | } | |
2347 | ||
3bbd8ef9 | 2348 | static int |
3ec4f2c8 KG |
2349 | bfad_iocmd_qos(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) |
2350 | { | |
2351 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; | |
2352 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); | |
2353 | unsigned long flags; | |
2354 | ||
2355 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2356 | if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) { | |
bc0e2c2a KG |
2357 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
2358 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) | |
2359 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; | |
2360 | else { | |
2361 | if (v_cmd == IOCMD_QOS_ENABLE) | |
2362 | fcport->cfg.qos_enabled = BFA_TRUE; | |
6894f013 | 2363 | else if (v_cmd == IOCMD_QOS_DISABLE) { |
bc0e2c2a | 2364 | fcport->cfg.qos_enabled = BFA_FALSE; |
6894f013 KG |
2365 | fcport->cfg.qos_bw.high = BFA_QOS_BW_HIGH; |
2366 | fcport->cfg.qos_bw.med = BFA_QOS_BW_MED; | |
2367 | fcport->cfg.qos_bw.low = BFA_QOS_BW_LOW; | |
2368 | } | |
bc0e2c2a | 2369 | } |
3ec4f2c8 KG |
2370 | } |
2371 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2372 | ||
3ec4f2c8 KG |
2373 | return 0; |
2374 | } | |
2375 | ||
3bbd8ef9 | 2376 | static int |
3ec4f2c8 KG |
2377 | bfad_iocmd_qos_get_attr(struct bfad_s *bfad, void *cmd) |
2378 | { | |
2379 | struct bfa_bsg_qos_attr_s *iocmd = (struct bfa_bsg_qos_attr_s *)cmd; | |
2380 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); | |
2381 | unsigned long flags; | |
2382 | ||
2383 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
bc0e2c2a KG |
2384 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
2385 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) | |
2386 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; | |
2387 | else { | |
2388 | iocmd->attr.state = fcport->qos_attr.state; | |
2389 | iocmd->attr.total_bb_cr = | |
2390 | be32_to_cpu(fcport->qos_attr.total_bb_cr); | |
6894f013 KG |
2391 | iocmd->attr.qos_bw.high = fcport->cfg.qos_bw.high; |
2392 | iocmd->attr.qos_bw.med = fcport->cfg.qos_bw.med; | |
2393 | iocmd->attr.qos_bw.low = fcport->cfg.qos_bw.low; | |
2394 | iocmd->attr.qos_bw_op = fcport->qos_attr.qos_bw_op; | |
bc0e2c2a KG |
2395 | iocmd->status = BFA_STATUS_OK; |
2396 | } | |
3ec4f2c8 KG |
2397 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
2398 | ||
3ec4f2c8 KG |
2399 | return 0; |
2400 | } | |
2401 | ||
3bbd8ef9 | 2402 | static int |
3ec4f2c8 KG |
2403 | bfad_iocmd_qos_get_vc_attr(struct bfad_s *bfad, void *cmd) |
2404 | { | |
2405 | struct bfa_bsg_qos_vc_attr_s *iocmd = | |
2406 | (struct bfa_bsg_qos_vc_attr_s *)cmd; | |
2407 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); | |
2408 | struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr; | |
2409 | unsigned long flags; | |
2410 | u32 i = 0; | |
2411 | ||
2412 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2413 | iocmd->attr.total_vc_count = be16_to_cpu(bfa_vc_attr->total_vc_count); | |
2414 | iocmd->attr.shared_credit = be16_to_cpu(bfa_vc_attr->shared_credit); | |
2415 | iocmd->attr.elp_opmode_flags = | |
2416 | be32_to_cpu(bfa_vc_attr->elp_opmode_flags); | |
2417 | ||
2418 | /* Individual VC info */ | |
2419 | while (i < iocmd->attr.total_vc_count) { | |
2420 | iocmd->attr.vc_info[i].vc_credit = | |
2421 | bfa_vc_attr->vc_info[i].vc_credit; | |
2422 | iocmd->attr.vc_info[i].borrow_credit = | |
2423 | bfa_vc_attr->vc_info[i].borrow_credit; | |
2424 | iocmd->attr.vc_info[i].priority = | |
2425 | bfa_vc_attr->vc_info[i].priority; | |
2426 | i++; | |
2427 | } | |
2428 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2429 | ||
2430 | iocmd->status = BFA_STATUS_OK; | |
2431 | return 0; | |
2432 | } | |
2433 | ||
3bbd8ef9 | 2434 | static int |
3ec4f2c8 KG |
2435 | bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd) |
2436 | { | |
2437 | struct bfa_bsg_fcport_stats_s *iocmd = | |
2438 | (struct bfa_bsg_fcport_stats_s *)cmd; | |
2439 | struct bfad_hal_comp fcomp; | |
2440 | unsigned long flags; | |
2441 | struct bfa_cb_pending_q_s cb_qe; | |
bc0e2c2a | 2442 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); |
3ec4f2c8 KG |
2443 | |
2444 | init_completion(&fcomp.comp); | |
b6960023 | 2445 | bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, &iocmd->stats); |
3ec4f2c8 KG |
2446 | |
2447 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2448 | WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); | |
bc0e2c2a KG |
2449 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
2450 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) | |
2451 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; | |
2452 | else | |
2453 | iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); | |
3ec4f2c8 KG |
2454 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
2455 | if (iocmd->status != BFA_STATUS_OK) { | |
2456 | bfa_trc(bfad, iocmd->status); | |
2457 | goto out; | |
2458 | } | |
2459 | wait_for_completion(&fcomp.comp); | |
2460 | iocmd->status = fcomp.status; | |
2461 | out: | |
2462 | return 0; | |
2463 | } | |
2464 | ||
3bbd8ef9 | 2465 | static int |
3ec4f2c8 KG |
2466 | bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd) |
2467 | { | |
2468 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; | |
2469 | struct bfad_hal_comp fcomp; | |
2470 | unsigned long flags; | |
2471 | struct bfa_cb_pending_q_s cb_qe; | |
bc0e2c2a | 2472 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); |
3ec4f2c8 KG |
2473 | |
2474 | init_completion(&fcomp.comp); | |
b6960023 | 2475 | bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, NULL); |
3ec4f2c8 KG |
2476 | |
2477 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2478 | WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); | |
bc0e2c2a KG |
2479 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
2480 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) | |
2481 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; | |
2482 | else | |
2483 | iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); | |
3ec4f2c8 KG |
2484 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
2485 | if (iocmd->status != BFA_STATUS_OK) { | |
2486 | bfa_trc(bfad, iocmd->status); | |
2487 | goto out; | |
2488 | } | |
2489 | wait_for_completion(&fcomp.comp); | |
2490 | iocmd->status = fcomp.status; | |
2491 | out: | |
2492 | return 0; | |
2493 | } | |
2494 | ||
3bbd8ef9 | 2495 | static int |
c0350bf5 KG |
2496 | bfad_iocmd_vf_get_stats(struct bfad_s *bfad, void *cmd) |
2497 | { | |
2498 | struct bfa_bsg_vf_stats_s *iocmd = | |
2499 | (struct bfa_bsg_vf_stats_s *)cmd; | |
2500 | struct bfa_fcs_fabric_s *fcs_vf; | |
2501 | unsigned long flags; | |
2502 | ||
2503 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2504 | fcs_vf = bfa_fcs_vf_lookup(&bfad->bfa_fcs, iocmd->vf_id); | |
2505 | if (fcs_vf == NULL) { | |
2506 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2507 | iocmd->status = BFA_STATUS_UNKNOWN_VFID; | |
2508 | goto out; | |
2509 | } | |
2510 | memcpy((void *)&iocmd->stats, (void *)&fcs_vf->stats, | |
2511 | sizeof(struct bfa_vf_stats_s)); | |
2512 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2513 | iocmd->status = BFA_STATUS_OK; | |
2514 | out: | |
2515 | return 0; | |
2516 | } | |
2517 | ||
3bbd8ef9 | 2518 | static int |
c0350bf5 KG |
2519 | bfad_iocmd_vf_clr_stats(struct bfad_s *bfad, void *cmd) |
2520 | { | |
2521 | struct bfa_bsg_vf_reset_stats_s *iocmd = | |
2522 | (struct bfa_bsg_vf_reset_stats_s *)cmd; | |
2523 | struct bfa_fcs_fabric_s *fcs_vf; | |
2524 | unsigned long flags; | |
2525 | ||
2526 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2527 | fcs_vf = bfa_fcs_vf_lookup(&bfad->bfa_fcs, iocmd->vf_id); | |
2528 | if (fcs_vf == NULL) { | |
2529 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2530 | iocmd->status = BFA_STATUS_UNKNOWN_VFID; | |
2531 | goto out; | |
2532 | } | |
2533 | memset((void *)&fcs_vf->stats, 0, sizeof(struct bfa_vf_stats_s)); | |
2534 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2535 | iocmd->status = BFA_STATUS_OK; | |
2536 | out: | |
2537 | return 0; | |
2538 | } | |
2539 | ||
2e5a6c3b BVA |
2540 | /* |
2541 | * Set the SCSI device sdev_bflags - sdev_bflags are used by the | |
2542 | * SCSI mid-layer to choose LUN Scanning mode REPORT_LUNS vs. Sequential Scan | |
2543 | * | |
2544 | * Internally iterates over all the ITNIM's part of the im_port & sets the | |
2545 | * sdev_bflags for the scsi_device associated with LUN #0. | |
2546 | */ | |
2547 | static void bfad_reset_sdev_bflags(struct bfad_im_port_s *im_port, | |
2548 | int lunmask_cfg) | |
2549 | { | |
0349be31 | 2550 | const blist_flags_t scan_flags = BLIST_NOREPORTLUN | BLIST_SPARSELUN; |
2e5a6c3b BVA |
2551 | struct bfad_itnim_s *itnim; |
2552 | struct scsi_device *sdev; | |
2e79cf37 | 2553 | unsigned long flags; |
2e5a6c3b | 2554 | |
2e79cf37 | 2555 | spin_lock_irqsave(im_port->shost->host_lock, flags); |
2e5a6c3b | 2556 | list_for_each_entry(itnim, &im_port->itnim_mapped_list, list_entry) { |
2e79cf37 BVA |
2557 | sdev = __scsi_device_lookup(im_port->shost, itnim->channel, |
2558 | itnim->scsi_tgt_id, 0); | |
2e5a6c3b BVA |
2559 | if (sdev) { |
2560 | if (lunmask_cfg == BFA_TRUE) | |
2561 | sdev->sdev_bflags |= scan_flags; | |
2562 | else | |
2563 | sdev->sdev_bflags &= ~scan_flags; | |
2e5a6c3b BVA |
2564 | } |
2565 | } | |
2e79cf37 | 2566 | spin_unlock_irqrestore(im_port->shost->host_lock, flags); |
2e5a6c3b BVA |
2567 | } |
2568 | ||
5b7db7af KG |
2569 | /* Function to reset the LUN SCAN mode */ |
2570 | static void | |
2571 | bfad_iocmd_lunmask_reset_lunscan_mode(struct bfad_s *bfad, int lunmask_cfg) | |
2572 | { | |
2573 | struct bfad_im_port_s *pport_im = bfad->pport.im_port; | |
2574 | struct bfad_vport_s *vport = NULL; | |
2575 | ||
2576 | /* Set the scsi device LUN SCAN flags for base port */ | |
2577 | bfad_reset_sdev_bflags(pport_im, lunmask_cfg); | |
2578 | ||
2579 | /* Set the scsi device LUN SCAN flags for the vports */ | |
2580 | list_for_each_entry(vport, &bfad->vport_list, list_entry) | |
2581 | bfad_reset_sdev_bflags(vport->drv_port.im_port, lunmask_cfg); | |
2582 | } | |
2583 | ||
3bbd8ef9 | 2584 | static int |
4c5d22bf KG |
2585 | bfad_iocmd_lunmask(struct bfad_s *bfad, void *pcmd, unsigned int v_cmd) |
2586 | { | |
2587 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; | |
2588 | unsigned long flags; | |
2589 | ||
2590 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
5b7db7af | 2591 | if (v_cmd == IOCMD_FCPIM_LUNMASK_ENABLE) { |
4c5d22bf | 2592 | iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_TRUE); |
5b7db7af KG |
2593 | /* Set the LUN Scanning mode to be Sequential scan */ |
2594 | if (iocmd->status == BFA_STATUS_OK) | |
2595 | bfad_iocmd_lunmask_reset_lunscan_mode(bfad, BFA_TRUE); | |
2596 | } else if (v_cmd == IOCMD_FCPIM_LUNMASK_DISABLE) { | |
4c5d22bf | 2597 | iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_FALSE); |
5b7db7af KG |
2598 | /* Set the LUN Scanning mode to default REPORT_LUNS scan */ |
2599 | if (iocmd->status == BFA_STATUS_OK) | |
2600 | bfad_iocmd_lunmask_reset_lunscan_mode(bfad, BFA_FALSE); | |
2601 | } else if (v_cmd == IOCMD_FCPIM_LUNMASK_CLEAR) | |
4c5d22bf KG |
2602 | iocmd->status = bfa_fcpim_lunmask_clear(&bfad->bfa); |
2603 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2604 | return 0; | |
2605 | } | |
2606 | ||
3bbd8ef9 | 2607 | static int |
4c5d22bf KG |
2608 | bfad_iocmd_fcpim_lunmask_query(struct bfad_s *bfad, void *cmd) |
2609 | { | |
2610 | struct bfa_bsg_fcpim_lunmask_query_s *iocmd = | |
2611 | (struct bfa_bsg_fcpim_lunmask_query_s *)cmd; | |
2612 | struct bfa_lunmask_cfg_s *lun_mask = &iocmd->lun_mask; | |
2613 | unsigned long flags; | |
2614 | ||
2615 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2616 | iocmd->status = bfa_fcpim_lunmask_query(&bfad->bfa, lun_mask); | |
2617 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2618 | return 0; | |
2619 | } | |
2620 | ||
3bbd8ef9 | 2621 | static int |
4c5d22bf KG |
2622 | bfad_iocmd_fcpim_cfg_lunmask(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) |
2623 | { | |
2624 | struct bfa_bsg_fcpim_lunmask_s *iocmd = | |
2625 | (struct bfa_bsg_fcpim_lunmask_s *)cmd; | |
2626 | unsigned long flags; | |
2627 | ||
2628 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2629 | if (v_cmd == IOCMD_FCPIM_LUNMASK_ADD) | |
2630 | iocmd->status = bfa_fcpim_lunmask_add(&bfad->bfa, iocmd->vf_id, | |
2631 | &iocmd->pwwn, iocmd->rpwwn, iocmd->lun); | |
2632 | else if (v_cmd == IOCMD_FCPIM_LUNMASK_DELETE) | |
2633 | iocmd->status = bfa_fcpim_lunmask_delete(&bfad->bfa, | |
2634 | iocmd->vf_id, &iocmd->pwwn, | |
2635 | iocmd->rpwwn, iocmd->lun); | |
2636 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2637 | return 0; | |
2638 | } | |
2639 | ||
3bbd8ef9 | 2640 | static int |
7ace27ae KG |
2641 | bfad_iocmd_fcpim_throttle_query(struct bfad_s *bfad, void *cmd) |
2642 | { | |
2643 | struct bfa_bsg_fcpim_throttle_s *iocmd = | |
2644 | (struct bfa_bsg_fcpim_throttle_s *)cmd; | |
2645 | unsigned long flags; | |
2646 | ||
2647 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2648 | iocmd->status = bfa_fcpim_throttle_get(&bfad->bfa, | |
2649 | (void *)&iocmd->throttle); | |
2650 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2651 | ||
2652 | return 0; | |
2653 | } | |
2654 | ||
3bbd8ef9 | 2655 | static int |
7ace27ae KG |
2656 | bfad_iocmd_fcpim_throttle_set(struct bfad_s *bfad, void *cmd) |
2657 | { | |
2658 | struct bfa_bsg_fcpim_throttle_s *iocmd = | |
2659 | (struct bfa_bsg_fcpim_throttle_s *)cmd; | |
2660 | unsigned long flags; | |
2661 | ||
2662 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2663 | iocmd->status = bfa_fcpim_throttle_set(&bfad->bfa, | |
2664 | iocmd->throttle.cfg_value); | |
2665 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2666 | ||
2667 | return 0; | |
2668 | } | |
2669 | ||
3bbd8ef9 | 2670 | static int |
e6826c96 KG |
2671 | bfad_iocmd_tfru_read(struct bfad_s *bfad, void *cmd) |
2672 | { | |
2673 | struct bfa_bsg_tfru_s *iocmd = | |
2674 | (struct bfa_bsg_tfru_s *)cmd; | |
2675 | struct bfad_hal_comp fcomp; | |
2676 | unsigned long flags = 0; | |
2677 | ||
2678 | init_completion(&fcomp.comp); | |
2679 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2680 | iocmd->status = bfa_tfru_read(BFA_FRU(&bfad->bfa), | |
2681 | &iocmd->data, iocmd->len, iocmd->offset, | |
2682 | bfad_hcb_comp, &fcomp); | |
2683 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2684 | if (iocmd->status == BFA_STATUS_OK) { | |
2685 | wait_for_completion(&fcomp.comp); | |
2686 | iocmd->status = fcomp.status; | |
2687 | } | |
2688 | ||
2689 | return 0; | |
2690 | } | |
2691 | ||
3bbd8ef9 | 2692 | static int |
e6826c96 KG |
2693 | bfad_iocmd_tfru_write(struct bfad_s *bfad, void *cmd) |
2694 | { | |
2695 | struct bfa_bsg_tfru_s *iocmd = | |
2696 | (struct bfa_bsg_tfru_s *)cmd; | |
2697 | struct bfad_hal_comp fcomp; | |
2698 | unsigned long flags = 0; | |
2699 | ||
2700 | init_completion(&fcomp.comp); | |
2701 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2702 | iocmd->status = bfa_tfru_write(BFA_FRU(&bfad->bfa), | |
2703 | &iocmd->data, iocmd->len, iocmd->offset, | |
2704 | bfad_hcb_comp, &fcomp); | |
2705 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2706 | if (iocmd->status == BFA_STATUS_OK) { | |
2707 | wait_for_completion(&fcomp.comp); | |
2708 | iocmd->status = fcomp.status; | |
2709 | } | |
2710 | ||
2711 | return 0; | |
2712 | } | |
2713 | ||
3bbd8ef9 | 2714 | static int |
e6826c96 KG |
2715 | bfad_iocmd_fruvpd_read(struct bfad_s *bfad, void *cmd) |
2716 | { | |
2717 | struct bfa_bsg_fruvpd_s *iocmd = | |
2718 | (struct bfa_bsg_fruvpd_s *)cmd; | |
2719 | struct bfad_hal_comp fcomp; | |
2720 | unsigned long flags = 0; | |
2721 | ||
2722 | init_completion(&fcomp.comp); | |
2723 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2724 | iocmd->status = bfa_fruvpd_read(BFA_FRU(&bfad->bfa), | |
2725 | &iocmd->data, iocmd->len, iocmd->offset, | |
2726 | bfad_hcb_comp, &fcomp); | |
2727 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2728 | if (iocmd->status == BFA_STATUS_OK) { | |
2729 | wait_for_completion(&fcomp.comp); | |
2730 | iocmd->status = fcomp.status; | |
2731 | } | |
2732 | ||
2733 | return 0; | |
2734 | } | |
2735 | ||
3bbd8ef9 | 2736 | static int |
e6826c96 KG |
2737 | bfad_iocmd_fruvpd_update(struct bfad_s *bfad, void *cmd) |
2738 | { | |
2739 | struct bfa_bsg_fruvpd_s *iocmd = | |
2740 | (struct bfa_bsg_fruvpd_s *)cmd; | |
2741 | struct bfad_hal_comp fcomp; | |
2742 | unsigned long flags = 0; | |
2743 | ||
2744 | init_completion(&fcomp.comp); | |
2745 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2746 | iocmd->status = bfa_fruvpd_update(BFA_FRU(&bfad->bfa), | |
2747 | &iocmd->data, iocmd->len, iocmd->offset, | |
079bcbc3 | 2748 | bfad_hcb_comp, &fcomp, iocmd->trfr_cmpl); |
e6826c96 KG |
2749 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
2750 | if (iocmd->status == BFA_STATUS_OK) { | |
2751 | wait_for_completion(&fcomp.comp); | |
2752 | iocmd->status = fcomp.status; | |
2753 | } | |
2754 | ||
2755 | return 0; | |
2756 | } | |
2757 | ||
3bbd8ef9 | 2758 | static int |
e6826c96 KG |
2759 | bfad_iocmd_fruvpd_get_max_size(struct bfad_s *bfad, void *cmd) |
2760 | { | |
2761 | struct bfa_bsg_fruvpd_max_size_s *iocmd = | |
2762 | (struct bfa_bsg_fruvpd_max_size_s *)cmd; | |
2763 | unsigned long flags = 0; | |
2764 | ||
2765 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
2766 | iocmd->status = bfa_fruvpd_get_max_size(BFA_FRU(&bfad->bfa), | |
2767 | &iocmd->max_size); | |
2768 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
2769 | ||
2770 | return 0; | |
2771 | } | |
2772 | ||
b85daafe KG |
2773 | static int |
2774 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | |
2775 | unsigned int payload_len) | |
2776 | { | |
9afbcfab | 2777 | int rc = -EINVAL; |
b85daafe KG |
2778 | |
2779 | switch (cmd) { | |
60138066 KG |
2780 | case IOCMD_IOC_ENABLE: |
2781 | rc = bfad_iocmd_ioc_enable(bfad, iocmd); | |
2782 | break; | |
2783 | case IOCMD_IOC_DISABLE: | |
2784 | rc = bfad_iocmd_ioc_disable(bfad, iocmd); | |
2785 | break; | |
b85daafe KG |
2786 | case IOCMD_IOC_GET_INFO: |
2787 | rc = bfad_iocmd_ioc_get_info(bfad, iocmd); | |
2788 | break; | |
2789 | case IOCMD_IOC_GET_ATTR: | |
2790 | rc = bfad_iocmd_ioc_get_attr(bfad, iocmd); | |
2791 | break; | |
60138066 KG |
2792 | case IOCMD_IOC_GET_STATS: |
2793 | rc = bfad_iocmd_ioc_get_stats(bfad, iocmd); | |
2794 | break; | |
2795 | case IOCMD_IOC_GET_FWSTATS: | |
2796 | rc = bfad_iocmd_ioc_get_fwstats(bfad, iocmd, payload_len); | |
2797 | break; | |
f2ee7601 KG |
2798 | case IOCMD_IOC_RESET_STATS: |
2799 | case IOCMD_IOC_RESET_FWSTATS: | |
2800 | rc = bfad_iocmd_ioc_reset_stats(bfad, iocmd, cmd); | |
2801 | break; | |
2802 | case IOCMD_IOC_SET_ADAPTER_NAME: | |
2803 | case IOCMD_IOC_SET_PORT_NAME: | |
2804 | rc = bfad_iocmd_ioc_set_name(bfad, iocmd, cmd); | |
2805 | break; | |
60138066 KG |
2806 | case IOCMD_IOCFC_GET_ATTR: |
2807 | rc = bfad_iocmd_iocfc_get_attr(bfad, iocmd); | |
2808 | break; | |
2809 | case IOCMD_IOCFC_SET_INTR: | |
2810 | rc = bfad_iocmd_iocfc_set_intr(bfad, iocmd); | |
2811 | break; | |
2812 | case IOCMD_PORT_ENABLE: | |
2813 | rc = bfad_iocmd_port_enable(bfad, iocmd); | |
2814 | break; | |
2815 | case IOCMD_PORT_DISABLE: | |
2816 | rc = bfad_iocmd_port_disable(bfad, iocmd); | |
2817 | break; | |
b85daafe KG |
2818 | case IOCMD_PORT_GET_ATTR: |
2819 | rc = bfad_iocmd_port_get_attr(bfad, iocmd); | |
2820 | break; | |
60138066 KG |
2821 | case IOCMD_PORT_GET_STATS: |
2822 | rc = bfad_iocmd_port_get_stats(bfad, iocmd, payload_len); | |
2823 | break; | |
f2ee7601 KG |
2824 | case IOCMD_PORT_RESET_STATS: |
2825 | rc = bfad_iocmd_port_reset_stats(bfad, iocmd); | |
2826 | break; | |
2827 | case IOCMD_PORT_CFG_TOPO: | |
2828 | case IOCMD_PORT_CFG_SPEED: | |
2829 | case IOCMD_PORT_CFG_ALPA: | |
2830 | case IOCMD_PORT_CLR_ALPA: | |
2831 | rc = bfad_iocmd_set_port_cfg(bfad, iocmd, cmd); | |
2832 | break; | |
2833 | case IOCMD_PORT_CFG_MAXFRSZ: | |
2834 | rc = bfad_iocmd_port_cfg_maxfrsize(bfad, iocmd); | |
2835 | break; | |
bbe37a67 VMG |
2836 | case IOCMD_PORT_BBCR_ENABLE: |
2837 | case IOCMD_PORT_BBCR_DISABLE: | |
2838 | rc = bfad_iocmd_port_cfg_bbcr(bfad, cmd, iocmd); | |
2839 | break; | |
2840 | case IOCMD_PORT_BBCR_GET_ATTR: | |
2841 | rc = bfad_iocmd_port_get_bbcr_attr(bfad, iocmd); | |
f2ee7601 | 2842 | break; |
b85daafe KG |
2843 | case IOCMD_LPORT_GET_ATTR: |
2844 | rc = bfad_iocmd_lport_get_attr(bfad, iocmd); | |
2845 | break; | |
60138066 KG |
2846 | case IOCMD_LPORT_GET_STATS: |
2847 | rc = bfad_iocmd_lport_get_stats(bfad, iocmd); | |
2848 | break; | |
f2ee7601 KG |
2849 | case IOCMD_LPORT_RESET_STATS: |
2850 | rc = bfad_iocmd_lport_reset_stats(bfad, iocmd); | |
2851 | break; | |
60138066 KG |
2852 | case IOCMD_LPORT_GET_IOSTATS: |
2853 | rc = bfad_iocmd_lport_get_iostats(bfad, iocmd); | |
2854 | break; | |
2855 | case IOCMD_LPORT_GET_RPORTS: | |
2856 | rc = bfad_iocmd_lport_get_rports(bfad, iocmd, payload_len); | |
2857 | break; | |
2858 | case IOCMD_RPORT_GET_ATTR: | |
2859 | rc = bfad_iocmd_rport_get_attr(bfad, iocmd); | |
2860 | break; | |
b85daafe KG |
2861 | case IOCMD_RPORT_GET_ADDR: |
2862 | rc = bfad_iocmd_rport_get_addr(bfad, iocmd); | |
2863 | break; | |
60138066 KG |
2864 | case IOCMD_RPORT_GET_STATS: |
2865 | rc = bfad_iocmd_rport_get_stats(bfad, iocmd); | |
2866 | break; | |
f2ee7601 KG |
2867 | case IOCMD_RPORT_RESET_STATS: |
2868 | rc = bfad_iocmd_rport_clr_stats(bfad, iocmd); | |
2869 | break; | |
2870 | case IOCMD_RPORT_SET_SPEED: | |
2871 | rc = bfad_iocmd_rport_set_speed(bfad, iocmd); | |
2872 | break; | |
2873 | case IOCMD_VPORT_GET_ATTR: | |
2874 | rc = bfad_iocmd_vport_get_attr(bfad, iocmd); | |
2875 | break; | |
2876 | case IOCMD_VPORT_GET_STATS: | |
2877 | rc = bfad_iocmd_vport_get_stats(bfad, iocmd); | |
2878 | break; | |
2879 | case IOCMD_VPORT_RESET_STATS: | |
2880 | rc = bfad_iocmd_vport_clr_stats(bfad, iocmd); | |
2881 | break; | |
b85daafe KG |
2882 | case IOCMD_FABRIC_GET_LPORTS: |
2883 | rc = bfad_iocmd_fabric_get_lports(bfad, iocmd, payload_len); | |
2884 | break; | |
f2ee7601 KG |
2885 | case IOCMD_RATELIM_ENABLE: |
2886 | case IOCMD_RATELIM_DISABLE: | |
2887 | rc = bfad_iocmd_ratelim(bfad, cmd, iocmd); | |
2888 | break; | |
2889 | case IOCMD_RATELIM_DEF_SPEED: | |
2890 | rc = bfad_iocmd_ratelim_speed(bfad, cmd, iocmd); | |
2891 | break; | |
2892 | case IOCMD_FCPIM_FAILOVER: | |
2893 | rc = bfad_iocmd_cfg_fcpim(bfad, iocmd); | |
2894 | break; | |
60138066 KG |
2895 | case IOCMD_FCPIM_MODSTATS: |
2896 | rc = bfad_iocmd_fcpim_get_modstats(bfad, iocmd); | |
2897 | break; | |
f2ee7601 KG |
2898 | case IOCMD_FCPIM_MODSTATSCLR: |
2899 | rc = bfad_iocmd_fcpim_clr_modstats(bfad, iocmd); | |
2900 | break; | |
60138066 KG |
2901 | case IOCMD_FCPIM_DEL_ITN_STATS: |
2902 | rc = bfad_iocmd_fcpim_get_del_itn_stats(bfad, iocmd); | |
2903 | break; | |
b85daafe KG |
2904 | case IOCMD_ITNIM_GET_ATTR: |
2905 | rc = bfad_iocmd_itnim_get_attr(bfad, iocmd); | |
2906 | break; | |
60138066 KG |
2907 | case IOCMD_ITNIM_GET_IOSTATS: |
2908 | rc = bfad_iocmd_itnim_get_iostats(bfad, iocmd); | |
2909 | break; | |
f2ee7601 KG |
2910 | case IOCMD_ITNIM_RESET_STATS: |
2911 | rc = bfad_iocmd_itnim_reset_stats(bfad, iocmd); | |
2912 | break; | |
60138066 KG |
2913 | case IOCMD_ITNIM_GET_ITNSTATS: |
2914 | rc = bfad_iocmd_itnim_get_itnstats(bfad, iocmd); | |
2915 | break; | |
2916 | case IOCMD_FCPORT_ENABLE: | |
2917 | rc = bfad_iocmd_fcport_enable(bfad, iocmd); | |
2918 | break; | |
2919 | case IOCMD_FCPORT_DISABLE: | |
2920 | rc = bfad_iocmd_fcport_disable(bfad, iocmd); | |
2921 | break; | |
1a4d8e1b KG |
2922 | case IOCMD_IOC_PCIFN_CFG: |
2923 | rc = bfad_iocmd_ioc_get_pcifn_cfg(bfad, iocmd); | |
2924 | break; | |
28d358d0 VMG |
2925 | case IOCMD_IOC_FW_SIG_INV: |
2926 | rc = bfad_iocmd_ioc_fw_sig_inv(bfad, iocmd); | |
2927 | break; | |
1a4d8e1b KG |
2928 | case IOCMD_PCIFN_CREATE: |
2929 | rc = bfad_iocmd_pcifn_create(bfad, iocmd); | |
2930 | break; | |
2931 | case IOCMD_PCIFN_DELETE: | |
2932 | rc = bfad_iocmd_pcifn_delete(bfad, iocmd); | |
2933 | break; | |
2934 | case IOCMD_PCIFN_BW: | |
2935 | rc = bfad_iocmd_pcifn_bw(bfad, iocmd); | |
2936 | break; | |
2937 | case IOCMD_ADAPTER_CFG_MODE: | |
2938 | rc = bfad_iocmd_adapter_cfg_mode(bfad, iocmd); | |
2939 | break; | |
2940 | case IOCMD_PORT_CFG_MODE: | |
2941 | rc = bfad_iocmd_port_cfg_mode(bfad, iocmd); | |
2942 | break; | |
2943 | case IOCMD_FLASH_ENABLE_OPTROM: | |
2944 | case IOCMD_FLASH_DISABLE_OPTROM: | |
2945 | rc = bfad_iocmd_ablk_optrom(bfad, cmd, iocmd); | |
2946 | break; | |
a714134a KG |
2947 | case IOCMD_FAA_QUERY: |
2948 | rc = bfad_iocmd_faa_query(bfad, iocmd); | |
2949 | break; | |
148d6103 KG |
2950 | case IOCMD_CEE_GET_ATTR: |
2951 | rc = bfad_iocmd_cee_attr(bfad, iocmd, payload_len); | |
2952 | break; | |
2953 | case IOCMD_CEE_GET_STATS: | |
2954 | rc = bfad_iocmd_cee_get_stats(bfad, iocmd, payload_len); | |
2955 | break; | |
2956 | case IOCMD_CEE_RESET_STATS: | |
2957 | rc = bfad_iocmd_cee_reset_stats(bfad, iocmd); | |
2958 | break; | |
51e569aa KG |
2959 | case IOCMD_SFP_MEDIA: |
2960 | rc = bfad_iocmd_sfp_media(bfad, iocmd); | |
2961 | break; | |
2962 | case IOCMD_SFP_SPEED: | |
2963 | rc = bfad_iocmd_sfp_speed(bfad, iocmd); | |
2964 | break; | |
5a54b1d5 KG |
2965 | case IOCMD_FLASH_GET_ATTR: |
2966 | rc = bfad_iocmd_flash_get_attr(bfad, iocmd); | |
2967 | break; | |
2968 | case IOCMD_FLASH_ERASE_PART: | |
2969 | rc = bfad_iocmd_flash_erase_part(bfad, iocmd); | |
2970 | break; | |
2971 | case IOCMD_FLASH_UPDATE_PART: | |
2972 | rc = bfad_iocmd_flash_update_part(bfad, iocmd, payload_len); | |
2973 | break; | |
2974 | case IOCMD_FLASH_READ_PART: | |
2975 | rc = bfad_iocmd_flash_read_part(bfad, iocmd, payload_len); | |
2976 | break; | |
3d7fc66d KG |
2977 | case IOCMD_DIAG_TEMP: |
2978 | rc = bfad_iocmd_diag_temp(bfad, iocmd); | |
2979 | break; | |
2980 | case IOCMD_DIAG_MEMTEST: | |
2981 | rc = bfad_iocmd_diag_memtest(bfad, iocmd); | |
2982 | break; | |
2983 | case IOCMD_DIAG_LOOPBACK: | |
2984 | rc = bfad_iocmd_diag_loopback(bfad, iocmd); | |
2985 | break; | |
2986 | case IOCMD_DIAG_FWPING: | |
2987 | rc = bfad_iocmd_diag_fwping(bfad, iocmd); | |
2988 | break; | |
2989 | case IOCMD_DIAG_QUEUETEST: | |
2990 | rc = bfad_iocmd_diag_queuetest(bfad, iocmd); | |
2991 | break; | |
2992 | case IOCMD_DIAG_SFP: | |
2993 | rc = bfad_iocmd_diag_sfp(bfad, iocmd); | |
2994 | break; | |
2995 | case IOCMD_DIAG_LED: | |
2996 | rc = bfad_iocmd_diag_led(bfad, iocmd); | |
2997 | break; | |
2998 | case IOCMD_DIAG_BEACON_LPORT: | |
2999 | rc = bfad_iocmd_diag_beacon_lport(bfad, iocmd); | |
3000 | break; | |
3001 | case IOCMD_DIAG_LB_STAT: | |
3002 | rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); | |
3003 | break; | |
e353546e | 3004 | case IOCMD_DIAG_DPORT_ENABLE: |
1a898a79 VMG |
3005 | rc = bfad_iocmd_diag_dport_enable(bfad, iocmd); |
3006 | break; | |
e353546e | 3007 | case IOCMD_DIAG_DPORT_DISABLE: |
1a898a79 VMG |
3008 | rc = bfad_iocmd_diag_dport_disable(bfad, iocmd); |
3009 | break; | |
3010 | case IOCMD_DIAG_DPORT_SHOW: | |
3011 | rc = bfad_iocmd_diag_dport_show(bfad, iocmd); | |
e353546e | 3012 | break; |
1a898a79 VMG |
3013 | case IOCMD_DIAG_DPORT_START: |
3014 | rc = bfad_iocmd_diag_dport_start(bfad, iocmd); | |
e353546e | 3015 | break; |
3350d98d KG |
3016 | case IOCMD_PHY_GET_ATTR: |
3017 | rc = bfad_iocmd_phy_get_attr(bfad, iocmd); | |
3018 | break; | |
3019 | case IOCMD_PHY_GET_STATS: | |
3020 | rc = bfad_iocmd_phy_get_stats(bfad, iocmd); | |
3021 | break; | |
3022 | case IOCMD_PHY_UPDATE_FW: | |
3023 | rc = bfad_iocmd_phy_update(bfad, iocmd, payload_len); | |
3024 | break; | |
3025 | case IOCMD_PHY_READ_FW: | |
3026 | rc = bfad_iocmd_phy_read(bfad, iocmd, payload_len); | |
3027 | break; | |
61e62e21 KG |
3028 | case IOCMD_VHBA_QUERY: |
3029 | rc = bfad_iocmd_vhba_query(bfad, iocmd); | |
3030 | break; | |
3031 | case IOCMD_DEBUG_PORTLOG: | |
3032 | rc = bfad_iocmd_porglog_get(bfad, iocmd); | |
3033 | break; | |
f2ee7601 KG |
3034 | case IOCMD_DEBUG_FW_CORE: |
3035 | rc = bfad_iocmd_debug_fw_core(bfad, iocmd, payload_len); | |
3036 | break; | |
3037 | case IOCMD_DEBUG_FW_STATE_CLR: | |
3038 | case IOCMD_DEBUG_PORTLOG_CLR: | |
3039 | case IOCMD_DEBUG_START_DTRC: | |
3040 | case IOCMD_DEBUG_STOP_DTRC: | |
3041 | rc = bfad_iocmd_debug_ctl(bfad, iocmd, cmd); | |
3042 | break; | |
3043 | case IOCMD_DEBUG_PORTLOG_CTL: | |
3044 | rc = bfad_iocmd_porglog_ctl(bfad, iocmd); | |
3045 | break; | |
42a8e6e2 KG |
3046 | case IOCMD_FCPIM_PROFILE_ON: |
3047 | case IOCMD_FCPIM_PROFILE_OFF: | |
3048 | rc = bfad_iocmd_fcpim_cfg_profile(bfad, iocmd, cmd); | |
3049 | break; | |
3050 | case IOCMD_ITNIM_GET_IOPROFILE: | |
3051 | rc = bfad_iocmd_itnim_get_ioprofile(bfad, iocmd); | |
3052 | break; | |
37ea0558 KG |
3053 | case IOCMD_FCPORT_GET_STATS: |
3054 | rc = bfad_iocmd_fcport_get_stats(bfad, iocmd); | |
3055 | break; | |
3056 | case IOCMD_FCPORT_RESET_STATS: | |
3057 | rc = bfad_iocmd_fcport_reset_stats(bfad, iocmd); | |
3058 | break; | |
a46bd300 KG |
3059 | case IOCMD_BOOT_CFG: |
3060 | rc = bfad_iocmd_boot_cfg(bfad, iocmd); | |
3061 | break; | |
3062 | case IOCMD_BOOT_QUERY: | |
3063 | rc = bfad_iocmd_boot_query(bfad, iocmd); | |
3064 | break; | |
3065 | case IOCMD_PREBOOT_QUERY: | |
3066 | rc = bfad_iocmd_preboot_query(bfad, iocmd); | |
3067 | break; | |
3068 | case IOCMD_ETHBOOT_CFG: | |
3069 | rc = bfad_iocmd_ethboot_cfg(bfad, iocmd); | |
3070 | break; | |
3071 | case IOCMD_ETHBOOT_QUERY: | |
3072 | rc = bfad_iocmd_ethboot_query(bfad, iocmd); | |
3073 | break; | |
45191236 KG |
3074 | case IOCMD_TRUNK_ENABLE: |
3075 | case IOCMD_TRUNK_DISABLE: | |
3076 | rc = bfad_iocmd_cfg_trunk(bfad, iocmd, cmd); | |
3077 | break; | |
3078 | case IOCMD_TRUNK_GET_ATTR: | |
3079 | rc = bfad_iocmd_trunk_get_attr(bfad, iocmd); | |
3080 | break; | |
3ec4f2c8 KG |
3081 | case IOCMD_QOS_ENABLE: |
3082 | case IOCMD_QOS_DISABLE: | |
3083 | rc = bfad_iocmd_qos(bfad, iocmd, cmd); | |
3084 | break; | |
3085 | case IOCMD_QOS_GET_ATTR: | |
3086 | rc = bfad_iocmd_qos_get_attr(bfad, iocmd); | |
3087 | break; | |
3088 | case IOCMD_QOS_GET_VC_ATTR: | |
3089 | rc = bfad_iocmd_qos_get_vc_attr(bfad, iocmd); | |
3090 | break; | |
3091 | case IOCMD_QOS_GET_STATS: | |
3092 | rc = bfad_iocmd_qos_get_stats(bfad, iocmd); | |
3093 | break; | |
3094 | case IOCMD_QOS_RESET_STATS: | |
3095 | rc = bfad_iocmd_qos_reset_stats(bfad, iocmd); | |
3096 | break; | |
6894f013 KG |
3097 | case IOCMD_QOS_SET_BW: |
3098 | rc = bfad_iocmd_qos_set_bw(bfad, iocmd); | |
3099 | break; | |
c0350bf5 KG |
3100 | case IOCMD_VF_GET_STATS: |
3101 | rc = bfad_iocmd_vf_get_stats(bfad, iocmd); | |
3102 | break; | |
3103 | case IOCMD_VF_RESET_STATS: | |
3104 | rc = bfad_iocmd_vf_clr_stats(bfad, iocmd); | |
3105 | break; | |
4c5d22bf KG |
3106 | case IOCMD_FCPIM_LUNMASK_ENABLE: |
3107 | case IOCMD_FCPIM_LUNMASK_DISABLE: | |
3108 | case IOCMD_FCPIM_LUNMASK_CLEAR: | |
3109 | rc = bfad_iocmd_lunmask(bfad, iocmd, cmd); | |
3110 | break; | |
3111 | case IOCMD_FCPIM_LUNMASK_QUERY: | |
3112 | rc = bfad_iocmd_fcpim_lunmask_query(bfad, iocmd); | |
3113 | break; | |
3114 | case IOCMD_FCPIM_LUNMASK_ADD: | |
3115 | case IOCMD_FCPIM_LUNMASK_DELETE: | |
3116 | rc = bfad_iocmd_fcpim_cfg_lunmask(bfad, iocmd, cmd); | |
3117 | break; | |
7ace27ae KG |
3118 | case IOCMD_FCPIM_THROTTLE_QUERY: |
3119 | rc = bfad_iocmd_fcpim_throttle_query(bfad, iocmd); | |
3120 | break; | |
3121 | case IOCMD_FCPIM_THROTTLE_SET: | |
3122 | rc = bfad_iocmd_fcpim_throttle_set(bfad, iocmd); | |
3123 | break; | |
e6826c96 KG |
3124 | /* TFRU */ |
3125 | case IOCMD_TFRU_READ: | |
3126 | rc = bfad_iocmd_tfru_read(bfad, iocmd); | |
3127 | break; | |
3128 | case IOCMD_TFRU_WRITE: | |
3129 | rc = bfad_iocmd_tfru_write(bfad, iocmd); | |
3130 | break; | |
3131 | /* FRU */ | |
3132 | case IOCMD_FRUVPD_READ: | |
3133 | rc = bfad_iocmd_fruvpd_read(bfad, iocmd); | |
3134 | break; | |
3135 | case IOCMD_FRUVPD_UPDATE: | |
3136 | rc = bfad_iocmd_fruvpd_update(bfad, iocmd); | |
3137 | break; | |
3138 | case IOCMD_FRUVPD_GET_MAX_SIZE: | |
3139 | rc = bfad_iocmd_fruvpd_get_max_size(bfad, iocmd); | |
3140 | break; | |
b85daafe | 3141 | default: |
9afbcfab | 3142 | rc = -EINVAL; |
b85daafe KG |
3143 | break; |
3144 | } | |
9afbcfab | 3145 | return rc; |
b85daafe KG |
3146 | } |
3147 | ||
3148 | static int | |
75cc8cfc | 3149 | bfad_im_bsg_vendor_request(struct bsg_job *job) |
b85daafe | 3150 | { |
01e0e15c JT |
3151 | struct fc_bsg_request *bsg_request = job->request; |
3152 | struct fc_bsg_reply *bsg_reply = job->reply; | |
3153 | uint32_t vendor_cmd = bsg_request->rqst_data.h_vendor.vendor_cmd[0]; | |
45349821 | 3154 | struct Scsi_Host *shost = fc_bsg_to_shost(job); |
48d83282 | 3155 | struct bfad_im_port_s *im_port = bfad_get_im_port(shost); |
b85daafe KG |
3156 | struct bfad_s *bfad = im_port->bfad; |
3157 | void *payload_kbuf; | |
3158 | int rc = -EINVAL; | |
3159 | ||
3160 | /* Allocate a temp buffer to hold the passed in user space command */ | |
3161 | payload_kbuf = kzalloc(job->request_payload.payload_len, GFP_KERNEL); | |
3162 | if (!payload_kbuf) { | |
3163 | rc = -ENOMEM; | |
3164 | goto out; | |
3165 | } | |
3166 | ||
3167 | /* Copy the sg_list passed in to a linear buffer: holds the cmnd data */ | |
3168 | sg_copy_to_buffer(job->request_payload.sg_list, | |
3169 | job->request_payload.sg_cnt, payload_kbuf, | |
3170 | job->request_payload.payload_len); | |
3171 | ||
3172 | /* Invoke IOCMD handler - to handle all the vendor command requests */ | |
3173 | rc = bfad_iocmd_handler(bfad, vendor_cmd, payload_kbuf, | |
3174 | job->request_payload.payload_len); | |
3175 | if (rc != BFA_STATUS_OK) | |
3176 | goto error; | |
3177 | ||
3178 | /* Copy the response data to the job->reply_payload sg_list */ | |
3179 | sg_copy_from_buffer(job->reply_payload.sg_list, | |
3180 | job->reply_payload.sg_cnt, | |
3181 | payload_kbuf, | |
3182 | job->reply_payload.payload_len); | |
3183 | ||
3184 | /* free the command buffer */ | |
3185 | kfree(payload_kbuf); | |
3186 | ||
3187 | /* Fill the BSG job reply data */ | |
3188 | job->reply_len = job->reply_payload.payload_len; | |
01e0e15c JT |
3189 | bsg_reply->reply_payload_rcv_len = job->reply_payload.payload_len; |
3190 | bsg_reply->result = rc; | |
b85daafe | 3191 | |
06548160 | 3192 | bsg_job_done(job, bsg_reply->result, |
1abaede7 | 3193 | bsg_reply->reply_payload_rcv_len); |
b85daafe KG |
3194 | return rc; |
3195 | error: | |
3196 | /* free the command buffer */ | |
3197 | kfree(payload_kbuf); | |
3198 | out: | |
01e0e15c | 3199 | bsg_reply->result = rc; |
b85daafe | 3200 | job->reply_len = sizeof(uint32_t); |
01e0e15c | 3201 | bsg_reply->reply_payload_rcv_len = 0; |
b85daafe KG |
3202 | return rc; |
3203 | } | |
3204 | ||
3205 | /* FC passthru call backs */ | |
3bbd8ef9 | 3206 | static u64 |
b85daafe KG |
3207 | bfad_fcxp_get_req_sgaddr_cb(void *bfad_fcxp, int sgeid) |
3208 | { | |
3209 | struct bfad_fcxp *drv_fcxp = bfad_fcxp; | |
3210 | struct bfa_sge_s *sge; | |
3211 | u64 addr; | |
3212 | ||
3213 | sge = drv_fcxp->req_sge + sgeid; | |
3214 | addr = (u64)(size_t) sge->sg_addr; | |
3215 | return addr; | |
3216 | } | |
3217 | ||
3bbd8ef9 | 3218 | static u32 |
b85daafe KG |
3219 | bfad_fcxp_get_req_sglen_cb(void *bfad_fcxp, int sgeid) |
3220 | { | |
3221 | struct bfad_fcxp *drv_fcxp = bfad_fcxp; | |
3222 | struct bfa_sge_s *sge; | |
3223 | ||
3224 | sge = drv_fcxp->req_sge + sgeid; | |
3225 | return sge->sg_len; | |
3226 | } | |
3227 | ||
3bbd8ef9 | 3228 | static u64 |
b85daafe KG |
3229 | bfad_fcxp_get_rsp_sgaddr_cb(void *bfad_fcxp, int sgeid) |
3230 | { | |
3231 | struct bfad_fcxp *drv_fcxp = bfad_fcxp; | |
3232 | struct bfa_sge_s *sge; | |
3233 | u64 addr; | |
3234 | ||
3235 | sge = drv_fcxp->rsp_sge + sgeid; | |
3236 | addr = (u64)(size_t) sge->sg_addr; | |
3237 | return addr; | |
3238 | } | |
3239 | ||
3bbd8ef9 | 3240 | static u32 |
b85daafe KG |
3241 | bfad_fcxp_get_rsp_sglen_cb(void *bfad_fcxp, int sgeid) |
3242 | { | |
3243 | struct bfad_fcxp *drv_fcxp = bfad_fcxp; | |
3244 | struct bfa_sge_s *sge; | |
3245 | ||
3246 | sge = drv_fcxp->rsp_sge + sgeid; | |
3247 | return sge->sg_len; | |
3248 | } | |
3249 | ||
3bbd8ef9 | 3250 | static void |
b85daafe KG |
3251 | bfad_send_fcpt_cb(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg, |
3252 | bfa_status_t req_status, u32 rsp_len, u32 resid_len, | |
3253 | struct fchs_s *rsp_fchs) | |
3254 | { | |
3255 | struct bfad_fcxp *drv_fcxp = bfad_fcxp; | |
3256 | ||
3257 | drv_fcxp->req_status = req_status; | |
3258 | drv_fcxp->rsp_len = rsp_len; | |
3259 | ||
3260 | /* bfa_fcxp will be automatically freed by BFA */ | |
3261 | drv_fcxp->bfa_fcxp = NULL; | |
3262 | complete(&drv_fcxp->comp); | |
3263 | } | |
3264 | ||
3bbd8ef9 | 3265 | static struct bfad_buf_info * |
b85daafe KG |
3266 | bfad_fcxp_map_sg(struct bfad_s *bfad, void *payload_kbuf, |
3267 | uint32_t payload_len, uint32_t *num_sgles) | |
3268 | { | |
3269 | struct bfad_buf_info *buf_base, *buf_info; | |
3270 | struct bfa_sge_s *sg_table; | |
3271 | int sge_num = 1; | |
3272 | ||
6396bb22 KC |
3273 | buf_base = kcalloc(sizeof(struct bfad_buf_info) + |
3274 | sizeof(struct bfa_sge_s), | |
3275 | sge_num, GFP_KERNEL); | |
b85daafe KG |
3276 | if (!buf_base) |
3277 | return NULL; | |
3278 | ||
3279 | sg_table = (struct bfa_sge_s *) (((uint8_t *)buf_base) + | |
3280 | (sizeof(struct bfad_buf_info) * sge_num)); | |
3281 | ||
3282 | /* Allocate dma coherent memory */ | |
3283 | buf_info = buf_base; | |
3284 | buf_info->size = payload_len; | |
750afb08 LC |
3285 | buf_info->virt = dma_alloc_coherent(&bfad->pcidev->dev, |
3286 | buf_info->size, &buf_info->phys, | |
3287 | GFP_KERNEL); | |
b85daafe KG |
3288 | if (!buf_info->virt) |
3289 | goto out_free_mem; | |
3290 | ||
3291 | /* copy the linear bsg buffer to buf_info */ | |
b85daafe KG |
3292 | memcpy(buf_info->virt, payload_kbuf, buf_info->size); |
3293 | ||
3294 | /* | |
3295 | * Setup SG table | |
3296 | */ | |
3297 | sg_table->sg_len = buf_info->size; | |
3298 | sg_table->sg_addr = (void *)(size_t) buf_info->phys; | |
3299 | ||
3300 | *num_sgles = sge_num; | |
3301 | ||
3302 | return buf_base; | |
3303 | ||
3304 | out_free_mem: | |
3305 | kfree(buf_base); | |
3306 | return NULL; | |
3307 | } | |
3308 | ||
3bbd8ef9 | 3309 | static void |
b85daafe KG |
3310 | bfad_fcxp_free_mem(struct bfad_s *bfad, struct bfad_buf_info *buf_base, |
3311 | uint32_t num_sgles) | |
3312 | { | |
3313 | int i; | |
3314 | struct bfad_buf_info *buf_info = buf_base; | |
3315 | ||
3316 | if (buf_base) { | |
3317 | for (i = 0; i < num_sgles; buf_info++, i++) { | |
3318 | if (buf_info->virt != NULL) | |
3319 | dma_free_coherent(&bfad->pcidev->dev, | |
3320 | buf_info->size, buf_info->virt, | |
3321 | buf_info->phys); | |
3322 | } | |
3323 | kfree(buf_base); | |
3324 | } | |
3325 | } | |
3326 | ||
3bbd8ef9 | 3327 | static int |
75cc8cfc | 3328 | bfad_fcxp_bsg_send(struct bsg_job *job, struct bfad_fcxp *drv_fcxp, |
b85daafe KG |
3329 | bfa_bsg_fcpt_t *bsg_fcpt) |
3330 | { | |
3331 | struct bfa_fcxp_s *hal_fcxp; | |
3332 | struct bfad_s *bfad = drv_fcxp->port->bfad; | |
3333 | unsigned long flags; | |
3334 | uint8_t lp_tag; | |
3335 | ||
3336 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
3337 | ||
3338 | /* Allocate bfa_fcxp structure */ | |
c3f1b123 | 3339 | hal_fcxp = bfa_fcxp_req_rsp_alloc(drv_fcxp, &bfad->bfa, |
b85daafe KG |
3340 | drv_fcxp->num_req_sgles, |
3341 | drv_fcxp->num_rsp_sgles, | |
3342 | bfad_fcxp_get_req_sgaddr_cb, | |
3343 | bfad_fcxp_get_req_sglen_cb, | |
3344 | bfad_fcxp_get_rsp_sgaddr_cb, | |
c3f1b123 | 3345 | bfad_fcxp_get_rsp_sglen_cb, BFA_TRUE); |
b85daafe KG |
3346 | if (!hal_fcxp) { |
3347 | bfa_trc(bfad, 0); | |
3348 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
3349 | return BFA_STATUS_ENOMEM; | |
3350 | } | |
3351 | ||
3352 | drv_fcxp->bfa_fcxp = hal_fcxp; | |
3353 | ||
3354 | lp_tag = bfa_lps_get_tag_from_pid(&bfad->bfa, bsg_fcpt->fchs.s_id); | |
3355 | ||
3356 | bfa_fcxp_send(hal_fcxp, drv_fcxp->bfa_rport, bsg_fcpt->vf_id, lp_tag, | |
3357 | bsg_fcpt->cts, bsg_fcpt->cos, | |
3358 | job->request_payload.payload_len, | |
3359 | &bsg_fcpt->fchs, bfad_send_fcpt_cb, bfad, | |
3360 | job->reply_payload.payload_len, bsg_fcpt->tsecs); | |
3361 | ||
3362 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
3363 | ||
3364 | return BFA_STATUS_OK; | |
3365 | } | |
3366 | ||
3bbd8ef9 | 3367 | static int |
75cc8cfc | 3368 | bfad_im_bsg_els_ct_request(struct bsg_job *job) |
b85daafe KG |
3369 | { |
3370 | struct bfa_bsg_data *bsg_data; | |
45349821 | 3371 | struct Scsi_Host *shost = fc_bsg_to_shost(job); |
48d83282 | 3372 | struct bfad_im_port_s *im_port = bfad_get_im_port(shost); |
b85daafe KG |
3373 | struct bfad_s *bfad = im_port->bfad; |
3374 | bfa_bsg_fcpt_t *bsg_fcpt; | |
3375 | struct bfad_fcxp *drv_fcxp; | |
3376 | struct bfa_fcs_lport_s *fcs_port; | |
3377 | struct bfa_fcs_rport_s *fcs_rport; | |
46337737 | 3378 | struct fc_bsg_request *bsg_request = job->request; |
01e0e15c JT |
3379 | struct fc_bsg_reply *bsg_reply = job->reply; |
3380 | uint32_t command_type = bsg_request->msgcode; | |
b85daafe KG |
3381 | unsigned long flags; |
3382 | struct bfad_buf_info *rsp_buf_info; | |
3383 | void *req_kbuf = NULL, *rsp_kbuf = NULL; | |
3384 | int rc = -EINVAL; | |
3385 | ||
3386 | job->reply_len = sizeof(uint32_t); /* Atleast uint32_t reply_len */ | |
01e0e15c | 3387 | bsg_reply->reply_payload_rcv_len = 0; |
b85daafe KG |
3388 | |
3389 | /* Get the payload passed in from userspace */ | |
01e0e15c JT |
3390 | bsg_data = (struct bfa_bsg_data *) (((char *)bsg_request) + |
3391 | sizeof(struct fc_bsg_request)); | |
b85daafe KG |
3392 | if (bsg_data == NULL) |
3393 | goto out; | |
3394 | ||
3395 | /* | |
3396 | * Allocate buffer for bsg_fcpt and do a copy_from_user op for payload | |
3397 | * buffer of size bsg_data->payload_len | |
3398 | */ | |
64b8aa75 | 3399 | bsg_fcpt = kzalloc(bsg_data->payload_len, GFP_KERNEL); |
529f9a76 KG |
3400 | if (!bsg_fcpt) { |
3401 | rc = -ENOMEM; | |
b85daafe | 3402 | goto out; |
529f9a76 | 3403 | } |
b85daafe | 3404 | |
bccd2683 VMG |
3405 | if (copy_from_user((uint8_t *)bsg_fcpt, |
3406 | (void *)(unsigned long)bsg_data->payload, | |
b85daafe KG |
3407 | bsg_data->payload_len)) { |
3408 | kfree(bsg_fcpt); | |
529f9a76 | 3409 | rc = -EIO; |
b85daafe KG |
3410 | goto out; |
3411 | } | |
3412 | ||
3413 | drv_fcxp = kzalloc(sizeof(struct bfad_fcxp), GFP_KERNEL); | |
3414 | if (drv_fcxp == NULL) { | |
64b8aa75 | 3415 | kfree(bsg_fcpt); |
b85daafe KG |
3416 | rc = -ENOMEM; |
3417 | goto out; | |
3418 | } | |
3419 | ||
3420 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
3421 | fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, bsg_fcpt->vf_id, | |
3422 | bsg_fcpt->lpwwn); | |
3423 | if (fcs_port == NULL) { | |
3424 | bsg_fcpt->status = BFA_STATUS_UNKNOWN_LWWN; | |
3425 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
3426 | goto out_free_mem; | |
3427 | } | |
3428 | ||
3429 | /* Check if the port is online before sending FC Passthru cmd */ | |
3430 | if (!bfa_fcs_lport_is_online(fcs_port)) { | |
3431 | bsg_fcpt->status = BFA_STATUS_PORT_OFFLINE; | |
3432 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
3433 | goto out_free_mem; | |
3434 | } | |
3435 | ||
3436 | drv_fcxp->port = fcs_port->bfad_port; | |
3437 | ||
1630e752 | 3438 | if (!drv_fcxp->port->bfad) |
b85daafe KG |
3439 | drv_fcxp->port->bfad = bfad; |
3440 | ||
3441 | /* Fetch the bfa_rport - if nexus needed */ | |
3442 | if (command_type == FC_BSG_HST_ELS_NOLOGIN || | |
3443 | command_type == FC_BSG_HST_CT) { | |
3444 | /* BSG HST commands: no nexus needed */ | |
3445 | drv_fcxp->bfa_rport = NULL; | |
3446 | ||
3447 | } else if (command_type == FC_BSG_RPT_ELS || | |
3448 | command_type == FC_BSG_RPT_CT) { | |
3449 | /* BSG RPT commands: nexus needed */ | |
3450 | fcs_rport = bfa_fcs_lport_get_rport_by_pwwn(fcs_port, | |
3451 | bsg_fcpt->dpwwn); | |
3452 | if (fcs_rport == NULL) { | |
3453 | bsg_fcpt->status = BFA_STATUS_UNKNOWN_RWWN; | |
3454 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
3455 | goto out_free_mem; | |
3456 | } | |
3457 | ||
3458 | drv_fcxp->bfa_rport = fcs_rport->bfa_rport; | |
3459 | ||
3460 | } else { /* Unknown BSG msgcode; return -EINVAL */ | |
3461 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
3462 | goto out_free_mem; | |
3463 | } | |
3464 | ||
3465 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
3466 | ||
3467 | /* allocate memory for req / rsp buffers */ | |
3468 | req_kbuf = kzalloc(job->request_payload.payload_len, GFP_KERNEL); | |
3469 | if (!req_kbuf) { | |
3470 | printk(KERN_INFO "bfa %s: fcpt request buffer alloc failed\n", | |
3471 | bfad->pci_name); | |
3472 | rc = -ENOMEM; | |
3473 | goto out_free_mem; | |
3474 | } | |
3475 | ||
3476 | rsp_kbuf = kzalloc(job->reply_payload.payload_len, GFP_KERNEL); | |
3477 | if (!rsp_kbuf) { | |
3478 | printk(KERN_INFO "bfa %s: fcpt response buffer alloc failed\n", | |
3479 | bfad->pci_name); | |
3480 | rc = -ENOMEM; | |
3481 | goto out_free_mem; | |
3482 | } | |
3483 | ||
3484 | /* map req sg - copy the sg_list passed in to the linear buffer */ | |
3485 | sg_copy_to_buffer(job->request_payload.sg_list, | |
3486 | job->request_payload.sg_cnt, req_kbuf, | |
3487 | job->request_payload.payload_len); | |
3488 | ||
3489 | drv_fcxp->reqbuf_info = bfad_fcxp_map_sg(bfad, req_kbuf, | |
3490 | job->request_payload.payload_len, | |
3491 | &drv_fcxp->num_req_sgles); | |
3492 | if (!drv_fcxp->reqbuf_info) { | |
3493 | printk(KERN_INFO "bfa %s: fcpt request fcxp_map_sg failed\n", | |
3494 | bfad->pci_name); | |
3495 | rc = -ENOMEM; | |
3496 | goto out_free_mem; | |
3497 | } | |
3498 | ||
3499 | drv_fcxp->req_sge = (struct bfa_sge_s *) | |
3500 | (((uint8_t *)drv_fcxp->reqbuf_info) + | |
3501 | (sizeof(struct bfad_buf_info) * | |
3502 | drv_fcxp->num_req_sgles)); | |
3503 | ||
3504 | /* map rsp sg */ | |
3505 | drv_fcxp->rspbuf_info = bfad_fcxp_map_sg(bfad, rsp_kbuf, | |
3506 | job->reply_payload.payload_len, | |
3507 | &drv_fcxp->num_rsp_sgles); | |
3508 | if (!drv_fcxp->rspbuf_info) { | |
3509 | printk(KERN_INFO "bfa %s: fcpt response fcxp_map_sg failed\n", | |
3510 | bfad->pci_name); | |
3511 | rc = -ENOMEM; | |
3512 | goto out_free_mem; | |
3513 | } | |
3514 | ||
3515 | rsp_buf_info = (struct bfad_buf_info *)drv_fcxp->rspbuf_info; | |
3516 | drv_fcxp->rsp_sge = (struct bfa_sge_s *) | |
3517 | (((uint8_t *)drv_fcxp->rspbuf_info) + | |
3518 | (sizeof(struct bfad_buf_info) * | |
3519 | drv_fcxp->num_rsp_sgles)); | |
3520 | ||
3521 | /* fcxp send */ | |
3522 | init_completion(&drv_fcxp->comp); | |
3523 | rc = bfad_fcxp_bsg_send(job, drv_fcxp, bsg_fcpt); | |
3524 | if (rc == BFA_STATUS_OK) { | |
3525 | wait_for_completion(&drv_fcxp->comp); | |
3526 | bsg_fcpt->status = drv_fcxp->req_status; | |
3527 | } else { | |
3528 | bsg_fcpt->status = rc; | |
3529 | goto out_free_mem; | |
3530 | } | |
3531 | ||
3532 | /* fill the job->reply data */ | |
3533 | if (drv_fcxp->req_status == BFA_STATUS_OK) { | |
3534 | job->reply_len = drv_fcxp->rsp_len; | |
01e0e15c JT |
3535 | bsg_reply->reply_payload_rcv_len = drv_fcxp->rsp_len; |
3536 | bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK; | |
b85daafe | 3537 | } else { |
01e0e15c | 3538 | bsg_reply->reply_payload_rcv_len = |
b85daafe KG |
3539 | sizeof(struct fc_bsg_ctels_reply); |
3540 | job->reply_len = sizeof(uint32_t); | |
01e0e15c | 3541 | bsg_reply->reply_data.ctels_reply.status = |
b85daafe KG |
3542 | FC_CTELS_STATUS_REJECT; |
3543 | } | |
3544 | ||
3545 | /* Copy the response data to the reply_payload sg list */ | |
3546 | sg_copy_from_buffer(job->reply_payload.sg_list, | |
3547 | job->reply_payload.sg_cnt, | |
3548 | (uint8_t *)rsp_buf_info->virt, | |
3549 | job->reply_payload.payload_len); | |
3550 | ||
3551 | out_free_mem: | |
3552 | bfad_fcxp_free_mem(bfad, drv_fcxp->rspbuf_info, | |
3553 | drv_fcxp->num_rsp_sgles); | |
3554 | bfad_fcxp_free_mem(bfad, drv_fcxp->reqbuf_info, | |
3555 | drv_fcxp->num_req_sgles); | |
3556 | kfree(req_kbuf); | |
3557 | kfree(rsp_kbuf); | |
3558 | ||
3559 | /* Need a copy to user op */ | |
bccd2683 VMG |
3560 | if (copy_to_user((void *)(unsigned long)bsg_data->payload, |
3561 | (void *)bsg_fcpt, bsg_data->payload_len)) | |
b85daafe KG |
3562 | rc = -EIO; |
3563 | ||
3564 | kfree(bsg_fcpt); | |
3565 | kfree(drv_fcxp); | |
3566 | out: | |
01e0e15c | 3567 | bsg_reply->result = rc; |
b85daafe KG |
3568 | |
3569 | if (rc == BFA_STATUS_OK) | |
06548160 | 3570 | bsg_job_done(job, bsg_reply->result, |
1abaede7 | 3571 | bsg_reply->reply_payload_rcv_len); |
b85daafe KG |
3572 | |
3573 | return rc; | |
3574 | } | |
3575 | ||
3576 | int | |
75cc8cfc | 3577 | bfad_im_bsg_request(struct bsg_job *job) |
b85daafe | 3578 | { |
01e0e15c JT |
3579 | struct fc_bsg_request *bsg_request = job->request; |
3580 | struct fc_bsg_reply *bsg_reply = job->reply; | |
b85daafe KG |
3581 | uint32_t rc = BFA_STATUS_OK; |
3582 | ||
01e0e15c | 3583 | switch (bsg_request->msgcode) { |
b85daafe KG |
3584 | case FC_BSG_HST_VENDOR: |
3585 | /* Process BSG HST Vendor requests */ | |
3586 | rc = bfad_im_bsg_vendor_request(job); | |
3587 | break; | |
3588 | case FC_BSG_HST_ELS_NOLOGIN: | |
3589 | case FC_BSG_RPT_ELS: | |
3590 | case FC_BSG_HST_CT: | |
3591 | case FC_BSG_RPT_CT: | |
3592 | /* Process BSG ELS/CT commands */ | |
3593 | rc = bfad_im_bsg_els_ct_request(job); | |
3594 | break; | |
3595 | default: | |
01e0e15c JT |
3596 | bsg_reply->result = rc = -EINVAL; |
3597 | bsg_reply->reply_payload_rcv_len = 0; | |
b85daafe KG |
3598 | break; |
3599 | } | |
3600 | ||
b85daafe KG |
3601 | return rc; |
3602 | } | |
3603 | ||
3604 | int | |
75cc8cfc | 3605 | bfad_im_bsg_timeout(struct bsg_job *job) |
b85daafe KG |
3606 | { |
3607 | /* Don't complete the BSG job request - return -EAGAIN | |
3608 | * to reset bsg job timeout : for ELS/CT pass thru we | |
3609 | * already have timer to track the request. | |
3610 | */ | |
3611 | return -EAGAIN; | |
3612 | } |