blob: 89f863ed2334e9c14c8bbf341a75b22993adc6e0 [file] [log] [blame]
Krishna Gudipatib85daaf2011-06-13 15:55:11 -07001/*
2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <linux/uaccess.h>
19#include "bfad_drv.h"
20#include "bfad_im.h"
21#include "bfad_bsg.h"
22
23BFA_TRC_FILE(LDRV, BSG);
24
Krishna Gudipati60138062011-06-24 20:25:15 -070025int
26bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd)
27{
28 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
29 int rc = 0;
30 unsigned long flags;
31
32 spin_lock_irqsave(&bfad->bfad_lock, flags);
33 /* If IOC is not in disabled state - return */
34 if (!bfa_ioc_is_disabled(&bfad->bfa.ioc)) {
35 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
36 iocmd->status = BFA_STATUS_IOC_FAILURE;
37 return rc;
38 }
39
40 init_completion(&bfad->enable_comp);
41 bfa_iocfc_enable(&bfad->bfa);
42 iocmd->status = BFA_STATUS_OK;
43 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
44 wait_for_completion(&bfad->enable_comp);
45
46 return rc;
47}
48
49int
50bfad_iocmd_ioc_disable(struct bfad_s *bfad, void *cmd)
51{
52 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
53 int rc = 0;
54 unsigned long flags;
55
56 spin_lock_irqsave(&bfad->bfad_lock, flags);
57 if (bfad->disable_active) {
58 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
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
Krishna Gudipatib85daaf2011-06-13 15:55:11 -070074static int
75bfad_iocmd_ioc_get_info(struct bfad_s *bfad, void *cmd)
76{
77 int i;
78 struct bfa_bsg_ioc_info_s *iocmd = (struct bfa_bsg_ioc_info_s *)cmd;
79 struct bfad_im_port_s *im_port;
80 struct bfa_port_attr_s pattr;
81 unsigned long flags;
82
83 spin_lock_irqsave(&bfad->bfad_lock, flags);
84 bfa_fcport_get_attr(&bfad->bfa, &pattr);
85 iocmd->nwwn = pattr.nwwn;
86 iocmd->pwwn = pattr.pwwn;
87 iocmd->ioc_type = bfa_get_type(&bfad->bfa);
88 iocmd->mac = bfa_get_mac(&bfad->bfa);
89 iocmd->factory_mac = bfa_get_mfg_mac(&bfad->bfa);
90 bfa_get_adapter_serial_num(&bfad->bfa, iocmd->serialnum);
91 iocmd->factorynwwn = pattr.factorynwwn;
92 iocmd->factorypwwn = pattr.factorypwwn;
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
111static int
112bfad_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
Krishna Gudipati60138062011-06-24 20:25:15 -0700140int
141bfad_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
150int
151bfad_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 }
175out:
176 bfa_trc(bfad, 0x6666);
177 return 0;
178}
179
180int
181bfad_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
191int
192bfad_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
204int
205bfad_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
225int
226bfad_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
Krishna Gudipatib85daaf2011-06-13 15:55:11 -0700247static int
248bfad_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
Krishna Gudipati60138062011-06-24 20:25:15 -0700275int
276bfad_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;
305out:
306 return 0;
307}
308
Krishna Gudipatib85daaf2011-06-13 15:55:11 -0700309static int
310bfad_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;
328out:
329 return 0;
330}
331
Krishna Gudipati60138062011-06-24 20:25:15 -0700332int
333bfad_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;
352out:
353 return 0;
354}
355
356int
357bfad_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;
377out:
378 return 0;
379}
380
381int
382bfad_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;
417out:
418 return 0;
419}
420
421int
422bfad_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;
450out:
451 return 0;
452}
453
Krishna Gudipatib85daaf2011-06-13 15:55:11 -0700454static int
455bfad_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;
499out:
500 return 0;
501}
502
Krishna Gudipati60138062011-06-24 20:25:15 -0700503int
504bfad_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;
538out:
539 return 0;
540}
541
Krishna Gudipatib85daaf2011-06-13 15:55:11 -0700542static int
543bfad_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;
580out:
581 return 0;
582}
583
Krishna Gudipati60138062011-06-24 20:25:15 -0700584int
585bfad_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
606int
607bfad_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
Krishna Gudipatib85daaf2011-06-13 15:55:11 -0700623static int
624bfad_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
Krishna Gudipati60138062011-06-24 20:25:15 -0700642static int
643bfad_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
672static int
673bfad_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
701int
702bfad_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
714int
715bfad_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
Krishna Gudipati1a4d8e12011-06-24 20:22:28 -0700727int
728bfad_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;
745out:
746 return 0;
747}
748
749int
750bfad_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;
768out:
769 return 0;
770}
771
772int
773bfad_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;
790out:
791 return 0;
792}
793
794int
795bfad_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);
814out:
815 return 0;
816}
817
818int
819bfad_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;
837out:
838 return 0;
839}
840
841int
842bfad_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;
861out:
862 return 0;
863}
864
865int
866bfad_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;
887out:
888 return 0;
889}
890
Krishna Gudipatia7141342011-06-24 20:23:19 -0700891int
892bfad_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;
909out:
910 return 0;
911}
912
913int
914bfad_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;
931out:
932 return 0;
933}
934
935int
936bfad_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;
954out:
955 return 0;
956}
957
Krishna Gudipati148d6102011-06-24 20:25:36 -0700958int
959bfad_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);
990out:
991 return 0;
992}
993
994int
995bfad_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);
1027out:
1028 return 0;
1029}
1030
1031int
1032bfad_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
Krishna Gudipati51e569a2011-06-24 20:26:25 -07001045int
1046bfad_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;
1063out:
1064 return 0;
1065}
1066
1067int
1068bfad_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;
1084out:
1085 return 0;
1086}
1087
Krishna Gudipati5a54b1d2011-06-24 20:27:13 -07001088int
1089bfad_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;
1105out:
1106 return 0;
1107}
1108
1109int
1110bfad_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;
1125out:
1126 return 0;
1127}
1128
1129int
1130bfad_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;
1157out:
1158 return 0;
1159}
1160
1161int
1162bfad_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;
1189out:
1190 return 0;
1191}
1192
Krishna Gudipati3d7fc662011-06-24 20:28:17 -07001193int
1194bfad_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;
1211out:
1212 return 0;
1213}
1214
1215int
1216bfad_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;
1234out:
1235 return 0;
1236}
1237
1238int
1239bfad_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;
1257out:
1258 return 0;
1259}
1260
1261int
1262bfad_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;
1281out:
1282 return 0;
1283}
1284
1285int
1286bfad_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;
1302out:
1303 return 0;
1304}
1305
1306int
1307bfad_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);
1325out:
1326 return 0;
1327}
1328
1329int
1330bfad_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
1342int
1343bfad_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
1357int
1358bfad_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
Krishna Gudipati3350d982011-06-24 20:28:37 -07001372int
1373bfad_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;
1389out:
1390 return 0;
1391}
1392
1393int
1394bfad_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;
1410out:
1411 return 0;
1412}
1413
1414int
1415bfad_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;
1442out:
1443 return 0;
1444}
1445
1446int
Krishna Gudipati61e62e22011-06-24 20:29:07 -07001447bfad_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
1465int
Krishna Gudipati3350d982011-06-24 20:28:37 -07001466bfad_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;
1491out:
1492 return 0;
1493}
1494
Krishna Gudipati61e62e22011-06-24 20:29:07 -07001495int
1496bfad_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));
1510out:
1511 return 0;
1512}
1513
Krishna Gudipatib85daaf2011-06-13 15:55:11 -07001514static int
1515bfad_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) {
Krishna Gudipati60138062011-06-24 20:25:15 -07001521 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;
Krishna Gudipatib85daaf2011-06-13 15:55:11 -07001527 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;
Krishna Gudipati60138062011-06-24 20:25:15 -07001533 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;
Krishna Gudipatib85daaf2011-06-13 15:55:11 -07001551 case IOCMD_PORT_GET_ATTR:
1552 rc = bfad_iocmd_port_get_attr(bfad, iocmd);
1553 break;
Krishna Gudipati60138062011-06-24 20:25:15 -07001554 case IOCMD_PORT_GET_STATS:
1555 rc = bfad_iocmd_port_get_stats(bfad, iocmd, payload_len);
1556 break;
Krishna Gudipatib85daaf2011-06-13 15:55:11 -07001557 case IOCMD_LPORT_GET_ATTR:
1558 rc = bfad_iocmd_lport_get_attr(bfad, iocmd);
1559 break;
Krishna Gudipati60138062011-06-24 20:25:15 -07001560 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;
Krishna Gudipatib85daaf2011-06-13 15:55:11 -07001572 case IOCMD_RPORT_GET_ADDR:
1573 rc = bfad_iocmd_rport_get_addr(bfad, iocmd);
1574 break;
Krishna Gudipati60138062011-06-24 20:25:15 -07001575 case IOCMD_RPORT_GET_STATS:
1576 rc = bfad_iocmd_rport_get_stats(bfad, iocmd);
1577 break;
Krishna Gudipatib85daaf2011-06-13 15:55:11 -07001578 case IOCMD_FABRIC_GET_LPORTS:
1579 rc = bfad_iocmd_fabric_get_lports(bfad, iocmd, payload_len);
1580 break;
Krishna Gudipati60138062011-06-24 20:25:15 -07001581 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;
Krishna Gudipatib85daaf2011-06-13 15:55:11 -07001587 case IOCMD_ITNIM_GET_ATTR:
1588 rc = bfad_iocmd_itnim_get_attr(bfad, iocmd);
1589 break;
Krishna Gudipati60138062011-06-24 20:25:15 -07001590 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;
Krishna Gudipati1a4d8e12011-06-24 20:22:28 -07001602 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;
Krishna Gudipatia7141342011-06-24 20:23:19 -07001624 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;
Krishna Gudipati148d6102011-06-24 20:25:36 -07001633 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;
Krishna Gudipati51e569a2011-06-24 20:26:25 -07001642 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;
Krishna Gudipati5a54b1d2011-06-24 20:27:13 -07001648 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;
Krishna Gudipati3d7fc662011-06-24 20:28:17 -07001660 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;
Krishna Gudipati3350d982011-06-24 20:28:37 -07001687 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;
Krishna Gudipati61e62e22011-06-24 20:29:07 -07001699 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;
Krishna Gudipatib85daaf2011-06-13 15:55:11 -07001705 default:
1706 rc = EINVAL;
1707 break;
1708 }
1709 return -rc;
1710}
1711
1712static int
1713bfad_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;
1756error:
1757 /* free the command buffer */
1758 kfree(payload_kbuf);
1759out:
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 */
1767u64
1768bfad_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
1779u32
1780bfad_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
1789u64
1790bfad_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
1801u32
1802bfad_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
1811void
1812bfad_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
1826struct bfad_buf_info *
1827bfad_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
1864out_free_mem:
1865 kfree(buf_base);
1866 return NULL;
1867}
1868
1869void
1870bfad_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
1887int
1888bfad_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
1927int
1928bfad_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
2105out_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);
2120out:
2121 job->reply->result = rc;
2122
2123 if (rc == BFA_STATUS_OK)
2124 job->job_done(job);
2125
2126 return rc;
2127}
2128
2129int
2130bfad_im_bsg_request(struct fc_bsg_job *job)
2131{
2132 uint32_t rc = BFA_STATUS_OK;
2133
Krishna Gudipatib85daaf2011-06-13 15:55:11 -07002134 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
Krishna Gudipatib85daaf2011-06-13 15:55:11 -07002152 return rc;
2153}
2154
2155int
2156bfad_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}