[SCSI] bfa: Check supported speed based on port mode
[linux-2.6-block.git] / drivers / scsi / bfa / bfad_bsg.c
CommitLineData
b85daafe
KG
1/*
2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <linux/uaccess.h>
19#include "bfad_drv.h"
20#include "bfad_im.h"
21#include "bfad_bsg.h"
22
23BFA_TRC_FILE(LDRV, BSG);
24
60138066
KG
25int
26bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd)
27{
28 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
29 int rc = 0;
30 unsigned long flags;
31
32 spin_lock_irqsave(&bfad->bfad_lock, flags);
33 /* If IOC is not in disabled state - return */
34 if (!bfa_ioc_is_disabled(&bfad->bfa.ioc)) {
35 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
36 iocmd->status = BFA_STATUS_IOC_FAILURE;
37 return rc;
38 }
39
40 init_completion(&bfad->enable_comp);
41 bfa_iocfc_enable(&bfad->bfa);
42 iocmd->status = BFA_STATUS_OK;
43 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
44 wait_for_completion(&bfad->enable_comp);
45
46 return rc;
47}
48
49int
50bfad_iocmd_ioc_disable(struct bfad_s *bfad, void *cmd)
51{
52 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
53 int rc = 0;
54 unsigned long flags;
55
56 spin_lock_irqsave(&bfad->bfad_lock, flags);
57 if (bfad->disable_active) {
58 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
9afbcfab 59 return -EBUSY;
60138066
KG
60 }
61
62 bfad->disable_active = BFA_TRUE;
63 init_completion(&bfad->disable_comp);
64 bfa_iocfc_disable(&bfad->bfa);
65 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
66
67 wait_for_completion(&bfad->disable_comp);
68 bfad->disable_active = BFA_FALSE;
69 iocmd->status = BFA_STATUS_OK;
70
71 return rc;
72}
73
b85daafe
KG
74static int
75bfad_iocmd_ioc_get_info(struct bfad_s *bfad, void *cmd)
76{
77 int i;
78 struct bfa_bsg_ioc_info_s *iocmd = (struct bfa_bsg_ioc_info_s *)cmd;
79 struct bfad_im_port_s *im_port;
80 struct bfa_port_attr_s pattr;
81 unsigned long flags;
82
83 spin_lock_irqsave(&bfad->bfad_lock, flags);
84 bfa_fcport_get_attr(&bfad->bfa, &pattr);
85 iocmd->nwwn = pattr.nwwn;
86 iocmd->pwwn = pattr.pwwn;
87 iocmd->ioc_type = bfa_get_type(&bfad->bfa);
88 iocmd->mac = bfa_get_mac(&bfad->bfa);
89 iocmd->factory_mac = bfa_get_mfg_mac(&bfad->bfa);
90 bfa_get_adapter_serial_num(&bfad->bfa, iocmd->serialnum);
91 iocmd->factorynwwn = pattr.factorynwwn;
92 iocmd->factorypwwn = pattr.factorypwwn;
7826f304 93 iocmd->bfad_num = bfad->inst_no;
b85daafe
KG
94 im_port = bfad->pport.im_port;
95 iocmd->host = im_port->shost->host_no;
96 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
97
98 strcpy(iocmd->name, bfad->adapter_name);
99 strcpy(iocmd->port_name, bfad->port_name);
100 strcpy(iocmd->hwpath, bfad->pci_name);
101
102 /* set adapter hw path */
103 strcpy(iocmd->adapter_hwpath, bfad->pci_name);
104 i = strlen(iocmd->adapter_hwpath) - 1;
105 while (iocmd->adapter_hwpath[i] != '.')
106 i--;
107 iocmd->adapter_hwpath[i] = '\0';
108 iocmd->status = BFA_STATUS_OK;
109 return 0;
110}
111
112static int
113bfad_iocmd_ioc_get_attr(struct bfad_s *bfad, void *cmd)
114{
115 struct bfa_bsg_ioc_attr_s *iocmd = (struct bfa_bsg_ioc_attr_s *)cmd;
116 unsigned long flags;
117
118 spin_lock_irqsave(&bfad->bfad_lock, flags);
119 bfa_ioc_get_attr(&bfad->bfa.ioc, &iocmd->ioc_attr);
120 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
121
122 /* fill in driver attr info */
123 strcpy(iocmd->ioc_attr.driver_attr.driver, BFAD_DRIVER_NAME);
124 strncpy(iocmd->ioc_attr.driver_attr.driver_ver,
125 BFAD_DRIVER_VERSION, BFA_VERSION_LEN);
126 strcpy(iocmd->ioc_attr.driver_attr.fw_ver,
127 iocmd->ioc_attr.adapter_attr.fw_ver);
128 strcpy(iocmd->ioc_attr.driver_attr.bios_ver,
129 iocmd->ioc_attr.adapter_attr.optrom_ver);
130
131 /* copy chip rev info first otherwise it will be overwritten */
132 memcpy(bfad->pci_attr.chip_rev, iocmd->ioc_attr.pci_attr.chip_rev,
133 sizeof(bfad->pci_attr.chip_rev));
134 memcpy(&iocmd->ioc_attr.pci_attr, &bfad->pci_attr,
135 sizeof(struct bfa_ioc_pci_attr_s));
136
137 iocmd->status = BFA_STATUS_OK;
138 return 0;
139}
140
60138066
KG
141int
142bfad_iocmd_ioc_get_stats(struct bfad_s *bfad, void *cmd)
143{
144 struct bfa_bsg_ioc_stats_s *iocmd = (struct bfa_bsg_ioc_stats_s *)cmd;
145
146 bfa_ioc_get_stats(&bfad->bfa, &iocmd->ioc_stats);
147 iocmd->status = BFA_STATUS_OK;
148 return 0;
149}
150
151int
152bfad_iocmd_ioc_get_fwstats(struct bfad_s *bfad, void *cmd,
153 unsigned int payload_len)
154{
155 struct bfa_bsg_ioc_fwstats_s *iocmd =
156 (struct bfa_bsg_ioc_fwstats_s *)cmd;
157 void *iocmd_bufptr;
158 unsigned long flags;
159
160 if (bfad_chk_iocmd_sz(payload_len,
161 sizeof(struct bfa_bsg_ioc_fwstats_s),
162 sizeof(struct bfa_fw_stats_s)) != BFA_STATUS_OK) {
163 iocmd->status = BFA_STATUS_VERSION_FAIL;
164 goto out;
165 }
166
167 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_ioc_fwstats_s);
168 spin_lock_irqsave(&bfad->bfad_lock, flags);
169 iocmd->status = bfa_ioc_fw_stats_get(&bfad->bfa.ioc, iocmd_bufptr);
170 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
171
172 if (iocmd->status != BFA_STATUS_OK) {
173 bfa_trc(bfad, iocmd->status);
174 goto out;
175 }
176out:
177 bfa_trc(bfad, 0x6666);
178 return 0;
179}
180
181int
182bfad_iocmd_iocfc_get_attr(struct bfad_s *bfad, void *cmd)
183{
184 struct bfa_bsg_iocfc_attr_s *iocmd = (struct bfa_bsg_iocfc_attr_s *)cmd;
185
186 iocmd->status = BFA_STATUS_OK;
187 bfa_iocfc_get_attr(&bfad->bfa, &iocmd->iocfc_attr);
188
189 return 0;
190}
191
192int
193bfad_iocmd_iocfc_set_intr(struct bfad_s *bfad, void *cmd)
194{
195 struct bfa_bsg_iocfc_intr_s *iocmd = (struct bfa_bsg_iocfc_intr_s *)cmd;
196 unsigned long flags;
197
198 spin_lock_irqsave(&bfad->bfad_lock, flags);
199 iocmd->status = bfa_iocfc_israttr_set(&bfad->bfa, &iocmd->attr);
200 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
201
202 return 0;
203}
204
205int
206bfad_iocmd_port_enable(struct bfad_s *bfad, void *cmd)
207{
208 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
209 struct bfad_hal_comp fcomp;
210 unsigned long flags;
211
212 init_completion(&fcomp.comp);
213 spin_lock_irqsave(&bfad->bfad_lock, flags);
214 iocmd->status = bfa_port_enable(&bfad->bfa.modules.port,
215 bfad_hcb_comp, &fcomp);
216 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
217 if (iocmd->status != BFA_STATUS_OK) {
218 bfa_trc(bfad, iocmd->status);
219 return 0;
220 }
221 wait_for_completion(&fcomp.comp);
222 iocmd->status = fcomp.status;
223 return 0;
224}
225
226int
227bfad_iocmd_port_disable(struct bfad_s *bfad, void *cmd)
228{
229 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
230 struct bfad_hal_comp fcomp;
231 unsigned long flags;
232
233 init_completion(&fcomp.comp);
234 spin_lock_irqsave(&bfad->bfad_lock, flags);
235 iocmd->status = bfa_port_disable(&bfad->bfa.modules.port,
236 bfad_hcb_comp, &fcomp);
237 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
238
239 if (iocmd->status != BFA_STATUS_OK) {
240 bfa_trc(bfad, iocmd->status);
241 return 0;
242 }
243 wait_for_completion(&fcomp.comp);
244 iocmd->status = fcomp.status;
245 return 0;
246}
247
b85daafe
KG
248static int
249bfad_iocmd_port_get_attr(struct bfad_s *bfad, void *cmd)
250{
251 struct bfa_bsg_port_attr_s *iocmd = (struct bfa_bsg_port_attr_s *)cmd;
252 struct bfa_lport_attr_s port_attr;
253 unsigned long flags;
254
255 spin_lock_irqsave(&bfad->bfad_lock, flags);
256 bfa_fcport_get_attr(&bfad->bfa, &iocmd->attr);
257 bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr);
258 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
259
260 if (iocmd->attr.topology != BFA_PORT_TOPOLOGY_NONE)
261 iocmd->attr.pid = port_attr.pid;
262 else
263 iocmd->attr.pid = 0;
264
265 iocmd->attr.port_type = port_attr.port_type;
266 iocmd->attr.loopback = port_attr.loopback;
267 iocmd->attr.authfail = port_attr.authfail;
268 strncpy(iocmd->attr.port_symname.symname,
269 port_attr.port_cfg.sym_name.symname,
270 sizeof(port_attr.port_cfg.sym_name.symname));
271
272 iocmd->status = BFA_STATUS_OK;
273 return 0;
274}
275
60138066
KG
276int
277bfad_iocmd_port_get_stats(struct bfad_s *bfad, void *cmd,
278 unsigned int payload_len)
279{
280 struct bfa_bsg_port_stats_s *iocmd = (struct bfa_bsg_port_stats_s *)cmd;
281 struct bfad_hal_comp fcomp;
282 void *iocmd_bufptr;
283 unsigned long flags;
284
285 if (bfad_chk_iocmd_sz(payload_len,
286 sizeof(struct bfa_bsg_port_stats_s),
287 sizeof(union bfa_port_stats_u)) != BFA_STATUS_OK) {
288 iocmd->status = BFA_STATUS_VERSION_FAIL;
289 return 0;
290 }
291
292 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_port_stats_s);
293
294 init_completion(&fcomp.comp);
295 spin_lock_irqsave(&bfad->bfad_lock, flags);
296 iocmd->status = bfa_port_get_stats(&bfad->bfa.modules.port,
297 iocmd_bufptr, bfad_hcb_comp, &fcomp);
298 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
299 if (iocmd->status != BFA_STATUS_OK) {
300 bfa_trc(bfad, iocmd->status);
301 goto out;
302 }
303
304 wait_for_completion(&fcomp.comp);
305 iocmd->status = fcomp.status;
306out:
307 return 0;
308}
309
b85daafe
KG
310static int
311bfad_iocmd_lport_get_attr(struct bfad_s *bfad, void *cmd)
312{
313 struct bfa_fcs_lport_s *fcs_port;
314 struct bfa_bsg_lport_attr_s *iocmd = (struct bfa_bsg_lport_attr_s *)cmd;
315 unsigned long flags;
316
317 spin_lock_irqsave(&bfad->bfad_lock, flags);
318 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
319 iocmd->vf_id, iocmd->pwwn);
320 if (fcs_port == NULL) {
321 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
322 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
323 goto out;
324 }
325
326 bfa_fcs_lport_get_attr(fcs_port, &iocmd->port_attr);
327 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
328 iocmd->status = BFA_STATUS_OK;
329out:
330 return 0;
331}
332
60138066
KG
333int
334bfad_iocmd_lport_get_stats(struct bfad_s *bfad, void *cmd)
335{
336 struct bfa_fcs_lport_s *fcs_port;
337 struct bfa_bsg_lport_stats_s *iocmd =
338 (struct bfa_bsg_lport_stats_s *)cmd;
339 unsigned long flags;
340
341 spin_lock_irqsave(&bfad->bfad_lock, flags);
342 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
343 iocmd->vf_id, iocmd->pwwn);
344 if (fcs_port == NULL) {
345 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
346 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
347 goto out;
348 }
349
350 bfa_fcs_lport_get_stats(fcs_port, &iocmd->port_stats);
351 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
352 iocmd->status = BFA_STATUS_OK;
353out:
354 return 0;
355}
356
357int
358bfad_iocmd_lport_get_iostats(struct bfad_s *bfad, void *cmd)
359{
360 struct bfa_fcs_lport_s *fcs_port;
361 struct bfa_bsg_lport_iostats_s *iocmd =
362 (struct bfa_bsg_lport_iostats_s *)cmd;
363 unsigned long flags;
364
365 spin_lock_irqsave(&bfad->bfad_lock, flags);
366 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
367 iocmd->vf_id, iocmd->pwwn);
368 if (fcs_port == NULL) {
369 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
370 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
371 goto out;
372 }
373
374 bfa_fcpim_port_iostats(&bfad->bfa, &iocmd->iostats,
375 fcs_port->lp_tag);
376 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
377 iocmd->status = BFA_STATUS_OK;
378out:
379 return 0;
380}
381
382int
383bfad_iocmd_lport_get_rports(struct bfad_s *bfad, void *cmd,
384 unsigned int payload_len)
385{
386 struct bfa_bsg_lport_get_rports_s *iocmd =
387 (struct bfa_bsg_lport_get_rports_s *)cmd;
388 struct bfa_fcs_lport_s *fcs_port;
389 unsigned long flags;
390 void *iocmd_bufptr;
391
392 if (iocmd->nrports == 0)
9afbcfab 393 return -EINVAL;
60138066
KG
394
395 if (bfad_chk_iocmd_sz(payload_len,
396 sizeof(struct bfa_bsg_lport_get_rports_s),
397 sizeof(wwn_t) * iocmd->nrports) != BFA_STATUS_OK) {
398 iocmd->status = BFA_STATUS_VERSION_FAIL;
399 return 0;
400 }
401
402 iocmd_bufptr = (char *)iocmd +
403 sizeof(struct bfa_bsg_lport_get_rports_s);
404 spin_lock_irqsave(&bfad->bfad_lock, flags);
405 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
406 iocmd->vf_id, iocmd->pwwn);
407 if (fcs_port == NULL) {
408 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
409 bfa_trc(bfad, 0);
410 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
411 goto out;
412 }
413
414 bfa_fcs_lport_get_rports(fcs_port, (wwn_t *)iocmd_bufptr,
415 &iocmd->nrports);
416 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
417 iocmd->status = BFA_STATUS_OK;
418out:
419 return 0;
420}
421
422int
423bfad_iocmd_rport_get_attr(struct bfad_s *bfad, void *cmd)
424{
425 struct bfa_bsg_rport_attr_s *iocmd = (struct bfa_bsg_rport_attr_s *)cmd;
426 struct bfa_fcs_lport_s *fcs_port;
427 struct bfa_fcs_rport_s *fcs_rport;
428 unsigned long flags;
429
430 spin_lock_irqsave(&bfad->bfad_lock, flags);
431 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
432 iocmd->vf_id, iocmd->pwwn);
433 if (fcs_port == NULL) {
434 bfa_trc(bfad, 0);
435 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
436 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
437 goto out;
438 }
439
440 fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn);
441 if (fcs_rport == NULL) {
442 bfa_trc(bfad, 0);
443 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
444 iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
445 goto out;
446 }
447
448 bfa_fcs_rport_get_attr(fcs_rport, &iocmd->attr);
449 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
450 iocmd->status = BFA_STATUS_OK;
451out:
452 return 0;
453}
454
b85daafe
KG
455static int
456bfad_iocmd_rport_get_addr(struct bfad_s *bfad, void *cmd)
457{
458 struct bfa_bsg_rport_scsi_addr_s *iocmd =
459 (struct bfa_bsg_rport_scsi_addr_s *)cmd;
460 struct bfa_fcs_lport_s *fcs_port;
461 struct bfa_fcs_itnim_s *fcs_itnim;
462 struct bfad_itnim_s *drv_itnim;
463 unsigned long flags;
464
465 spin_lock_irqsave(&bfad->bfad_lock, flags);
466 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
467 iocmd->vf_id, iocmd->pwwn);
468 if (fcs_port == NULL) {
469 bfa_trc(bfad, 0);
470 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
471 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
472 goto out;
473 }
474
475 fcs_itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn);
476 if (fcs_itnim == NULL) {
477 bfa_trc(bfad, 0);
478 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
479 iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
480 goto out;
481 }
482
483 drv_itnim = fcs_itnim->itnim_drv;
484
485 if (drv_itnim && drv_itnim->im_port)
486 iocmd->host = drv_itnim->im_port->shost->host_no;
487 else {
488 bfa_trc(bfad, 0);
489 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
490 iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
491 goto out;
492 }
493
494 iocmd->target = drv_itnim->scsi_tgt_id;
495 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
496
497 iocmd->bus = 0;
498 iocmd->lun = 0;
499 iocmd->status = BFA_STATUS_OK;
500out:
501 return 0;
502}
503
60138066
KG
504int
505bfad_iocmd_rport_get_stats(struct bfad_s *bfad, void *cmd)
506{
507 struct bfa_bsg_rport_stats_s *iocmd =
508 (struct bfa_bsg_rport_stats_s *)cmd;
509 struct bfa_fcs_lport_s *fcs_port;
510 struct bfa_fcs_rport_s *fcs_rport;
511 unsigned long flags;
512
513 spin_lock_irqsave(&bfad->bfad_lock, flags);
514 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
515 iocmd->vf_id, iocmd->pwwn);
516 if (fcs_port == NULL) {
517 bfa_trc(bfad, 0);
518 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
519 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
520 goto out;
521 }
522
523 fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn);
524 if (fcs_rport == NULL) {
525 bfa_trc(bfad, 0);
526 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
527 iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
528 goto out;
529 }
530
531 memcpy((void *)&iocmd->stats, (void *)&fcs_rport->stats,
532 sizeof(struct bfa_rport_stats_s));
533 memcpy((void *)&iocmd->stats.hal_stats,
534 (void *)&(bfa_fcs_rport_get_halrport(fcs_rport)->stats),
535 sizeof(struct bfa_rport_hal_stats_s));
536
537 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
538 iocmd->status = BFA_STATUS_OK;
539out:
540 return 0;
541}
542
b85daafe
KG
543static int
544bfad_iocmd_fabric_get_lports(struct bfad_s *bfad, void *cmd,
545 unsigned int payload_len)
546{
547 struct bfa_bsg_fabric_get_lports_s *iocmd =
548 (struct bfa_bsg_fabric_get_lports_s *)cmd;
549 bfa_fcs_vf_t *fcs_vf;
550 uint32_t nports = iocmd->nports;
551 unsigned long flags;
552 void *iocmd_bufptr;
553
554 if (nports == 0) {
555 iocmd->status = BFA_STATUS_EINVAL;
556 goto out;
557 }
558
559 if (bfad_chk_iocmd_sz(payload_len,
560 sizeof(struct bfa_bsg_fabric_get_lports_s),
561 sizeof(wwn_t[iocmd->nports])) != BFA_STATUS_OK) {
562 iocmd->status = BFA_STATUS_VERSION_FAIL;
563 goto out;
564 }
565
566 iocmd_bufptr = (char *)iocmd +
567 sizeof(struct bfa_bsg_fabric_get_lports_s);
568
569 spin_lock_irqsave(&bfad->bfad_lock, flags);
570 fcs_vf = bfa_fcs_vf_lookup(&bfad->bfa_fcs, iocmd->vf_id);
571 if (fcs_vf == NULL) {
572 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
573 iocmd->status = BFA_STATUS_UNKNOWN_VFID;
574 goto out;
575 }
576 bfa_fcs_vf_get_ports(fcs_vf, (wwn_t *)iocmd_bufptr, &nports);
577 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
578
579 iocmd->nports = nports;
580 iocmd->status = BFA_STATUS_OK;
581out:
582 return 0;
583}
584
60138066
KG
585int
586bfad_iocmd_fcpim_get_modstats(struct bfad_s *bfad, void *cmd)
587{
588 struct bfa_bsg_fcpim_modstats_s *iocmd =
589 (struct bfa_bsg_fcpim_modstats_s *)cmd;
590 struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa);
591 struct list_head *qe, *qen;
592 struct bfa_itnim_s *itnim;
593 unsigned long flags;
594
595 spin_lock_irqsave(&bfad->bfad_lock, flags);
596 /* accumulate IO stats from itnim */
597 memset((void *)&iocmd->modstats, 0, sizeof(struct bfa_itnim_iostats_s));
598 list_for_each_safe(qe, qen, &fcpim->itnim_q) {
599 itnim = (struct bfa_itnim_s *) qe;
600 bfa_fcpim_add_stats(&iocmd->modstats, &(itnim->stats));
601 }
602 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
603 iocmd->status = BFA_STATUS_OK;
604 return 0;
605}
606
607int
608bfad_iocmd_fcpim_get_del_itn_stats(struct bfad_s *bfad, void *cmd)
609{
610 struct bfa_bsg_fcpim_del_itn_stats_s *iocmd =
611 (struct bfa_bsg_fcpim_del_itn_stats_s *)cmd;
612 struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa);
613 unsigned long flags;
614
615 spin_lock_irqsave(&bfad->bfad_lock, flags);
616 memcpy((void *)&iocmd->modstats, (void *)&fcpim->del_itn_stats,
617 sizeof(struct bfa_fcpim_del_itn_stats_s));
618 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
619
620 iocmd->status = BFA_STATUS_OK;
621 return 0;
622}
623
b85daafe
KG
624static int
625bfad_iocmd_itnim_get_attr(struct bfad_s *bfad, void *cmd)
626{
627 struct bfa_bsg_itnim_attr_s *iocmd = (struct bfa_bsg_itnim_attr_s *)cmd;
628 struct bfa_fcs_lport_s *fcs_port;
629 unsigned long flags;
630
631 spin_lock_irqsave(&bfad->bfad_lock, flags);
632 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
633 iocmd->vf_id, iocmd->lpwwn);
634 if (!fcs_port)
635 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
636 else
637 iocmd->status = bfa_fcs_itnim_attr_get(fcs_port,
638 iocmd->rpwwn, &iocmd->attr);
639 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
640 return 0;
641}
642
60138066
KG
643static int
644bfad_iocmd_itnim_get_iostats(struct bfad_s *bfad, void *cmd)
645{
646 struct bfa_bsg_itnim_iostats_s *iocmd =
647 (struct bfa_bsg_itnim_iostats_s *)cmd;
648 struct bfa_fcs_lport_s *fcs_port;
649 struct bfa_fcs_itnim_s *itnim;
650 unsigned long flags;
651
652 spin_lock_irqsave(&bfad->bfad_lock, flags);
653 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
654 iocmd->vf_id, iocmd->lpwwn);
655 if (!fcs_port) {
656 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
657 bfa_trc(bfad, 0);
658 } else {
659 itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn);
660 if (itnim == NULL)
661 iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
662 else {
663 iocmd->status = BFA_STATUS_OK;
664 memcpy((void *)&iocmd->iostats, (void *)
665 &(bfa_fcs_itnim_get_halitn(itnim)->stats),
666 sizeof(struct bfa_itnim_iostats_s));
667 }
668 }
669 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
670 return 0;
671}
672
673static int
674bfad_iocmd_itnim_get_itnstats(struct bfad_s *bfad, void *cmd)
675{
676 struct bfa_bsg_itnim_itnstats_s *iocmd =
677 (struct bfa_bsg_itnim_itnstats_s *)cmd;
678 struct bfa_fcs_lport_s *fcs_port;
679 struct bfa_fcs_itnim_s *itnim;
680 unsigned long flags;
681
682 spin_lock_irqsave(&bfad->bfad_lock, flags);
683 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
684 iocmd->vf_id, iocmd->lpwwn);
685 if (!fcs_port) {
686 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
687 bfa_trc(bfad, 0);
688 } else {
689 itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn);
690 if (itnim == NULL)
691 iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
692 else {
693 iocmd->status = BFA_STATUS_OK;
694 bfa_fcs_itnim_stats_get(fcs_port, iocmd->rpwwn,
695 &iocmd->itnstats);
696 }
697 }
698 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
699 return 0;
700}
701
702int
703bfad_iocmd_fcport_enable(struct bfad_s *bfad, void *cmd)
704{
705 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
706 unsigned long flags;
707
708 spin_lock_irqsave(&bfad->bfad_lock, flags);
709 iocmd->status = bfa_fcport_enable(&bfad->bfa);
710 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
711
712 return 0;
713}
714
715int
716bfad_iocmd_fcport_disable(struct bfad_s *bfad, void *cmd)
717{
718 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
719 unsigned long flags;
720
721 spin_lock_irqsave(&bfad->bfad_lock, flags);
722 iocmd->status = bfa_fcport_disable(&bfad->bfa);
723 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
724
725 return 0;
726}
727
1a4d8e1b
KG
728int
729bfad_iocmd_ioc_get_pcifn_cfg(struct bfad_s *bfad, void *cmd)
730{
731 struct bfa_bsg_pcifn_cfg_s *iocmd = (struct bfa_bsg_pcifn_cfg_s *)cmd;
732 struct bfad_hal_comp fcomp;
733 unsigned long flags;
734
735 init_completion(&fcomp.comp);
736 spin_lock_irqsave(&bfad->bfad_lock, flags);
737 iocmd->status = bfa_ablk_query(&bfad->bfa.modules.ablk,
738 &iocmd->pcifn_cfg,
739 bfad_hcb_comp, &fcomp);
740 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
741 if (iocmd->status != BFA_STATUS_OK)
742 goto out;
743
744 wait_for_completion(&fcomp.comp);
745 iocmd->status = fcomp.status;
746out:
747 return 0;
748}
749
750int
751bfad_iocmd_pcifn_create(struct bfad_s *bfad, void *cmd)
752{
753 struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd;
754 struct bfad_hal_comp fcomp;
755 unsigned long flags;
756
757 init_completion(&fcomp.comp);
758 spin_lock_irqsave(&bfad->bfad_lock, flags);
759 iocmd->status = bfa_ablk_pf_create(&bfad->bfa.modules.ablk,
760 &iocmd->pcifn_id, iocmd->port,
761 iocmd->pcifn_class, iocmd->bandwidth,
762 bfad_hcb_comp, &fcomp);
763 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
764 if (iocmd->status != BFA_STATUS_OK)
765 goto out;
766
767 wait_for_completion(&fcomp.comp);
768 iocmd->status = fcomp.status;
769out:
770 return 0;
771}
772
773int
774bfad_iocmd_pcifn_delete(struct bfad_s *bfad, void *cmd)
775{
776 struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd;
777 struct bfad_hal_comp fcomp;
778 unsigned long flags;
779
780 init_completion(&fcomp.comp);
781 spin_lock_irqsave(&bfad->bfad_lock, flags);
782 iocmd->status = bfa_ablk_pf_delete(&bfad->bfa.modules.ablk,
783 iocmd->pcifn_id,
784 bfad_hcb_comp, &fcomp);
785 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
786 if (iocmd->status != BFA_STATUS_OK)
787 goto out;
788
789 wait_for_completion(&fcomp.comp);
790 iocmd->status = fcomp.status;
791out:
792 return 0;
793}
794
795int
796bfad_iocmd_pcifn_bw(struct bfad_s *bfad, void *cmd)
797{
798 struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd;
799 struct bfad_hal_comp fcomp;
800 unsigned long flags;
801
802 init_completion(&fcomp.comp);
803 spin_lock_irqsave(&bfad->bfad_lock, flags);
804 iocmd->status = bfa_ablk_pf_update(&bfad->bfa.modules.ablk,
805 iocmd->pcifn_id, iocmd->bandwidth,
806 bfad_hcb_comp, &fcomp);
807 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
808 bfa_trc(bfad, iocmd->status);
809 if (iocmd->status != BFA_STATUS_OK)
810 goto out;
811
812 wait_for_completion(&fcomp.comp);
813 iocmd->status = fcomp.status;
814 bfa_trc(bfad, iocmd->status);
815out:
816 return 0;
817}
818
819int
820bfad_iocmd_adapter_cfg_mode(struct bfad_s *bfad, void *cmd)
821{
822 struct bfa_bsg_adapter_cfg_mode_s *iocmd =
823 (struct bfa_bsg_adapter_cfg_mode_s *)cmd;
824 struct bfad_hal_comp fcomp;
825 unsigned long flags = 0;
826
827 init_completion(&fcomp.comp);
828 spin_lock_irqsave(&bfad->bfad_lock, flags);
829 iocmd->status = bfa_ablk_adapter_config(&bfad->bfa.modules.ablk,
830 iocmd->cfg.mode, iocmd->cfg.max_pf,
831 iocmd->cfg.max_vf, bfad_hcb_comp, &fcomp);
832 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
833 if (iocmd->status != BFA_STATUS_OK)
834 goto out;
835
836 wait_for_completion(&fcomp.comp);
837 iocmd->status = fcomp.status;
838out:
839 return 0;
840}
841
842int
843bfad_iocmd_port_cfg_mode(struct bfad_s *bfad, void *cmd)
844{
845 struct bfa_bsg_port_cfg_mode_s *iocmd =
846 (struct bfa_bsg_port_cfg_mode_s *)cmd;
847 struct bfad_hal_comp fcomp;
848 unsigned long flags = 0;
849
850 init_completion(&fcomp.comp);
851 spin_lock_irqsave(&bfad->bfad_lock, flags);
852 iocmd->status = bfa_ablk_port_config(&bfad->bfa.modules.ablk,
853 iocmd->instance, iocmd->cfg.mode,
854 iocmd->cfg.max_pf, iocmd->cfg.max_vf,
855 bfad_hcb_comp, &fcomp);
856 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
857 if (iocmd->status != BFA_STATUS_OK)
858 goto out;
859
860 wait_for_completion(&fcomp.comp);
861 iocmd->status = fcomp.status;
862out:
863 return 0;
864}
865
866int
867bfad_iocmd_ablk_optrom(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
868{
869 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd;
870 struct bfad_hal_comp fcomp;
871 unsigned long flags;
872
873 init_completion(&fcomp.comp);
874 spin_lock_irqsave(&bfad->bfad_lock, flags);
875 if (cmd == IOCMD_FLASH_ENABLE_OPTROM)
876 iocmd->status = bfa_ablk_optrom_en(&bfad->bfa.modules.ablk,
877 bfad_hcb_comp, &fcomp);
878 else
879 iocmd->status = bfa_ablk_optrom_dis(&bfad->bfa.modules.ablk,
880 bfad_hcb_comp, &fcomp);
881 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
882
883 if (iocmd->status != BFA_STATUS_OK)
884 goto out;
885
886 wait_for_completion(&fcomp.comp);
887 iocmd->status = fcomp.status;
888out:
889 return 0;
890}
891
a714134a
KG
892int
893bfad_iocmd_faa_enable(struct bfad_s *bfad, void *cmd)
894{
895 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
896 unsigned long flags;
897 struct bfad_hal_comp fcomp;
898
899 init_completion(&fcomp.comp);
900 iocmd->status = BFA_STATUS_OK;
901 spin_lock_irqsave(&bfad->bfad_lock, flags);
902 iocmd->status = bfa_faa_enable(&bfad->bfa, bfad_hcb_comp, &fcomp);
903 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
904
905 if (iocmd->status != BFA_STATUS_OK)
906 goto out;
907
908 wait_for_completion(&fcomp.comp);
909 iocmd->status = fcomp.status;
910out:
911 return 0;
912}
913
914int
915bfad_iocmd_faa_disable(struct bfad_s *bfad, void *cmd)
916{
917 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
918 unsigned long flags;
919 struct bfad_hal_comp fcomp;
920
921 init_completion(&fcomp.comp);
922 iocmd->status = BFA_STATUS_OK;
923 spin_lock_irqsave(&bfad->bfad_lock, flags);
924 iocmd->status = bfa_faa_disable(&bfad->bfa, bfad_hcb_comp, &fcomp);
925 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
926
927 if (iocmd->status != BFA_STATUS_OK)
928 goto out;
929
930 wait_for_completion(&fcomp.comp);
931 iocmd->status = fcomp.status;
932out:
933 return 0;
934}
935
936int
937bfad_iocmd_faa_query(struct bfad_s *bfad, void *cmd)
938{
939 struct bfa_bsg_faa_attr_s *iocmd = (struct bfa_bsg_faa_attr_s *)cmd;
940 struct bfad_hal_comp fcomp;
941 unsigned long flags;
942
943 init_completion(&fcomp.comp);
944 iocmd->status = BFA_STATUS_OK;
945 spin_lock_irqsave(&bfad->bfad_lock, flags);
946 iocmd->status = bfa_faa_query(&bfad->bfa, &iocmd->faa_attr,
947 bfad_hcb_comp, &fcomp);
948 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
949
950 if (iocmd->status != BFA_STATUS_OK)
951 goto out;
952
953 wait_for_completion(&fcomp.comp);
954 iocmd->status = fcomp.status;
955out:
956 return 0;
957}
958
148d6103
KG
959int
960bfad_iocmd_cee_attr(struct bfad_s *bfad, void *cmd, unsigned int payload_len)
961{
962 struct bfa_bsg_cee_attr_s *iocmd =
963 (struct bfa_bsg_cee_attr_s *)cmd;
964 void *iocmd_bufptr;
965 struct bfad_hal_comp cee_comp;
966 unsigned long flags;
967
968 if (bfad_chk_iocmd_sz(payload_len,
969 sizeof(struct bfa_bsg_cee_attr_s),
970 sizeof(struct bfa_cee_attr_s)) != BFA_STATUS_OK) {
971 iocmd->status = BFA_STATUS_VERSION_FAIL;
972 return 0;
973 }
974
975 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_cee_attr_s);
976
977 cee_comp.status = 0;
978 init_completion(&cee_comp.comp);
979 mutex_lock(&bfad_mutex);
980 spin_lock_irqsave(&bfad->bfad_lock, flags);
981 iocmd->status = bfa_cee_get_attr(&bfad->bfa.modules.cee, iocmd_bufptr,
982 bfad_hcb_comp, &cee_comp);
983 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
984 if (iocmd->status != BFA_STATUS_OK) {
985 mutex_unlock(&bfad_mutex);
986 bfa_trc(bfad, 0x5555);
987 goto out;
988 }
989 wait_for_completion(&cee_comp.comp);
990 mutex_unlock(&bfad_mutex);
991out:
992 return 0;
993}
994
995int
996bfad_iocmd_cee_get_stats(struct bfad_s *bfad, void *cmd,
997 unsigned int payload_len)
998{
999 struct bfa_bsg_cee_stats_s *iocmd =
1000 (struct bfa_bsg_cee_stats_s *)cmd;
1001 void *iocmd_bufptr;
1002 struct bfad_hal_comp cee_comp;
1003 unsigned long flags;
1004
1005 if (bfad_chk_iocmd_sz(payload_len,
1006 sizeof(struct bfa_bsg_cee_stats_s),
1007 sizeof(struct bfa_cee_stats_s)) != BFA_STATUS_OK) {
1008 iocmd->status = BFA_STATUS_VERSION_FAIL;
1009 return 0;
1010 }
1011
1012 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_cee_stats_s);
1013
1014 cee_comp.status = 0;
1015 init_completion(&cee_comp.comp);
1016 mutex_lock(&bfad_mutex);
1017 spin_lock_irqsave(&bfad->bfad_lock, flags);
1018 iocmd->status = bfa_cee_get_stats(&bfad->bfa.modules.cee, iocmd_bufptr,
1019 bfad_hcb_comp, &cee_comp);
1020 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1021 if (iocmd->status != BFA_STATUS_OK) {
1022 mutex_unlock(&bfad_mutex);
1023 bfa_trc(bfad, 0x5555);
1024 goto out;
1025 }
1026 wait_for_completion(&cee_comp.comp);
1027 mutex_unlock(&bfad_mutex);
1028out:
1029 return 0;
1030}
1031
1032int
1033bfad_iocmd_cee_reset_stats(struct bfad_s *bfad, void *cmd)
1034{
1035 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
1036 unsigned long flags;
1037
1038 spin_lock_irqsave(&bfad->bfad_lock, flags);
1039 iocmd->status = bfa_cee_reset_stats(&bfad->bfa.modules.cee, NULL, NULL);
1040 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1041 if (iocmd->status != BFA_STATUS_OK)
1042 bfa_trc(bfad, 0x5555);
1043 return 0;
1044}
1045
51e569aa
KG
1046int
1047bfad_iocmd_sfp_media(struct bfad_s *bfad, void *cmd)
1048{
1049 struct bfa_bsg_sfp_media_s *iocmd = (struct bfa_bsg_sfp_media_s *)cmd;
1050 struct bfad_hal_comp fcomp;
1051 unsigned long flags;
1052
1053 init_completion(&fcomp.comp);
1054 spin_lock_irqsave(&bfad->bfad_lock, flags);
1055 iocmd->status = bfa_sfp_media(BFA_SFP_MOD(&bfad->bfa), &iocmd->media,
1056 bfad_hcb_comp, &fcomp);
1057 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1058 bfa_trc(bfad, iocmd->status);
1059 if (iocmd->status != BFA_STATUS_SFP_NOT_READY)
1060 goto out;
1061
1062 wait_for_completion(&fcomp.comp);
1063 iocmd->status = fcomp.status;
1064out:
1065 return 0;
1066}
1067
1068int
1069bfad_iocmd_sfp_speed(struct bfad_s *bfad, void *cmd)
1070{
1071 struct bfa_bsg_sfp_speed_s *iocmd = (struct bfa_bsg_sfp_speed_s *)cmd;
1072 struct bfad_hal_comp fcomp;
1073 unsigned long flags;
1074
1075 init_completion(&fcomp.comp);
1076 spin_lock_irqsave(&bfad->bfad_lock, flags);
1077 iocmd->status = bfa_sfp_speed(BFA_SFP_MOD(&bfad->bfa), iocmd->speed,
1078 bfad_hcb_comp, &fcomp);
1079 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1080 bfa_trc(bfad, iocmd->status);
1081 if (iocmd->status != BFA_STATUS_SFP_NOT_READY)
1082 goto out;
1083 wait_for_completion(&fcomp.comp);
1084 iocmd->status = fcomp.status;
1085out:
1086 return 0;
1087}
1088
5a54b1d5
KG
1089int
1090bfad_iocmd_flash_get_attr(struct bfad_s *bfad, void *cmd)
1091{
1092 struct bfa_bsg_flash_attr_s *iocmd =
1093 (struct bfa_bsg_flash_attr_s *)cmd;
1094 struct bfad_hal_comp fcomp;
1095 unsigned long flags;
1096
1097 init_completion(&fcomp.comp);
1098 spin_lock_irqsave(&bfad->bfad_lock, flags);
1099 iocmd->status = bfa_flash_get_attr(BFA_FLASH(&bfad->bfa), &iocmd->attr,
1100 bfad_hcb_comp, &fcomp);
1101 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1102 if (iocmd->status != BFA_STATUS_OK)
1103 goto out;
1104 wait_for_completion(&fcomp.comp);
1105 iocmd->status = fcomp.status;
1106out:
1107 return 0;
1108}
1109
1110int
1111bfad_iocmd_flash_erase_part(struct bfad_s *bfad, void *cmd)
1112{
1113 struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd;
1114 struct bfad_hal_comp fcomp;
1115 unsigned long flags;
1116
1117 init_completion(&fcomp.comp);
1118 spin_lock_irqsave(&bfad->bfad_lock, flags);
1119 iocmd->status = bfa_flash_erase_part(BFA_FLASH(&bfad->bfa), iocmd->type,
1120 iocmd->instance, bfad_hcb_comp, &fcomp);
1121 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1122 if (iocmd->status != BFA_STATUS_OK)
1123 goto out;
1124 wait_for_completion(&fcomp.comp);
1125 iocmd->status = fcomp.status;
1126out:
1127 return 0;
1128}
1129
1130int
1131bfad_iocmd_flash_update_part(struct bfad_s *bfad, void *cmd,
1132 unsigned int payload_len)
1133{
1134 struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd;
1135 void *iocmd_bufptr;
1136 struct bfad_hal_comp fcomp;
1137 unsigned long flags;
1138
1139 if (bfad_chk_iocmd_sz(payload_len,
1140 sizeof(struct bfa_bsg_flash_s),
1141 iocmd->bufsz) != BFA_STATUS_OK) {
1142 iocmd->status = BFA_STATUS_VERSION_FAIL;
1143 return 0;
1144 }
1145
1146 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_flash_s);
1147
1148 init_completion(&fcomp.comp);
1149 spin_lock_irqsave(&bfad->bfad_lock, flags);
1150 iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa),
1151 iocmd->type, iocmd->instance, iocmd_bufptr,
1152 iocmd->bufsz, 0, bfad_hcb_comp, &fcomp);
1153 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1154 if (iocmd->status != BFA_STATUS_OK)
1155 goto out;
1156 wait_for_completion(&fcomp.comp);
1157 iocmd->status = fcomp.status;
1158out:
1159 return 0;
1160}
1161
1162int
1163bfad_iocmd_flash_read_part(struct bfad_s *bfad, void *cmd,
1164 unsigned int payload_len)
1165{
1166 struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd;
1167 struct bfad_hal_comp fcomp;
1168 void *iocmd_bufptr;
1169 unsigned long flags;
1170
1171 if (bfad_chk_iocmd_sz(payload_len,
1172 sizeof(struct bfa_bsg_flash_s),
1173 iocmd->bufsz) != BFA_STATUS_OK) {
1174 iocmd->status = BFA_STATUS_VERSION_FAIL;
1175 return 0;
1176 }
1177
1178 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_flash_s);
1179
1180 init_completion(&fcomp.comp);
1181 spin_lock_irqsave(&bfad->bfad_lock, flags);
1182 iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), iocmd->type,
1183 iocmd->instance, iocmd_bufptr, iocmd->bufsz, 0,
1184 bfad_hcb_comp, &fcomp);
1185 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1186 if (iocmd->status != BFA_STATUS_OK)
1187 goto out;
1188 wait_for_completion(&fcomp.comp);
1189 iocmd->status = fcomp.status;
1190out:
1191 return 0;
1192}
1193
3d7fc66d
KG
1194int
1195bfad_iocmd_diag_temp(struct bfad_s *bfad, void *cmd)
1196{
1197 struct bfa_bsg_diag_get_temp_s *iocmd =
1198 (struct bfa_bsg_diag_get_temp_s *)cmd;
1199 struct bfad_hal_comp fcomp;
1200 unsigned long flags;
1201
1202 init_completion(&fcomp.comp);
1203 spin_lock_irqsave(&bfad->bfad_lock, flags);
1204 iocmd->status = bfa_diag_tsensor_query(BFA_DIAG_MOD(&bfad->bfa),
1205 &iocmd->result, bfad_hcb_comp, &fcomp);
1206 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1207 bfa_trc(bfad, iocmd->status);
1208 if (iocmd->status != BFA_STATUS_OK)
1209 goto out;
1210 wait_for_completion(&fcomp.comp);
1211 iocmd->status = fcomp.status;
1212out:
1213 return 0;
1214}
1215
1216int
1217bfad_iocmd_diag_memtest(struct bfad_s *bfad, void *cmd)
1218{
1219 struct bfa_bsg_diag_memtest_s *iocmd =
1220 (struct bfa_bsg_diag_memtest_s *)cmd;
1221 struct bfad_hal_comp fcomp;
1222 unsigned long flags;
1223
1224 init_completion(&fcomp.comp);
1225 spin_lock_irqsave(&bfad->bfad_lock, flags);
1226 iocmd->status = bfa_diag_memtest(BFA_DIAG_MOD(&bfad->bfa),
1227 &iocmd->memtest, iocmd->pat,
1228 &iocmd->result, bfad_hcb_comp, &fcomp);
1229 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1230 bfa_trc(bfad, iocmd->status);
1231 if (iocmd->status != BFA_STATUS_OK)
1232 goto out;
1233 wait_for_completion(&fcomp.comp);
1234 iocmd->status = fcomp.status;
1235out:
1236 return 0;
1237}
1238
1239int
1240bfad_iocmd_diag_loopback(struct bfad_s *bfad, void *cmd)
1241{
1242 struct bfa_bsg_diag_loopback_s *iocmd =
1243 (struct bfa_bsg_diag_loopback_s *)cmd;
1244 struct bfad_hal_comp fcomp;
1245 unsigned long flags;
1246
1247 init_completion(&fcomp.comp);
1248 spin_lock_irqsave(&bfad->bfad_lock, flags);
1249 iocmd->status = bfa_fcdiag_loopback(&bfad->bfa, iocmd->opmode,
1250 iocmd->speed, iocmd->lpcnt, iocmd->pat,
1251 &iocmd->result, bfad_hcb_comp, &fcomp);
1252 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1253 bfa_trc(bfad, iocmd->status);
1254 if (iocmd->status != BFA_STATUS_OK)
1255 goto out;
1256 wait_for_completion(&fcomp.comp);
1257 iocmd->status = fcomp.status;
1258out:
1259 return 0;
1260}
1261
1262int
1263bfad_iocmd_diag_fwping(struct bfad_s *bfad, void *cmd)
1264{
1265 struct bfa_bsg_diag_fwping_s *iocmd =
1266 (struct bfa_bsg_diag_fwping_s *)cmd;
1267 struct bfad_hal_comp fcomp;
1268 unsigned long flags;
1269
1270 init_completion(&fcomp.comp);
1271 spin_lock_irqsave(&bfad->bfad_lock, flags);
1272 iocmd->status = bfa_diag_fwping(BFA_DIAG_MOD(&bfad->bfa), iocmd->cnt,
1273 iocmd->pattern, &iocmd->result,
1274 bfad_hcb_comp, &fcomp);
1275 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1276 bfa_trc(bfad, iocmd->status);
1277 if (iocmd->status != BFA_STATUS_OK)
1278 goto out;
1279 bfa_trc(bfad, 0x77771);
1280 wait_for_completion(&fcomp.comp);
1281 iocmd->status = fcomp.status;
1282out:
1283 return 0;
1284}
1285
1286int
1287bfad_iocmd_diag_queuetest(struct bfad_s *bfad, void *cmd)
1288{
1289 struct bfa_bsg_diag_qtest_s *iocmd = (struct bfa_bsg_diag_qtest_s *)cmd;
1290 struct bfad_hal_comp fcomp;
1291 unsigned long flags;
1292
1293 init_completion(&fcomp.comp);
1294 spin_lock_irqsave(&bfad->bfad_lock, flags);
1295 iocmd->status = bfa_fcdiag_queuetest(&bfad->bfa, iocmd->force,
1296 iocmd->queue, &iocmd->result,
1297 bfad_hcb_comp, &fcomp);
1298 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1299 if (iocmd->status != BFA_STATUS_OK)
1300 goto out;
1301 wait_for_completion(&fcomp.comp);
1302 iocmd->status = fcomp.status;
1303out:
1304 return 0;
1305}
1306
1307int
1308bfad_iocmd_diag_sfp(struct bfad_s *bfad, void *cmd)
1309{
1310 struct bfa_bsg_sfp_show_s *iocmd =
1311 (struct bfa_bsg_sfp_show_s *)cmd;
1312 struct bfad_hal_comp fcomp;
1313 unsigned long flags;
1314
1315 init_completion(&fcomp.comp);
1316 spin_lock_irqsave(&bfad->bfad_lock, flags);
1317 iocmd->status = bfa_sfp_show(BFA_SFP_MOD(&bfad->bfa), &iocmd->sfp,
1318 bfad_hcb_comp, &fcomp);
1319 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1320 bfa_trc(bfad, iocmd->status);
1321 if (iocmd->status != BFA_STATUS_OK)
1322 goto out;
1323 wait_for_completion(&fcomp.comp);
1324 iocmd->status = fcomp.status;
1325 bfa_trc(bfad, iocmd->status);
1326out:
1327 return 0;
1328}
1329
1330int
1331bfad_iocmd_diag_led(struct bfad_s *bfad, void *cmd)
1332{
1333 struct bfa_bsg_diag_led_s *iocmd = (struct bfa_bsg_diag_led_s *)cmd;
1334 unsigned long flags;
1335
1336 spin_lock_irqsave(&bfad->bfad_lock, flags);
1337 iocmd->status = bfa_diag_ledtest(BFA_DIAG_MOD(&bfad->bfa),
1338 &iocmd->ledtest);
1339 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1340 return 0;
1341}
1342
1343int
1344bfad_iocmd_diag_beacon_lport(struct bfad_s *bfad, void *cmd)
1345{
1346 struct bfa_bsg_diag_beacon_s *iocmd =
1347 (struct bfa_bsg_diag_beacon_s *)cmd;
1348 unsigned long flags;
1349
1350 spin_lock_irqsave(&bfad->bfad_lock, flags);
1351 iocmd->status = bfa_diag_beacon_port(BFA_DIAG_MOD(&bfad->bfa),
1352 iocmd->beacon, iocmd->link_e2e_beacon,
1353 iocmd->second);
1354 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1355 return 0;
1356}
1357
1358int
1359bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd)
1360{
1361 struct bfa_bsg_diag_lb_stat_s *iocmd =
1362 (struct bfa_bsg_diag_lb_stat_s *)cmd;
1363 unsigned long flags;
1364
1365 spin_lock_irqsave(&bfad->bfad_lock, flags);
1366 iocmd->status = bfa_fcdiag_lb_is_running(&bfad->bfa);
1367 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1368 bfa_trc(bfad, iocmd->status);
1369
1370 return 0;
1371}
1372
3350d98d
KG
1373int
1374bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd)
1375{
1376 struct bfa_bsg_phy_attr_s *iocmd =
1377 (struct bfa_bsg_phy_attr_s *)cmd;
1378 struct bfad_hal_comp fcomp;
1379 unsigned long flags;
1380
1381 init_completion(&fcomp.comp);
1382 spin_lock_irqsave(&bfad->bfad_lock, flags);
1383 iocmd->status = bfa_phy_get_attr(BFA_PHY(&bfad->bfa), iocmd->instance,
1384 &iocmd->attr, bfad_hcb_comp, &fcomp);
1385 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1386 if (iocmd->status != BFA_STATUS_OK)
1387 goto out;
1388 wait_for_completion(&fcomp.comp);
1389 iocmd->status = fcomp.status;
1390out:
1391 return 0;
1392}
1393
1394int
1395bfad_iocmd_phy_get_stats(struct bfad_s *bfad, void *cmd)
1396{
1397 struct bfa_bsg_phy_stats_s *iocmd =
1398 (struct bfa_bsg_phy_stats_s *)cmd;
1399 struct bfad_hal_comp fcomp;
1400 unsigned long flags;
1401
1402 init_completion(&fcomp.comp);
1403 spin_lock_irqsave(&bfad->bfad_lock, flags);
1404 iocmd->status = bfa_phy_get_stats(BFA_PHY(&bfad->bfa), iocmd->instance,
1405 &iocmd->stats, bfad_hcb_comp, &fcomp);
1406 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1407 if (iocmd->status != BFA_STATUS_OK)
1408 goto out;
1409 wait_for_completion(&fcomp.comp);
1410 iocmd->status = fcomp.status;
1411out:
1412 return 0;
1413}
1414
1415int
1416bfad_iocmd_phy_read(struct bfad_s *bfad, void *cmd, unsigned int payload_len)
1417{
1418 struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd;
1419 struct bfad_hal_comp fcomp;
1420 void *iocmd_bufptr;
1421 unsigned long flags;
1422
1423 if (bfad_chk_iocmd_sz(payload_len,
1424 sizeof(struct bfa_bsg_phy_s),
1425 iocmd->bufsz) != BFA_STATUS_OK) {
1426 iocmd->status = BFA_STATUS_VERSION_FAIL;
1427 return 0;
1428 }
1429
1430 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_phy_s);
1431 init_completion(&fcomp.comp);
1432 spin_lock_irqsave(&bfad->bfad_lock, flags);
1433 iocmd->status = bfa_phy_read(BFA_PHY(&bfad->bfa),
1434 iocmd->instance, iocmd_bufptr, iocmd->bufsz,
1435 0, bfad_hcb_comp, &fcomp);
1436 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1437 if (iocmd->status != BFA_STATUS_OK)
1438 goto out;
1439 wait_for_completion(&fcomp.comp);
1440 iocmd->status = fcomp.status;
1441 if (iocmd->status != BFA_STATUS_OK)
1442 goto out;
1443out:
1444 return 0;
1445}
1446
61e62e21
KG
1447int
1448bfad_iocmd_vhba_query(struct bfad_s *bfad, void *cmd)
1449{
1450 struct bfa_bsg_vhba_attr_s *iocmd =
1451 (struct bfa_bsg_vhba_attr_s *)cmd;
1452 struct bfa_vhba_attr_s *attr = &iocmd->attr;
1453 unsigned long flags;
1454
1455 spin_lock_irqsave(&bfad->bfad_lock, flags);
1456 attr->pwwn = bfad->bfa.ioc.attr->pwwn;
1457 attr->nwwn = bfad->bfa.ioc.attr->nwwn;
1458 attr->plog_enabled = (bfa_boolean_t)bfad->bfa.plog->plog_enabled;
1459 attr->io_profile = bfa_fcpim_get_io_profile(&bfad->bfa);
1460 attr->path_tov = bfa_fcpim_path_tov_get(&bfad->bfa);
1461 iocmd->status = BFA_STATUS_OK;
1462 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1463 return 0;
1464}
1465
3350d98d
KG
1466int
1467bfad_iocmd_phy_update(struct bfad_s *bfad, void *cmd, unsigned int payload_len)
1468{
1469 struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd;
1470 void *iocmd_bufptr;
1471 struct bfad_hal_comp fcomp;
1472 unsigned long flags;
1473
1474 if (bfad_chk_iocmd_sz(payload_len,
1475 sizeof(struct bfa_bsg_phy_s),
1476 iocmd->bufsz) != BFA_STATUS_OK) {
1477 iocmd->status = BFA_STATUS_VERSION_FAIL;
1478 return 0;
1479 }
1480
1481 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_phy_s);
1482 init_completion(&fcomp.comp);
1483 spin_lock_irqsave(&bfad->bfad_lock, flags);
1484 iocmd->status = bfa_phy_update(BFA_PHY(&bfad->bfa),
1485 iocmd->instance, iocmd_bufptr, iocmd->bufsz,
1486 0, bfad_hcb_comp, &fcomp);
1487 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1488 if (iocmd->status != BFA_STATUS_OK)
1489 goto out;
1490 wait_for_completion(&fcomp.comp);
1491 iocmd->status = fcomp.status;
1492out:
1493 return 0;
1494}
1495
61e62e21
KG
1496int
1497bfad_iocmd_porglog_get(struct bfad_s *bfad, void *cmd)
1498{
1499 struct bfa_bsg_debug_s *iocmd = (struct bfa_bsg_debug_s *)cmd;
1500 void *iocmd_bufptr;
1501
1502 if (iocmd->bufsz < sizeof(struct bfa_plog_s)) {
1503 bfa_trc(bfad, sizeof(struct bfa_plog_s));
1504 iocmd->status = BFA_STATUS_EINVAL;
1505 goto out;
1506 }
1507
1508 iocmd->status = BFA_STATUS_OK;
1509 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_debug_s);
1510 memcpy(iocmd_bufptr, (u8 *) &bfad->plog_buf, sizeof(struct bfa_plog_s));
1511out:
1512 return 0;
1513}
1514
b85daafe
KG
1515static int
1516bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
1517 unsigned int payload_len)
1518{
9afbcfab 1519 int rc = -EINVAL;
b85daafe
KG
1520
1521 switch (cmd) {
60138066
KG
1522 case IOCMD_IOC_ENABLE:
1523 rc = bfad_iocmd_ioc_enable(bfad, iocmd);
1524 break;
1525 case IOCMD_IOC_DISABLE:
1526 rc = bfad_iocmd_ioc_disable(bfad, iocmd);
1527 break;
b85daafe
KG
1528 case IOCMD_IOC_GET_INFO:
1529 rc = bfad_iocmd_ioc_get_info(bfad, iocmd);
1530 break;
1531 case IOCMD_IOC_GET_ATTR:
1532 rc = bfad_iocmd_ioc_get_attr(bfad, iocmd);
1533 break;
60138066
KG
1534 case IOCMD_IOC_GET_STATS:
1535 rc = bfad_iocmd_ioc_get_stats(bfad, iocmd);
1536 break;
1537 case IOCMD_IOC_GET_FWSTATS:
1538 rc = bfad_iocmd_ioc_get_fwstats(bfad, iocmd, payload_len);
1539 break;
1540 case IOCMD_IOCFC_GET_ATTR:
1541 rc = bfad_iocmd_iocfc_get_attr(bfad, iocmd);
1542 break;
1543 case IOCMD_IOCFC_SET_INTR:
1544 rc = bfad_iocmd_iocfc_set_intr(bfad, iocmd);
1545 break;
1546 case IOCMD_PORT_ENABLE:
1547 rc = bfad_iocmd_port_enable(bfad, iocmd);
1548 break;
1549 case IOCMD_PORT_DISABLE:
1550 rc = bfad_iocmd_port_disable(bfad, iocmd);
1551 break;
b85daafe
KG
1552 case IOCMD_PORT_GET_ATTR:
1553 rc = bfad_iocmd_port_get_attr(bfad, iocmd);
1554 break;
60138066
KG
1555 case IOCMD_PORT_GET_STATS:
1556 rc = bfad_iocmd_port_get_stats(bfad, iocmd, payload_len);
1557 break;
b85daafe
KG
1558 case IOCMD_LPORT_GET_ATTR:
1559 rc = bfad_iocmd_lport_get_attr(bfad, iocmd);
1560 break;
60138066
KG
1561 case IOCMD_LPORT_GET_STATS:
1562 rc = bfad_iocmd_lport_get_stats(bfad, iocmd);
1563 break;
1564 case IOCMD_LPORT_GET_IOSTATS:
1565 rc = bfad_iocmd_lport_get_iostats(bfad, iocmd);
1566 break;
1567 case IOCMD_LPORT_GET_RPORTS:
1568 rc = bfad_iocmd_lport_get_rports(bfad, iocmd, payload_len);
1569 break;
1570 case IOCMD_RPORT_GET_ATTR:
1571 rc = bfad_iocmd_rport_get_attr(bfad, iocmd);
1572 break;
b85daafe
KG
1573 case IOCMD_RPORT_GET_ADDR:
1574 rc = bfad_iocmd_rport_get_addr(bfad, iocmd);
1575 break;
60138066
KG
1576 case IOCMD_RPORT_GET_STATS:
1577 rc = bfad_iocmd_rport_get_stats(bfad, iocmd);
1578 break;
b85daafe
KG
1579 case IOCMD_FABRIC_GET_LPORTS:
1580 rc = bfad_iocmd_fabric_get_lports(bfad, iocmd, payload_len);
1581 break;
60138066
KG
1582 case IOCMD_FCPIM_MODSTATS:
1583 rc = bfad_iocmd_fcpim_get_modstats(bfad, iocmd);
1584 break;
1585 case IOCMD_FCPIM_DEL_ITN_STATS:
1586 rc = bfad_iocmd_fcpim_get_del_itn_stats(bfad, iocmd);
1587 break;
b85daafe
KG
1588 case IOCMD_ITNIM_GET_ATTR:
1589 rc = bfad_iocmd_itnim_get_attr(bfad, iocmd);
1590 break;
60138066
KG
1591 case IOCMD_ITNIM_GET_IOSTATS:
1592 rc = bfad_iocmd_itnim_get_iostats(bfad, iocmd);
1593 break;
1594 case IOCMD_ITNIM_GET_ITNSTATS:
1595 rc = bfad_iocmd_itnim_get_itnstats(bfad, iocmd);
1596 break;
1597 case IOCMD_FCPORT_ENABLE:
1598 rc = bfad_iocmd_fcport_enable(bfad, iocmd);
1599 break;
1600 case IOCMD_FCPORT_DISABLE:
1601 rc = bfad_iocmd_fcport_disable(bfad, iocmd);
1602 break;
1a4d8e1b
KG
1603 case IOCMD_IOC_PCIFN_CFG:
1604 rc = bfad_iocmd_ioc_get_pcifn_cfg(bfad, iocmd);
1605 break;
1606 case IOCMD_PCIFN_CREATE:
1607 rc = bfad_iocmd_pcifn_create(bfad, iocmd);
1608 break;
1609 case IOCMD_PCIFN_DELETE:
1610 rc = bfad_iocmd_pcifn_delete(bfad, iocmd);
1611 break;
1612 case IOCMD_PCIFN_BW:
1613 rc = bfad_iocmd_pcifn_bw(bfad, iocmd);
1614 break;
1615 case IOCMD_ADAPTER_CFG_MODE:
1616 rc = bfad_iocmd_adapter_cfg_mode(bfad, iocmd);
1617 break;
1618 case IOCMD_PORT_CFG_MODE:
1619 rc = bfad_iocmd_port_cfg_mode(bfad, iocmd);
1620 break;
1621 case IOCMD_FLASH_ENABLE_OPTROM:
1622 case IOCMD_FLASH_DISABLE_OPTROM:
1623 rc = bfad_iocmd_ablk_optrom(bfad, cmd, iocmd);
1624 break;
a714134a
KG
1625 case IOCMD_FAA_ENABLE:
1626 rc = bfad_iocmd_faa_enable(bfad, iocmd);
1627 break;
1628 case IOCMD_FAA_DISABLE:
1629 rc = bfad_iocmd_faa_disable(bfad, iocmd);
1630 break;
1631 case IOCMD_FAA_QUERY:
1632 rc = bfad_iocmd_faa_query(bfad, iocmd);
1633 break;
148d6103
KG
1634 case IOCMD_CEE_GET_ATTR:
1635 rc = bfad_iocmd_cee_attr(bfad, iocmd, payload_len);
1636 break;
1637 case IOCMD_CEE_GET_STATS:
1638 rc = bfad_iocmd_cee_get_stats(bfad, iocmd, payload_len);
1639 break;
1640 case IOCMD_CEE_RESET_STATS:
1641 rc = bfad_iocmd_cee_reset_stats(bfad, iocmd);
1642 break;
51e569aa
KG
1643 case IOCMD_SFP_MEDIA:
1644 rc = bfad_iocmd_sfp_media(bfad, iocmd);
1645 break;
1646 case IOCMD_SFP_SPEED:
1647 rc = bfad_iocmd_sfp_speed(bfad, iocmd);
1648 break;
5a54b1d5
KG
1649 case IOCMD_FLASH_GET_ATTR:
1650 rc = bfad_iocmd_flash_get_attr(bfad, iocmd);
1651 break;
1652 case IOCMD_FLASH_ERASE_PART:
1653 rc = bfad_iocmd_flash_erase_part(bfad, iocmd);
1654 break;
1655 case IOCMD_FLASH_UPDATE_PART:
1656 rc = bfad_iocmd_flash_update_part(bfad, iocmd, payload_len);
1657 break;
1658 case IOCMD_FLASH_READ_PART:
1659 rc = bfad_iocmd_flash_read_part(bfad, iocmd, payload_len);
1660 break;
3d7fc66d
KG
1661 case IOCMD_DIAG_TEMP:
1662 rc = bfad_iocmd_diag_temp(bfad, iocmd);
1663 break;
1664 case IOCMD_DIAG_MEMTEST:
1665 rc = bfad_iocmd_diag_memtest(bfad, iocmd);
1666 break;
1667 case IOCMD_DIAG_LOOPBACK:
1668 rc = bfad_iocmd_diag_loopback(bfad, iocmd);
1669 break;
1670 case IOCMD_DIAG_FWPING:
1671 rc = bfad_iocmd_diag_fwping(bfad, iocmd);
1672 break;
1673 case IOCMD_DIAG_QUEUETEST:
1674 rc = bfad_iocmd_diag_queuetest(bfad, iocmd);
1675 break;
1676 case IOCMD_DIAG_SFP:
1677 rc = bfad_iocmd_diag_sfp(bfad, iocmd);
1678 break;
1679 case IOCMD_DIAG_LED:
1680 rc = bfad_iocmd_diag_led(bfad, iocmd);
1681 break;
1682 case IOCMD_DIAG_BEACON_LPORT:
1683 rc = bfad_iocmd_diag_beacon_lport(bfad, iocmd);
1684 break;
1685 case IOCMD_DIAG_LB_STAT:
1686 rc = bfad_iocmd_diag_lb_stat(bfad, iocmd);
1687 break;
3350d98d
KG
1688 case IOCMD_PHY_GET_ATTR:
1689 rc = bfad_iocmd_phy_get_attr(bfad, iocmd);
1690 break;
1691 case IOCMD_PHY_GET_STATS:
1692 rc = bfad_iocmd_phy_get_stats(bfad, iocmd);
1693 break;
1694 case IOCMD_PHY_UPDATE_FW:
1695 rc = bfad_iocmd_phy_update(bfad, iocmd, payload_len);
1696 break;
1697 case IOCMD_PHY_READ_FW:
1698 rc = bfad_iocmd_phy_read(bfad, iocmd, payload_len);
1699 break;
61e62e21
KG
1700 case IOCMD_VHBA_QUERY:
1701 rc = bfad_iocmd_vhba_query(bfad, iocmd);
1702 break;
1703 case IOCMD_DEBUG_PORTLOG:
1704 rc = bfad_iocmd_porglog_get(bfad, iocmd);
1705 break;
b85daafe 1706 default:
9afbcfab 1707 rc = -EINVAL;
b85daafe
KG
1708 break;
1709 }
9afbcfab 1710 return rc;
b85daafe
KG
1711}
1712
1713static int
1714bfad_im_bsg_vendor_request(struct fc_bsg_job *job)
1715{
1716 uint32_t vendor_cmd = job->request->rqst_data.h_vendor.vendor_cmd[0];
1717 struct bfad_im_port_s *im_port =
1718 (struct bfad_im_port_s *) job->shost->hostdata[0];
1719 struct bfad_s *bfad = im_port->bfad;
1720 void *payload_kbuf;
1721 int rc = -EINVAL;
1722
1723 /* Allocate a temp buffer to hold the passed in user space command */
1724 payload_kbuf = kzalloc(job->request_payload.payload_len, GFP_KERNEL);
1725 if (!payload_kbuf) {
1726 rc = -ENOMEM;
1727 goto out;
1728 }
1729
1730 /* Copy the sg_list passed in to a linear buffer: holds the cmnd data */
1731 sg_copy_to_buffer(job->request_payload.sg_list,
1732 job->request_payload.sg_cnt, payload_kbuf,
1733 job->request_payload.payload_len);
1734
1735 /* Invoke IOCMD handler - to handle all the vendor command requests */
1736 rc = bfad_iocmd_handler(bfad, vendor_cmd, payload_kbuf,
1737 job->request_payload.payload_len);
1738 if (rc != BFA_STATUS_OK)
1739 goto error;
1740
1741 /* Copy the response data to the job->reply_payload sg_list */
1742 sg_copy_from_buffer(job->reply_payload.sg_list,
1743 job->reply_payload.sg_cnt,
1744 payload_kbuf,
1745 job->reply_payload.payload_len);
1746
1747 /* free the command buffer */
1748 kfree(payload_kbuf);
1749
1750 /* Fill the BSG job reply data */
1751 job->reply_len = job->reply_payload.payload_len;
1752 job->reply->reply_payload_rcv_len = job->reply_payload.payload_len;
1753 job->reply->result = rc;
1754
1755 job->job_done(job);
1756 return rc;
1757error:
1758 /* free the command buffer */
1759 kfree(payload_kbuf);
1760out:
1761 job->reply->result = rc;
1762 job->reply_len = sizeof(uint32_t);
1763 job->reply->reply_payload_rcv_len = 0;
1764 return rc;
1765}
1766
1767/* FC passthru call backs */
1768u64
1769bfad_fcxp_get_req_sgaddr_cb(void *bfad_fcxp, int sgeid)
1770{
1771 struct bfad_fcxp *drv_fcxp = bfad_fcxp;
1772 struct bfa_sge_s *sge;
1773 u64 addr;
1774
1775 sge = drv_fcxp->req_sge + sgeid;
1776 addr = (u64)(size_t) sge->sg_addr;
1777 return addr;
1778}
1779
1780u32
1781bfad_fcxp_get_req_sglen_cb(void *bfad_fcxp, int sgeid)
1782{
1783 struct bfad_fcxp *drv_fcxp = bfad_fcxp;
1784 struct bfa_sge_s *sge;
1785
1786 sge = drv_fcxp->req_sge + sgeid;
1787 return sge->sg_len;
1788}
1789
1790u64
1791bfad_fcxp_get_rsp_sgaddr_cb(void *bfad_fcxp, int sgeid)
1792{
1793 struct bfad_fcxp *drv_fcxp = bfad_fcxp;
1794 struct bfa_sge_s *sge;
1795 u64 addr;
1796
1797 sge = drv_fcxp->rsp_sge + sgeid;
1798 addr = (u64)(size_t) sge->sg_addr;
1799 return addr;
1800}
1801
1802u32
1803bfad_fcxp_get_rsp_sglen_cb(void *bfad_fcxp, int sgeid)
1804{
1805 struct bfad_fcxp *drv_fcxp = bfad_fcxp;
1806 struct bfa_sge_s *sge;
1807
1808 sge = drv_fcxp->rsp_sge + sgeid;
1809 return sge->sg_len;
1810}
1811
1812void
1813bfad_send_fcpt_cb(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg,
1814 bfa_status_t req_status, u32 rsp_len, u32 resid_len,
1815 struct fchs_s *rsp_fchs)
1816{
1817 struct bfad_fcxp *drv_fcxp = bfad_fcxp;
1818
1819 drv_fcxp->req_status = req_status;
1820 drv_fcxp->rsp_len = rsp_len;
1821
1822 /* bfa_fcxp will be automatically freed by BFA */
1823 drv_fcxp->bfa_fcxp = NULL;
1824 complete(&drv_fcxp->comp);
1825}
1826
1827struct bfad_buf_info *
1828bfad_fcxp_map_sg(struct bfad_s *bfad, void *payload_kbuf,
1829 uint32_t payload_len, uint32_t *num_sgles)
1830{
1831 struct bfad_buf_info *buf_base, *buf_info;
1832 struct bfa_sge_s *sg_table;
1833 int sge_num = 1;
1834
1835 buf_base = kzalloc((sizeof(struct bfad_buf_info) +
1836 sizeof(struct bfa_sge_s)) * sge_num, GFP_KERNEL);
1837 if (!buf_base)
1838 return NULL;
1839
1840 sg_table = (struct bfa_sge_s *) (((uint8_t *)buf_base) +
1841 (sizeof(struct bfad_buf_info) * sge_num));
1842
1843 /* Allocate dma coherent memory */
1844 buf_info = buf_base;
1845 buf_info->size = payload_len;
1846 buf_info->virt = dma_alloc_coherent(&bfad->pcidev->dev, buf_info->size,
1847 &buf_info->phys, GFP_KERNEL);
1848 if (!buf_info->virt)
1849 goto out_free_mem;
1850
1851 /* copy the linear bsg buffer to buf_info */
1852 memset(buf_info->virt, 0, buf_info->size);
1853 memcpy(buf_info->virt, payload_kbuf, buf_info->size);
1854
1855 /*
1856 * Setup SG table
1857 */
1858 sg_table->sg_len = buf_info->size;
1859 sg_table->sg_addr = (void *)(size_t) buf_info->phys;
1860
1861 *num_sgles = sge_num;
1862
1863 return buf_base;
1864
1865out_free_mem:
1866 kfree(buf_base);
1867 return NULL;
1868}
1869
1870void
1871bfad_fcxp_free_mem(struct bfad_s *bfad, struct bfad_buf_info *buf_base,
1872 uint32_t num_sgles)
1873{
1874 int i;
1875 struct bfad_buf_info *buf_info = buf_base;
1876
1877 if (buf_base) {
1878 for (i = 0; i < num_sgles; buf_info++, i++) {
1879 if (buf_info->virt != NULL)
1880 dma_free_coherent(&bfad->pcidev->dev,
1881 buf_info->size, buf_info->virt,
1882 buf_info->phys);
1883 }
1884 kfree(buf_base);
1885 }
1886}
1887
1888int
1889bfad_fcxp_bsg_send(struct fc_bsg_job *job, struct bfad_fcxp *drv_fcxp,
1890 bfa_bsg_fcpt_t *bsg_fcpt)
1891{
1892 struct bfa_fcxp_s *hal_fcxp;
1893 struct bfad_s *bfad = drv_fcxp->port->bfad;
1894 unsigned long flags;
1895 uint8_t lp_tag;
1896
1897 spin_lock_irqsave(&bfad->bfad_lock, flags);
1898
1899 /* Allocate bfa_fcxp structure */
1900 hal_fcxp = bfa_fcxp_alloc(drv_fcxp, &bfad->bfa,
1901 drv_fcxp->num_req_sgles,
1902 drv_fcxp->num_rsp_sgles,
1903 bfad_fcxp_get_req_sgaddr_cb,
1904 bfad_fcxp_get_req_sglen_cb,
1905 bfad_fcxp_get_rsp_sgaddr_cb,
1906 bfad_fcxp_get_rsp_sglen_cb);
1907 if (!hal_fcxp) {
1908 bfa_trc(bfad, 0);
1909 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1910 return BFA_STATUS_ENOMEM;
1911 }
1912
1913 drv_fcxp->bfa_fcxp = hal_fcxp;
1914
1915 lp_tag = bfa_lps_get_tag_from_pid(&bfad->bfa, bsg_fcpt->fchs.s_id);
1916
1917 bfa_fcxp_send(hal_fcxp, drv_fcxp->bfa_rport, bsg_fcpt->vf_id, lp_tag,
1918 bsg_fcpt->cts, bsg_fcpt->cos,
1919 job->request_payload.payload_len,
1920 &bsg_fcpt->fchs, bfad_send_fcpt_cb, bfad,
1921 job->reply_payload.payload_len, bsg_fcpt->tsecs);
1922
1923 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1924
1925 return BFA_STATUS_OK;
1926}
1927
1928int
1929bfad_im_bsg_els_ct_request(struct fc_bsg_job *job)
1930{
1931 struct bfa_bsg_data *bsg_data;
1932 struct bfad_im_port_s *im_port =
1933 (struct bfad_im_port_s *) job->shost->hostdata[0];
1934 struct bfad_s *bfad = im_port->bfad;
1935 bfa_bsg_fcpt_t *bsg_fcpt;
1936 struct bfad_fcxp *drv_fcxp;
1937 struct bfa_fcs_lport_s *fcs_port;
1938 struct bfa_fcs_rport_s *fcs_rport;
1939 uint32_t command_type = job->request->msgcode;
1940 unsigned long flags;
1941 struct bfad_buf_info *rsp_buf_info;
1942 void *req_kbuf = NULL, *rsp_kbuf = NULL;
1943 int rc = -EINVAL;
1944
1945 job->reply_len = sizeof(uint32_t); /* Atleast uint32_t reply_len */
1946 job->reply->reply_payload_rcv_len = 0;
1947
1948 /* Get the payload passed in from userspace */
1949 bsg_data = (struct bfa_bsg_data *) (((char *)job->request) +
1950 sizeof(struct fc_bsg_request));
1951 if (bsg_data == NULL)
1952 goto out;
1953
1954 /*
1955 * Allocate buffer for bsg_fcpt and do a copy_from_user op for payload
1956 * buffer of size bsg_data->payload_len
1957 */
1958 bsg_fcpt = (struct bfa_bsg_fcpt_s *)
1959 kzalloc(bsg_data->payload_len, GFP_KERNEL);
1960 if (!bsg_fcpt)
1961 goto out;
1962
1963 if (copy_from_user((uint8_t *)bsg_fcpt, bsg_data->payload,
1964 bsg_data->payload_len)) {
1965 kfree(bsg_fcpt);
1966 goto out;
1967 }
1968
1969 drv_fcxp = kzalloc(sizeof(struct bfad_fcxp), GFP_KERNEL);
1970 if (drv_fcxp == NULL) {
1971 rc = -ENOMEM;
1972 goto out;
1973 }
1974
1975 spin_lock_irqsave(&bfad->bfad_lock, flags);
1976 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, bsg_fcpt->vf_id,
1977 bsg_fcpt->lpwwn);
1978 if (fcs_port == NULL) {
1979 bsg_fcpt->status = BFA_STATUS_UNKNOWN_LWWN;
1980 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1981 goto out_free_mem;
1982 }
1983
1984 /* Check if the port is online before sending FC Passthru cmd */
1985 if (!bfa_fcs_lport_is_online(fcs_port)) {
1986 bsg_fcpt->status = BFA_STATUS_PORT_OFFLINE;
1987 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1988 goto out_free_mem;
1989 }
1990
1991 drv_fcxp->port = fcs_port->bfad_port;
1992
1993 if (drv_fcxp->port->bfad == 0)
1994 drv_fcxp->port->bfad = bfad;
1995
1996 /* Fetch the bfa_rport - if nexus needed */
1997 if (command_type == FC_BSG_HST_ELS_NOLOGIN ||
1998 command_type == FC_BSG_HST_CT) {
1999 /* BSG HST commands: no nexus needed */
2000 drv_fcxp->bfa_rport = NULL;
2001
2002 } else if (command_type == FC_BSG_RPT_ELS ||
2003 command_type == FC_BSG_RPT_CT) {
2004 /* BSG RPT commands: nexus needed */
2005 fcs_rport = bfa_fcs_lport_get_rport_by_pwwn(fcs_port,
2006 bsg_fcpt->dpwwn);
2007 if (fcs_rport == NULL) {
2008 bsg_fcpt->status = BFA_STATUS_UNKNOWN_RWWN;
2009 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2010 goto out_free_mem;
2011 }
2012
2013 drv_fcxp->bfa_rport = fcs_rport->bfa_rport;
2014
2015 } else { /* Unknown BSG msgcode; return -EINVAL */
2016 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2017 goto out_free_mem;
2018 }
2019
2020 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2021
2022 /* allocate memory for req / rsp buffers */
2023 req_kbuf = kzalloc(job->request_payload.payload_len, GFP_KERNEL);
2024 if (!req_kbuf) {
2025 printk(KERN_INFO "bfa %s: fcpt request buffer alloc failed\n",
2026 bfad->pci_name);
2027 rc = -ENOMEM;
2028 goto out_free_mem;
2029 }
2030
2031 rsp_kbuf = kzalloc(job->reply_payload.payload_len, GFP_KERNEL);
2032 if (!rsp_kbuf) {
2033 printk(KERN_INFO "bfa %s: fcpt response buffer alloc failed\n",
2034 bfad->pci_name);
2035 rc = -ENOMEM;
2036 goto out_free_mem;
2037 }
2038
2039 /* map req sg - copy the sg_list passed in to the linear buffer */
2040 sg_copy_to_buffer(job->request_payload.sg_list,
2041 job->request_payload.sg_cnt, req_kbuf,
2042 job->request_payload.payload_len);
2043
2044 drv_fcxp->reqbuf_info = bfad_fcxp_map_sg(bfad, req_kbuf,
2045 job->request_payload.payload_len,
2046 &drv_fcxp->num_req_sgles);
2047 if (!drv_fcxp->reqbuf_info) {
2048 printk(KERN_INFO "bfa %s: fcpt request fcxp_map_sg failed\n",
2049 bfad->pci_name);
2050 rc = -ENOMEM;
2051 goto out_free_mem;
2052 }
2053
2054 drv_fcxp->req_sge = (struct bfa_sge_s *)
2055 (((uint8_t *)drv_fcxp->reqbuf_info) +
2056 (sizeof(struct bfad_buf_info) *
2057 drv_fcxp->num_req_sgles));
2058
2059 /* map rsp sg */
2060 drv_fcxp->rspbuf_info = bfad_fcxp_map_sg(bfad, rsp_kbuf,
2061 job->reply_payload.payload_len,
2062 &drv_fcxp->num_rsp_sgles);
2063 if (!drv_fcxp->rspbuf_info) {
2064 printk(KERN_INFO "bfa %s: fcpt response fcxp_map_sg failed\n",
2065 bfad->pci_name);
2066 rc = -ENOMEM;
2067 goto out_free_mem;
2068 }
2069
2070 rsp_buf_info = (struct bfad_buf_info *)drv_fcxp->rspbuf_info;
2071 drv_fcxp->rsp_sge = (struct bfa_sge_s *)
2072 (((uint8_t *)drv_fcxp->rspbuf_info) +
2073 (sizeof(struct bfad_buf_info) *
2074 drv_fcxp->num_rsp_sgles));
2075
2076 /* fcxp send */
2077 init_completion(&drv_fcxp->comp);
2078 rc = bfad_fcxp_bsg_send(job, drv_fcxp, bsg_fcpt);
2079 if (rc == BFA_STATUS_OK) {
2080 wait_for_completion(&drv_fcxp->comp);
2081 bsg_fcpt->status = drv_fcxp->req_status;
2082 } else {
2083 bsg_fcpt->status = rc;
2084 goto out_free_mem;
2085 }
2086
2087 /* fill the job->reply data */
2088 if (drv_fcxp->req_status == BFA_STATUS_OK) {
2089 job->reply_len = drv_fcxp->rsp_len;
2090 job->reply->reply_payload_rcv_len = drv_fcxp->rsp_len;
2091 job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
2092 } else {
2093 job->reply->reply_payload_rcv_len =
2094 sizeof(struct fc_bsg_ctels_reply);
2095 job->reply_len = sizeof(uint32_t);
2096 job->reply->reply_data.ctels_reply.status =
2097 FC_CTELS_STATUS_REJECT;
2098 }
2099
2100 /* Copy the response data to the reply_payload sg list */
2101 sg_copy_from_buffer(job->reply_payload.sg_list,
2102 job->reply_payload.sg_cnt,
2103 (uint8_t *)rsp_buf_info->virt,
2104 job->reply_payload.payload_len);
2105
2106out_free_mem:
2107 bfad_fcxp_free_mem(bfad, drv_fcxp->rspbuf_info,
2108 drv_fcxp->num_rsp_sgles);
2109 bfad_fcxp_free_mem(bfad, drv_fcxp->reqbuf_info,
2110 drv_fcxp->num_req_sgles);
2111 kfree(req_kbuf);
2112 kfree(rsp_kbuf);
2113
2114 /* Need a copy to user op */
2115 if (copy_to_user(bsg_data->payload, (void *) bsg_fcpt,
2116 bsg_data->payload_len))
2117 rc = -EIO;
2118
2119 kfree(bsg_fcpt);
2120 kfree(drv_fcxp);
2121out:
2122 job->reply->result = rc;
2123
2124 if (rc == BFA_STATUS_OK)
2125 job->job_done(job);
2126
2127 return rc;
2128}
2129
2130int
2131bfad_im_bsg_request(struct fc_bsg_job *job)
2132{
2133 uint32_t rc = BFA_STATUS_OK;
2134
b85daafe
KG
2135 switch (job->request->msgcode) {
2136 case FC_BSG_HST_VENDOR:
2137 /* Process BSG HST Vendor requests */
2138 rc = bfad_im_bsg_vendor_request(job);
2139 break;
2140 case FC_BSG_HST_ELS_NOLOGIN:
2141 case FC_BSG_RPT_ELS:
2142 case FC_BSG_HST_CT:
2143 case FC_BSG_RPT_CT:
2144 /* Process BSG ELS/CT commands */
2145 rc = bfad_im_bsg_els_ct_request(job);
2146 break;
2147 default:
2148 job->reply->result = rc = -EINVAL;
2149 job->reply->reply_payload_rcv_len = 0;
2150 break;
2151 }
2152
b85daafe
KG
2153 return rc;
2154}
2155
2156int
2157bfad_im_bsg_timeout(struct fc_bsg_job *job)
2158{
2159 /* Don't complete the BSG job request - return -EAGAIN
2160 * to reset bsg job timeout : for ELS/CT pass thru we
2161 * already have timer to track the request.
2162 */
2163 return -EAGAIN;
2164}