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