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