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