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