aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJing Huang <huangj@brocade.com>2009-09-23 20:46:15 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-10-02 10:47:40 -0400
commit7725ccfda59715ecf8f99e3b520a0b84cc2ea79e (patch)
treedf76910891c6b92bf23c06c84955bf600c9d7573 /drivers
parent5415907af1f5ef80c95147bacbd321b0d4236dd5 (diff)
[SCSI] bfa: Brocade BFA FC SCSI driver
Add new driver for Brocade Hardware Signed-off-by: Jing Huang <huangj@brocade.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/Kconfig10
-rw-r--r--drivers/scsi/Makefile1
-rw-r--r--drivers/scsi/bfa/Makefile15
-rw-r--r--drivers/scsi/bfa/bfa_callback_priv.h57
-rw-r--r--drivers/scsi/bfa/bfa_cb_ioim_macros.h205
-rw-r--r--drivers/scsi/bfa/bfa_cee.c492
-rw-r--r--drivers/scsi/bfa/bfa_core.c402
-rw-r--r--drivers/scsi/bfa/bfa_csdebug.c58
-rw-r--r--drivers/scsi/bfa/bfa_fcpim.c175
-rw-r--r--drivers/scsi/bfa/bfa_fcpim_priv.h188
-rw-r--r--drivers/scsi/bfa/bfa_fcport.c1671
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c182
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c940
-rw-r--r--drivers/scsi/bfa/bfa_fcs_port.c68
-rw-r--r--drivers/scsi/bfa/bfa_fcs_uf.c105
-rw-r--r--drivers/scsi/bfa/bfa_fcxp.c782
-rw-r--r--drivers/scsi/bfa/bfa_fcxp_priv.h138
-rw-r--r--drivers/scsi/bfa/bfa_fwimg_priv.h31
-rw-r--r--drivers/scsi/bfa/bfa_hw_cb.c142
-rw-r--r--drivers/scsi/bfa/bfa_hw_ct.c162
-rw-r--r--drivers/scsi/bfa/bfa_intr.c218
-rw-r--r--drivers/scsi/bfa/bfa_intr_priv.h115
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c2382
-rw-r--r--drivers/scsi/bfa/bfa_ioc.h259
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.c872
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.h168
-rw-r--r--drivers/scsi/bfa/bfa_iocfc_q.c44
-rw-r--r--drivers/scsi/bfa/bfa_ioim.c1311
-rw-r--r--drivers/scsi/bfa/bfa_itnim.c1088
-rw-r--r--drivers/scsi/bfa/bfa_log.c346
-rw-r--r--drivers/scsi/bfa/bfa_log_module.c451
-rw-r--r--drivers/scsi/bfa/bfa_lps.c782
-rw-r--r--drivers/scsi/bfa/bfa_lps_priv.h38
-rw-r--r--drivers/scsi/bfa/bfa_module.c90
-rw-r--r--drivers/scsi/bfa/bfa_modules_priv.h43
-rw-r--r--drivers/scsi/bfa/bfa_os_inc.h222
-rw-r--r--drivers/scsi/bfa/bfa_port.c460
-rw-r--r--drivers/scsi/bfa/bfa_port_priv.h90
-rw-r--r--drivers/scsi/bfa/bfa_priv.h113
-rw-r--r--drivers/scsi/bfa/bfa_rport.c911
-rw-r--r--drivers/scsi/bfa/bfa_rport_priv.h45
-rw-r--r--drivers/scsi/bfa/bfa_sgpg.c231
-rw-r--r--drivers/scsi/bfa/bfa_sgpg_priv.h79
-rw-r--r--drivers/scsi/bfa/bfa_sm.c38
-rw-r--r--drivers/scsi/bfa/bfa_timer.c90
-rw-r--r--drivers/scsi/bfa/bfa_trcmod_priv.h66
-rw-r--r--drivers/scsi/bfa/bfa_tskim.c689
-rw-r--r--drivers/scsi/bfa/bfa_uf.c345
-rw-r--r--drivers/scsi/bfa/bfa_uf_priv.h47
-rw-r--r--drivers/scsi/bfa/bfad.c1182
-rw-r--r--drivers/scsi/bfa/bfad_attr.c649
-rw-r--r--drivers/scsi/bfa/bfad_attr.h65
-rw-r--r--drivers/scsi/bfa/bfad_drv.h295
-rw-r--r--drivers/scsi/bfa/bfad_fwimg.c95
-rw-r--r--drivers/scsi/bfa/bfad_im.c1230
-rw-r--r--drivers/scsi/bfa/bfad_im.h150
-rw-r--r--drivers/scsi/bfa/bfad_im_compat.h46
-rw-r--r--drivers/scsi/bfa/bfad_intr.c214
-rw-r--r--drivers/scsi/bfa/bfad_ipfc.h42
-rw-r--r--drivers/scsi/bfa/bfad_os.c50
-rw-r--r--drivers/scsi/bfa/bfad_tm.h59
-rw-r--r--drivers/scsi/bfa/bfad_trcmod.h52
-rw-r--r--drivers/scsi/bfa/fab.c62
-rw-r--r--drivers/scsi/bfa/fabric.c1278
-rw-r--r--drivers/scsi/bfa/fcbuild.c1449
-rw-r--r--drivers/scsi/bfa/fcbuild.h273
-rw-r--r--drivers/scsi/bfa/fcpim.c844
-rw-r--r--drivers/scsi/bfa/fcptm.c68
-rw-r--r--drivers/scsi/bfa/fcs.h30
-rw-r--r--drivers/scsi/bfa/fcs_auth.h37
-rw-r--r--drivers/scsi/bfa/fcs_fabric.h61
-rw-r--r--drivers/scsi/bfa/fcs_fcpim.h44
-rw-r--r--drivers/scsi/bfa/fcs_fcptm.h45
-rw-r--r--drivers/scsi/bfa/fcs_fcxp.h29
-rw-r--r--drivers/scsi/bfa/fcs_lport.h117
-rw-r--r--drivers/scsi/bfa/fcs_ms.h35
-rw-r--r--drivers/scsi/bfa/fcs_port.h32
-rw-r--r--drivers/scsi/bfa/fcs_rport.h61
-rw-r--r--drivers/scsi/bfa/fcs_trcmod.h56
-rw-r--r--drivers/scsi/bfa/fcs_uf.h32
-rw-r--r--drivers/scsi/bfa/fcs_vport.h39
-rw-r--r--drivers/scsi/bfa/fdmi.c1223
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen.h92
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_adapter.h31
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_audit.h31
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_ethport.h35
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_ioc.h37
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_itnim.h33
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_lport.h51
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_port.h57
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_rport.h37
-rw-r--r--drivers/scsi/bfa/include/bfa.h177
-rw-r--r--drivers/scsi/bfa/include/bfa_fcpim.h159
-rw-r--r--drivers/scsi/bfa/include/bfa_fcptm.h47
-rw-r--r--drivers/scsi/bfa/include/bfa_svc.h324
-rw-r--r--drivers/scsi/bfa/include/bfa_timer.h53
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi.h174
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_boot.h34
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_cbreg.h305
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_cee.h119
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ctreg.h611
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_fabric.h92
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_fcpim.h301
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_fcxp.h71
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ioc.h202
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_iocfc.h177
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_lport.h89
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_lps.h96
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_port.h115
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_pport.h184
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_rport.h104
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_uf.h52
-rw-r--r--drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h36
-rw-r--r--drivers/scsi/bfa/include/cna/cee/bfa_cee.h77
-rw-r--r--drivers/scsi/bfa/include/cna/port/bfa_port.h69
-rw-r--r--drivers/scsi/bfa/include/cna/pstats/ethport_defs.h36
-rw-r--r--drivers/scsi/bfa/include/cna/pstats/phyport_defs.h218
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_checksum.h60
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_debug.h44
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_log.h184
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_perf.h34
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_plog.h162
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_q.h81
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_sm.h69
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_trc.h176
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_wc.h68
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_adapter.h82
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_aen.h73
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_audit.h38
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_auth.h112
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_boot.h71
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_cee.h159
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_driver.h40
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_ethport.h98
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_fcpim.h45
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_im_common.h32
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_im_team.h72
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_ioc.h152
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h310
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_ipfc.h70
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_itnim.h126
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_led.h35
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_lport.h68
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_mfg.h58
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pci.h41
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pm.h33
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pom.h56
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_port.h245
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pport.h383
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_qos.h99
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_rport.h199
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_status.h255
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_tin.h118
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h43
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_types.h30
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_version.h22
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_vf.h74
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_vport.h91
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb.h33
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h76
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_port.h113
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_rport.h80
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_vf.h47
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h47
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs.h73
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_auth.h82
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h112
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h131
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_fdmi.h63
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h226
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h104
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h63
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_fcs.h28
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_hal.h30
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_linux.h44
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_wdrv.h36
-rw-r--r--drivers/scsi/bfa/include/protocol/ct.h492
-rw-r--r--drivers/scsi/bfa/include/protocol/fc.h1105
-rw-r--r--drivers/scsi/bfa/include/protocol/fc_sp.h224
-rw-r--r--drivers/scsi/bfa/include/protocol/fcp.h186
-rw-r--r--drivers/scsi/bfa/include/protocol/fdmi.h163
-rw-r--r--drivers/scsi/bfa/include/protocol/pcifw.h75
-rw-r--r--drivers/scsi/bfa/include/protocol/scsi.h1648
-rw-r--r--drivers/scsi/bfa/include/protocol/types.h42
-rw-r--r--drivers/scsi/bfa/loop.c422
-rw-r--r--drivers/scsi/bfa/lport_api.c291
-rw-r--r--drivers/scsi/bfa/lport_priv.h82
-rw-r--r--drivers/scsi/bfa/ms.c759
-rw-r--r--drivers/scsi/bfa/n2n.c105
-rw-r--r--drivers/scsi/bfa/ns.c1243
-rw-r--r--drivers/scsi/bfa/plog.c184
-rw-r--r--drivers/scsi/bfa/rport.c2618
-rw-r--r--drivers/scsi/bfa/rport_api.c180
-rw-r--r--drivers/scsi/bfa/rport_ftrs.c375
-rw-r--r--drivers/scsi/bfa/scn.c482
-rw-r--r--drivers/scsi/bfa/vfapi.c292
-rw-r--r--drivers/scsi/bfa/vport.c891
197 files changed, 49182 insertions, 0 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 82bb3b2d207a..a8ea01b07868 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1827,6 +1827,16 @@ config SCSI_SRP
1827 To compile this driver as a module, choose M here: the 1827 To compile this driver as a module, choose M here: the
1828 module will be called libsrp. 1828 module will be called libsrp.
1829 1829
1830config SCSI_BFA_FC
1831 tristate "Brocade BFA Fibre Channel Support"
1832 depends on PCI && SCSI
1833 select SCSI_FC_ATTRS
1834 help
1835 This bfa driver supports all Brocade PCIe FC/FCOE host adapters.
1836
1837 To compile this driver as a module, choose M here. The module will
1838 be called bfa.
1839
1830endif # SCSI_LOWLEVEL 1840endif # SCSI_LOWLEVEL
1831 1841
1832source "drivers/scsi/pcmcia/Kconfig" 1842source "drivers/scsi/pcmcia/Kconfig"
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 61a94af3cee7..316f0a1a7986 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o
86obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/ 86obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/
87obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx/ 87obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx/
88obj-$(CONFIG_SCSI_LPFC) += lpfc/ 88obj-$(CONFIG_SCSI_LPFC) += lpfc/
89obj-$(CONFIG_SCSI_BFA_FC) += bfa/
89obj-$(CONFIG_SCSI_PAS16) += pas16.o 90obj-$(CONFIG_SCSI_PAS16) += pas16.o
90obj-$(CONFIG_SCSI_T128) += t128.o 91obj-$(CONFIG_SCSI_T128) += t128.o
91obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o 92obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o
diff --git a/drivers/scsi/bfa/Makefile b/drivers/scsi/bfa/Makefile
new file mode 100644
index 000000000000..1d6009490d1c
--- /dev/null
+++ b/drivers/scsi/bfa/Makefile
@@ -0,0 +1,15 @@
1obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
2
3bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o
4
5bfa-y += bfa_core.o bfa_ioc.o bfa_iocfc.o bfa_fcxp.o bfa_lps.o
6bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
7bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o
8bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o
9bfa-y += bfa_csdebug.o bfa_sm.o plog.o
10
11bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o
12bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o
13bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o
14
15ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna
diff --git a/drivers/scsi/bfa/bfa_callback_priv.h b/drivers/scsi/bfa/bfa_callback_priv.h
new file mode 100644
index 000000000000..1e3265c9f7d4
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_callback_priv.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_CALLBACK_PRIV_H__
19#define __BFA_CALLBACK_PRIV_H__
20
21#include <cs/bfa_q.h>
22
23typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete);
24
25/**
26 * Generic BFA callback element.
27 */
28struct bfa_cb_qe_s {
29 struct list_head qe;
30 bfa_cb_cbfn_t cbfn;
31 bfa_boolean_t once;
32 u32 rsvd;
33 void *cbarg;
34};
35
36#define bfa_cb_queue(__bfa, __hcb_qe, __cbfn, __cbarg) do { \
37 (__hcb_qe)->cbfn = (__cbfn); \
38 (__hcb_qe)->cbarg = (__cbarg); \
39 list_add_tail(&(__hcb_qe)->qe, &(__bfa)->comp_q); \
40} while (0)
41
42#define bfa_cb_dequeue(__hcb_qe) list_del(&(__hcb_qe)->qe)
43
44#define bfa_cb_queue_once(__bfa, __hcb_qe, __cbfn, __cbarg) do { \
45 (__hcb_qe)->cbfn = (__cbfn); \
46 (__hcb_qe)->cbarg = (__cbarg); \
47 if (!(__hcb_qe)->once) { \
48 list_add_tail((__hcb_qe), &(__bfa)->comp_q); \
49 (__hcb_qe)->once = BFA_TRUE; \
50 } \
51} while (0)
52
53#define bfa_cb_queue_done(__hcb_qe) do { \
54 (__hcb_qe)->once = BFA_FALSE; \
55} while (0)
56
57#endif /* __BFA_CALLBACK_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_cb_ioim_macros.h b/drivers/scsi/bfa/bfa_cb_ioim_macros.h
new file mode 100644
index 000000000000..0050c838c358
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_cb_ioim_macros.h
@@ -0,0 +1,205 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_cb_ioim_macros.h BFA IOIM driver interface macros.
20 */
21
22#ifndef __BFA_HCB_IOIM_MACROS_H__
23#define __BFA_HCB_IOIM_MACROS_H__
24
25#include <bfa_os_inc.h>
26/*
27 * #include <linux/dma-mapping.h>
28 *
29 * #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> #include
30 * <scsi/scsi_device.h> #include <scsi/scsi_host.h>
31 */
32#include "bfad_im_compat.h"
33
34/*
35 * task attribute values in FCP-2 FCP_CMND IU
36 */
37#define SIMPLE_Q 0
38#define HEAD_OF_Q 1
39#define ORDERED_Q 2
40#define ACA_Q 4
41#define UNTAGGED 5
42
43static inline lun_t
44bfad_int_to_lun(u32 luno)
45{
46 union {
47 u16 scsi_lun[4];
48 lun_t bfa_lun;
49 } lun;
50
51 lun.bfa_lun = 0;
52 lun.scsi_lun[0] = bfa_os_htons(luno);
53
54 return (lun.bfa_lun);
55}
56
57/**
58 * Get LUN for the I/O request
59 */
60#define bfa_cb_ioim_get_lun(__dio) \
61 bfad_int_to_lun(((struct scsi_cmnd *)__dio)->device->lun)
62
63/**
64 * Get CDB for the I/O request
65 */
66static inline u8 *
67bfa_cb_ioim_get_cdb(struct bfad_ioim_s *dio)
68{
69 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
70
71 return ((u8 *) cmnd->cmnd);
72}
73
74/**
75 * Get I/O direction (read/write) for the I/O request
76 */
77static inline enum fcp_iodir
78bfa_cb_ioim_get_iodir(struct bfad_ioim_s *dio)
79{
80 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
81 enum dma_data_direction dmadir;
82
83 dmadir = cmnd->sc_data_direction;
84 if (dmadir == DMA_TO_DEVICE)
85 return FCP_IODIR_WRITE;
86 else if (dmadir == DMA_FROM_DEVICE)
87 return FCP_IODIR_READ;
88 else
89 return FCP_IODIR_NONE;
90}
91
92/**
93 * Get IO size in bytes for the I/O request
94 */
95static inline u32
96bfa_cb_ioim_get_size(struct bfad_ioim_s *dio)
97{
98 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
99
100 return (scsi_bufflen(cmnd));
101}
102
103/**
104 * Get timeout for the I/O request
105 */
106static inline u8
107bfa_cb_ioim_get_timeout(struct bfad_ioim_s *dio)
108{
109 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
110 /*
111 * TBD: need a timeout for scsi passthru
112 */
113 if (cmnd->device->host == NULL)
114 return 4;
115
116 return 0;
117}
118
119/**
120 * Get SG element for the I/O request given the SG element index
121 */
122static inline union bfi_addr_u
123bfa_cb_ioim_get_sgaddr(struct bfad_ioim_s *dio, int sgeid)
124{
125 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
126 struct scatterlist *sge;
127 u64 addr;
128
129 sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid;
130 addr = (u64) sg_dma_address(sge);
131
132 return (*(union bfi_addr_u *) &addr);
133}
134
135static inline u32
136bfa_cb_ioim_get_sglen(struct bfad_ioim_s *dio, int sgeid)
137{
138 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
139 struct scatterlist *sge;
140 u32 len;
141
142 sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid;
143 len = sg_dma_len(sge);
144
145 return len;
146}
147
148/**
149 * Get Command Reference Number for the I/O request. 0 if none.
150 */
151static inline u8
152bfa_cb_ioim_get_crn(struct bfad_ioim_s *dio)
153{
154 return 0;
155}
156
157/**
158 * Get SAM-3 priority for the I/O request. 0 is default.
159 */
160static inline u8
161bfa_cb_ioim_get_priority(struct bfad_ioim_s *dio)
162{
163 return 0;
164}
165
166/**
167 * Get task attributes for the I/O request. Default is FCP_TASK_ATTR_SIMPLE(0).
168 */
169static inline u8
170bfa_cb_ioim_get_taskattr(struct bfad_ioim_s *dio)
171{
172 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
173 u8 task_attr = UNTAGGED;
174
175 if (cmnd->device->tagged_supported) {
176 switch (cmnd->tag) {
177 case HEAD_OF_QUEUE_TAG:
178 task_attr = HEAD_OF_Q;
179 break;
180 case ORDERED_QUEUE_TAG:
181 task_attr = ORDERED_Q;
182 break;
183 default:
184 task_attr = SIMPLE_Q;
185 break;
186 }
187 }
188
189 return task_attr;
190}
191
192/**
193 * Get CDB length in bytes for the I/O request. Default is FCP_CMND_CDB_LEN(16).
194 */
195static inline u8
196bfa_cb_ioim_get_cdblen(struct bfad_ioim_s *dio)
197{
198 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
199
200 return (cmnd->cmd_len);
201}
202
203
204
205#endif /* __BFA_HCB_IOIM_MACROS_H__ */
diff --git a/drivers/scsi/bfa/bfa_cee.c b/drivers/scsi/bfa/bfa_cee.c
new file mode 100644
index 000000000000..7a959c34e789
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_cee.c
@@ -0,0 +1,492 @@
1/*
2 * Copyright (c) 2005-2009 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 <defs/bfa_defs_cee.h>
19#include <cs/bfa_trc.h>
20#include <cs/bfa_log.h>
21#include <cs/bfa_debug.h>
22#include <cee/bfa_cee.h>
23#include <bfi/bfi_cee.h>
24#include <bfi/bfi.h>
25#include <bfa_ioc.h>
26#include <cna/bfa_cna_trcmod.h>
27
28BFA_TRC_FILE(CNA, CEE);
29
30#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
31#define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc)
32
33static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s *lldp_cfg);
34static void bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s
35 *dcbcx_stats);
36static void bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s
37 *lldp_stats);
38static void bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s *cfg_stats);
39static void bfa_cee_format_cee_cfg(void *buffer);
40static void bfa_cee_format_cee_stats(void *buffer);
41
42static void
43bfa_cee_format_cee_stats(void *buffer)
44{
45 struct bfa_cee_stats_s *cee_stats = buffer;
46 bfa_cee_format_dcbcx_stats(&cee_stats->dcbx_stats);
47 bfa_cee_format_lldp_stats(&cee_stats->lldp_stats);
48 bfa_cee_format_cfg_stats(&cee_stats->cfg_stats);
49}
50
51static void
52bfa_cee_format_cee_cfg(void *buffer)
53{
54 struct bfa_cee_attr_s *cee_cfg = buffer;
55 bfa_cee_format_lldp_cfg(&cee_cfg->lldp_remote);
56}
57
58static void
59bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s *dcbcx_stats)
60{
61 dcbcx_stats->subtlvs_unrecognized =
62 bfa_os_ntohl(dcbcx_stats->subtlvs_unrecognized);
63 dcbcx_stats->negotiation_failed =
64 bfa_os_ntohl(dcbcx_stats->negotiation_failed);
65 dcbcx_stats->remote_cfg_changed =
66 bfa_os_ntohl(dcbcx_stats->remote_cfg_changed);
67 dcbcx_stats->tlvs_received = bfa_os_ntohl(dcbcx_stats->tlvs_received);
68 dcbcx_stats->tlvs_invalid = bfa_os_ntohl(dcbcx_stats->tlvs_invalid);
69 dcbcx_stats->seqno = bfa_os_ntohl(dcbcx_stats->seqno);
70 dcbcx_stats->ackno = bfa_os_ntohl(dcbcx_stats->ackno);
71 dcbcx_stats->recvd_seqno = bfa_os_ntohl(dcbcx_stats->recvd_seqno);
72 dcbcx_stats->recvd_ackno = bfa_os_ntohl(dcbcx_stats->recvd_ackno);
73}
74
75static void
76bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s *lldp_stats)
77{
78 lldp_stats->frames_transmitted =
79 bfa_os_ntohl(lldp_stats->frames_transmitted);
80 lldp_stats->frames_aged_out = bfa_os_ntohl(lldp_stats->frames_aged_out);
81 lldp_stats->frames_discarded =
82 bfa_os_ntohl(lldp_stats->frames_discarded);
83 lldp_stats->frames_in_error = bfa_os_ntohl(lldp_stats->frames_in_error);
84 lldp_stats->frames_rcvd = bfa_os_ntohl(lldp_stats->frames_rcvd);
85 lldp_stats->tlvs_discarded = bfa_os_ntohl(lldp_stats->tlvs_discarded);
86 lldp_stats->tlvs_unrecognized =
87 bfa_os_ntohl(lldp_stats->tlvs_unrecognized);
88}
89
90static void
91bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s *cfg_stats)
92{
93 cfg_stats->cee_status_down = bfa_os_ntohl(cfg_stats->cee_status_down);
94 cfg_stats->cee_status_up = bfa_os_ntohl(cfg_stats->cee_status_up);
95 cfg_stats->cee_hw_cfg_changed =
96 bfa_os_ntohl(cfg_stats->cee_hw_cfg_changed);
97 cfg_stats->recvd_invalid_cfg =
98 bfa_os_ntohl(cfg_stats->recvd_invalid_cfg);
99}
100
101static void
102bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s *lldp_cfg)
103{
104 lldp_cfg->time_to_interval = bfa_os_ntohs(lldp_cfg->time_to_interval);
105 lldp_cfg->enabled_system_cap =
106 bfa_os_ntohs(lldp_cfg->enabled_system_cap);
107}
108
109/**
110 * bfa_cee_attr_meminfo()
111 *
112 *
113 * @param[in] void
114 *
115 * @return Size of DMA region
116 */
117static u32
118bfa_cee_attr_meminfo(void)
119{
120 return BFA_ROUNDUP(sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ);
121}
122
123/**
124 * bfa_cee_stats_meminfo()
125 *
126 *
127 * @param[in] void
128 *
129 * @return Size of DMA region
130 */
131static u32
132bfa_cee_stats_meminfo(void)
133{
134 return BFA_ROUNDUP(sizeof(struct bfa_cee_stats_s), BFA_DMA_ALIGN_SZ);
135}
136
137/**
138 * bfa_cee_get_attr_isr()
139 *
140 *
141 * @param[in] cee - Pointer to the CEE module
142 * status - Return status from the f/w
143 *
144 * @return void
145 */
146static void
147bfa_cee_get_attr_isr(struct bfa_cee_s *cee, bfa_status_t status)
148{
149 cee->get_attr_status = status;
150 bfa_trc(cee, 0);
151 if (status == BFA_STATUS_OK) {
152 bfa_trc(cee, 0);
153 /*
154 * The requested data has been copied to the DMA area, *process
155 * it.
156 */
157 memcpy(cee->attr, cee->attr_dma.kva,
158 sizeof(struct bfa_cee_attr_s));
159 bfa_cee_format_cee_cfg(cee->attr);
160 }
161 cee->get_attr_pending = BFA_FALSE;
162 if (cee->cbfn.get_attr_cbfn) {
163 bfa_trc(cee, 0);
164 cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status);
165 }
166 bfa_trc(cee, 0);
167}
168
169/**
170 * bfa_cee_get_attr_isr()
171 *
172 *
173 * @param[in] cee - Pointer to the CEE module
174 * status - Return status from the f/w
175 *
176 * @return void
177 */
178static void
179bfa_cee_get_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
180{
181 cee->get_stats_status = status;
182 bfa_trc(cee, 0);
183 if (status == BFA_STATUS_OK) {
184 bfa_trc(cee, 0);
185 /*
186 * The requested data has been copied to the DMA area, process
187 * it.
188 */
189 memcpy(cee->stats, cee->stats_dma.kva,
190 sizeof(struct bfa_cee_stats_s));
191 bfa_cee_format_cee_stats(cee->stats);
192 }
193 cee->get_stats_pending = BFA_FALSE;
194 bfa_trc(cee, 0);
195 if (cee->cbfn.get_stats_cbfn) {
196 bfa_trc(cee, 0);
197 cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status);
198 }
199 bfa_trc(cee, 0);
200}
201
202/**
203 * bfa_cee_get_attr_isr()
204 *
205 *
206 * @param[in] cee - Pointer to the CEE module
207 * status - Return status from the f/w
208 *
209 * @return void
210 */
211static void
212bfa_cee_reset_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
213{
214 cee->reset_stats_status = status;
215 cee->reset_stats_pending = BFA_FALSE;
216 if (cee->cbfn.reset_stats_cbfn)
217 cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status);
218}
219
220/**
221 * bfa_cee_meminfo()
222 *
223 *
224 * @param[in] void
225 *
226 * @return Size of DMA region
227 */
228u32
229bfa_cee_meminfo(void)
230{
231 return (bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo());
232}
233
234/**
235 * bfa_cee_mem_claim()
236 *
237 *
238 * @param[in] cee CEE module pointer
239 * dma_kva Kernel Virtual Address of CEE DMA Memory
240 * dma_pa Physical Address of CEE DMA Memory
241 *
242 * @return void
243 */
244void
245bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva, u64 dma_pa)
246{
247 cee->attr_dma.kva = dma_kva;
248 cee->attr_dma.pa = dma_pa;
249 cee->stats_dma.kva = dma_kva + bfa_cee_attr_meminfo();
250 cee->stats_dma.pa = dma_pa + bfa_cee_attr_meminfo();
251 cee->attr = (struct bfa_cee_attr_s *)dma_kva;
252 cee->stats =
253 (struct bfa_cee_stats_s *)(dma_kva + bfa_cee_attr_meminfo());
254}
255
256/**
257 * bfa_cee_get_attr()
258 *
259 * Send the request to the f/w to fetch CEE attributes.
260 *
261 * @param[in] Pointer to the CEE module data structure.
262 *
263 * @return Status
264 */
265
266bfa_status_t
267bfa_cee_get_attr(struct bfa_cee_s *cee, struct bfa_cee_attr_s *attr,
268 bfa_cee_get_attr_cbfn_t cbfn, void *cbarg)
269{
270 struct bfi_cee_get_req_s *cmd;
271
272 bfa_assert((cee != NULL) && (cee->ioc != NULL));
273 bfa_trc(cee, 0);
274 if (!bfa_ioc_is_operational(cee->ioc)) {
275 bfa_trc(cee, 0);
276 return BFA_STATUS_IOC_FAILURE;
277 }
278 if (cee->get_attr_pending == BFA_TRUE) {
279 bfa_trc(cee, 0);
280 return BFA_STATUS_DEVBUSY;
281 }
282 cee->get_attr_pending = BFA_TRUE;
283 cmd = (struct bfi_cee_get_req_s *)cee->get_cfg_mb.msg;
284 cee->attr = attr;
285 cee->cbfn.get_attr_cbfn = cbfn;
286 cee->cbfn.get_attr_cbarg = cbarg;
287 bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ,
288 bfa_ioc_portid(cee->ioc));
289 bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa);
290 bfa_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb);
291 bfa_trc(cee, 0);
292
293 return BFA_STATUS_OK;
294}
295
296/**
297 * bfa_cee_get_stats()
298 *
299 * Send the request to the f/w to fetch CEE statistics.
300 *
301 * @param[in] Pointer to the CEE module data structure.
302 *
303 * @return Status
304 */
305
306bfa_status_t
307bfa_cee_get_stats(struct bfa_cee_s *cee, struct bfa_cee_stats_s *stats,
308 bfa_cee_get_stats_cbfn_t cbfn, void *cbarg)
309{
310 struct bfi_cee_get_req_s *cmd;
311
312 bfa_assert((cee != NULL) && (cee->ioc != NULL));
313
314 if (!bfa_ioc_is_operational(cee->ioc)) {
315 bfa_trc(cee, 0);
316 return BFA_STATUS_IOC_FAILURE;
317 }
318 if (cee->get_stats_pending == BFA_TRUE) {
319 bfa_trc(cee, 0);
320 return BFA_STATUS_DEVBUSY;
321 }
322 cee->get_stats_pending = BFA_TRUE;
323 cmd = (struct bfi_cee_get_req_s *)cee->get_stats_mb.msg;
324 cee->stats = stats;
325 cee->cbfn.get_stats_cbfn = cbfn;
326 cee->cbfn.get_stats_cbarg = cbarg;
327 bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_STATS_REQ,
328 bfa_ioc_portid(cee->ioc));
329 bfa_dma_be_addr_set(cmd->dma_addr, cee->stats_dma.pa);
330 bfa_ioc_mbox_queue(cee->ioc, &cee->get_stats_mb);
331 bfa_trc(cee, 0);
332
333 return BFA_STATUS_OK;
334}
335
336/**
337 * bfa_cee_reset_stats()
338 *
339 *
340 * @param[in] Pointer to the CEE module data structure.
341 *
342 * @return Status
343 */
344
345bfa_status_t
346bfa_cee_reset_stats(struct bfa_cee_s *cee, bfa_cee_reset_stats_cbfn_t cbfn,
347 void *cbarg)
348{
349 struct bfi_cee_reset_stats_s *cmd;
350
351 bfa_assert((cee != NULL) && (cee->ioc != NULL));
352 if (!bfa_ioc_is_operational(cee->ioc)) {
353 bfa_trc(cee, 0);
354 return BFA_STATUS_IOC_FAILURE;
355 }
356 if (cee->reset_stats_pending == BFA_TRUE) {
357 bfa_trc(cee, 0);
358 return BFA_STATUS_DEVBUSY;
359 }
360 cee->reset_stats_pending = BFA_TRUE;
361 cmd = (struct bfi_cee_reset_stats_s *)cee->reset_stats_mb.msg;
362 cee->cbfn.reset_stats_cbfn = cbfn;
363 cee->cbfn.reset_stats_cbarg = cbarg;
364 bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_RESET_STATS,
365 bfa_ioc_portid(cee->ioc));
366 bfa_ioc_mbox_queue(cee->ioc, &cee->reset_stats_mb);
367 bfa_trc(cee, 0);
368 return BFA_STATUS_OK;
369}
370
371/**
372 * bfa_cee_isrs()
373 *
374 *
375 * @param[in] Pointer to the CEE module data structure.
376 *
377 * @return void
378 */
379
380void
381bfa_cee_isr(void *cbarg, struct bfi_mbmsg_s *m)
382{
383 union bfi_cee_i2h_msg_u *msg;
384 struct bfi_cee_get_rsp_s *get_rsp;
385 struct bfa_cee_s *cee = (struct bfa_cee_s *)cbarg;
386 msg = (union bfi_cee_i2h_msg_u *)m;
387 get_rsp = (struct bfi_cee_get_rsp_s *)m;
388 bfa_trc(cee, msg->mh.msg_id);
389 switch (msg->mh.msg_id) {
390 case BFI_CEE_I2H_GET_CFG_RSP:
391 bfa_trc(cee, get_rsp->cmd_status);
392 bfa_cee_get_attr_isr(cee, get_rsp->cmd_status);
393 break;
394 case BFI_CEE_I2H_GET_STATS_RSP:
395 bfa_cee_get_stats_isr(cee, get_rsp->cmd_status);
396 break;
397 case BFI_CEE_I2H_RESET_STATS_RSP:
398 bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status);
399 break;
400 default:
401 bfa_assert(0);
402 }
403}
404
405/**
406 * bfa_cee_hbfail()
407 *
408 *
409 * @param[in] Pointer to the CEE module data structure.
410 *
411 * @return void
412 */
413
414void
415bfa_cee_hbfail(void *arg)
416{
417 struct bfa_cee_s *cee;
418 cee = (struct bfa_cee_s *)arg;
419
420 if (cee->get_attr_pending == BFA_TRUE) {
421 cee->get_attr_status = BFA_STATUS_FAILED;
422 cee->get_attr_pending = BFA_FALSE;
423 if (cee->cbfn.get_attr_cbfn) {
424 cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg,
425 BFA_STATUS_FAILED);
426 }
427 }
428 if (cee->get_stats_pending == BFA_TRUE) {
429 cee->get_stats_status = BFA_STATUS_FAILED;
430 cee->get_stats_pending = BFA_FALSE;
431 if (cee->cbfn.get_stats_cbfn) {
432 cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg,
433 BFA_STATUS_FAILED);
434 }
435 }
436 if (cee->reset_stats_pending == BFA_TRUE) {
437 cee->reset_stats_status = BFA_STATUS_FAILED;
438 cee->reset_stats_pending = BFA_FALSE;
439 if (cee->cbfn.reset_stats_cbfn) {
440 cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg,
441 BFA_STATUS_FAILED);
442 }
443 }
444}
445
446/**
447 * bfa_cee_attach()
448 *
449 *
450 * @param[in] cee - Pointer to the CEE module data structure
451 * ioc - Pointer to the ioc module data structure
452 * dev - Pointer to the device driver module data structure
453 * The device driver specific mbox ISR functions have
454 * this pointer as one of the parameters.
455 * trcmod -
456 * logmod -
457 *
458 * @return void
459 */
460void
461bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc, void *dev,
462 struct bfa_trc_mod_s *trcmod, struct bfa_log_mod_s *logmod)
463{
464 bfa_assert(cee != NULL);
465 cee->dev = dev;
466 cee->trcmod = trcmod;
467 cee->logmod = logmod;
468 cee->ioc = ioc;
469
470 bfa_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
471 bfa_ioc_hbfail_init(&cee->hbfail, bfa_cee_hbfail, cee);
472 bfa_ioc_hbfail_register(cee->ioc, &cee->hbfail);
473 bfa_trc(cee, 0);
474}
475
476/**
477 * bfa_cee_detach()
478 *
479 *
480 * @param[in] cee - Pointer to the CEE module data structure
481 *
482 * @return void
483 */
484void
485bfa_cee_detach(struct bfa_cee_s *cee)
486{
487 /*
488 * For now, just check if there is some ioctl pending and mark that as
489 * failed?
490 */
491 /* bfa_cee_hbfail(cee); */
492}
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
new file mode 100644
index 000000000000..44e2d1155c51
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -0,0 +1,402 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19#include <defs/bfa_defs_pci.h>
20#include <cs/bfa_debug.h>
21#include <bfa_iocfc.h>
22
23#define DEF_CFG_NUM_FABRICS 1
24#define DEF_CFG_NUM_LPORTS 256
25#define DEF_CFG_NUM_CQS 4
26#define DEF_CFG_NUM_IOIM_REQS (BFA_IOIM_MAX)
27#define DEF_CFG_NUM_TSKIM_REQS 128
28#define DEF_CFG_NUM_FCXP_REQS 64
29#define DEF_CFG_NUM_UF_BUFS 64
30#define DEF_CFG_NUM_RPORTS 1024
31#define DEF_CFG_NUM_ITNIMS (DEF_CFG_NUM_RPORTS)
32#define DEF_CFG_NUM_TINS 256
33
34#define DEF_CFG_NUM_SGPGS 2048
35#define DEF_CFG_NUM_REQQ_ELEMS 256
36#define DEF_CFG_NUM_RSPQ_ELEMS 64
37#define DEF_CFG_NUM_SBOOT_TGTS 16
38#define DEF_CFG_NUM_SBOOT_LUNS 16
39
40/**
41 * Use this function query the memory requirement of the BFA library.
42 * This function needs to be called before bfa_attach() to get the
43 * memory required of the BFA layer for a given driver configuration.
44 *
45 * This call will fail, if the cap is out of range compared to pre-defined
46 * values within the BFA library
47 *
48 * @param[in] cfg - pointer to bfa_ioc_cfg_t. Driver layer should indicate
49 * its configuration in this structure.
50 * The default values for struct bfa_iocfc_cfg_s can be
51 * fetched using bfa_cfg_get_default() API.
52 *
53 * If cap's boundary check fails, the library will use
54 * the default bfa_cap_t values (and log a warning msg).
55 *
56 * @param[out] meminfo - pointer to bfa_meminfo_t. This content
57 * indicates the memory type (see bfa_mem_type_t) and
58 * amount of memory required.
59 *
60 * Driver should allocate the memory, populate the
61 * starting address for each block and provide the same
62 * structure as input parameter to bfa_attach() call.
63 *
64 * @return void
65 *
66 * Special Considerations: @note
67 */
68void
69bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo)
70{
71 int i;
72 u32 km_len = 0, dm_len = 0;
73
74 bfa_assert((cfg != NULL) && (meminfo != NULL));
75
76 bfa_os_memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s));
77 meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_type =
78 BFA_MEM_TYPE_KVA;
79 meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_type =
80 BFA_MEM_TYPE_DMA;
81
82 bfa_iocfc_meminfo(cfg, &km_len, &dm_len);
83
84 for (i = 0; hal_mods[i]; i++)
85 hal_mods[i]->meminfo(cfg, &km_len, &dm_len);
86
87
88 meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_len = km_len;
89 meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_len = dm_len;
90}
91
92/**
93 * Use this function to do attach the driver instance with the BFA
94 * library. This function will not trigger any HW initialization
95 * process (which will be done in bfa_init() call)
96 *
97 * This call will fail, if the cap is out of range compared to
98 * pre-defined values within the BFA library
99 *
100 * @param[out] bfa Pointer to bfa_t.
101 * @param[in] bfad Opaque handle back to the driver's IOC structure
102 * @param[in] cfg Pointer to bfa_ioc_cfg_t. Should be same structure
103 * that was used in bfa_cfg_get_meminfo().
104 * @param[in] meminfo Pointer to bfa_meminfo_t. The driver should
105 * use the bfa_cfg_get_meminfo() call to
106 * find the memory blocks required, allocate the
107 * required memory and provide the starting addresses.
108 * @param[in] pcidev pointer to struct bfa_pcidev_s
109 *
110 * @return
111 * void
112 *
113 * Special Considerations:
114 *
115 * @note
116 *
117 */
118void
119bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
120 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
121{
122 int i;
123 struct bfa_mem_elem_s *melem;
124
125 bfa->fcs = BFA_FALSE;
126
127 bfa_assert((cfg != NULL) && (meminfo != NULL));
128
129 /**
130 * initialize all memory pointers for iterative allocation
131 */
132 for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
133 melem = meminfo->meminfo + i;
134 melem->kva_curp = melem->kva;
135 melem->dma_curp = melem->dma;
136 }
137
138 bfa_iocfc_attach(bfa, bfad, cfg, meminfo, pcidev);
139
140 for (i = 0; hal_mods[i]; i++)
141 hal_mods[i]->attach(bfa, bfad, cfg, meminfo, pcidev);
142
143}
144
145/**
146 * Use this function to delete a BFA IOC. IOC should be stopped (by
147 * calling bfa_stop()) before this function call.
148 *
149 * @param[in] bfa - pointer to bfa_t.
150 *
151 * @return
152 * void
153 *
154 * Special Considerations:
155 *
156 * @note
157 */
158void
159bfa_detach(struct bfa_s *bfa)
160{
161 int i;
162
163 for (i = 0; hal_mods[i]; i++)
164 hal_mods[i]->detach(bfa);
165
166 bfa_iocfc_detach(bfa);
167}
168
169
170void
171bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod)
172{
173 bfa->trcmod = trcmod;
174}
175
176
177void
178bfa_init_log(struct bfa_s *bfa, struct bfa_log_mod_s *logmod)
179{
180 bfa->logm = logmod;
181}
182
183
184void
185bfa_init_aen(struct bfa_s *bfa, struct bfa_aen_s *aen)
186{
187 bfa->aen = aen;
188}
189
190void
191bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog)
192{
193 bfa->plog = plog;
194}
195
196/**
197 * Initialize IOC.
198 *
199 * This function will return immediately, when the IOC initialization is
200 * completed, the bfa_cb_init() will be called.
201 *
202 * @param[in] bfa instance
203 *
204 * @return void
205 *
206 * Special Considerations:
207 *
208 * @note
209 * When this function returns, the driver should register the interrupt service
210 * routine(s) and enable the device interrupts. If this is not done,
211 * bfa_cb_init() will never get called
212 */
213void
214bfa_init(struct bfa_s *bfa)
215{
216 bfa_iocfc_init(bfa);
217}
218
219/**
220 * Use this function initiate the IOC configuration setup. This function
221 * will return immediately.
222 *
223 * @param[in] bfa instance
224 *
225 * @return None
226 */
227void
228bfa_start(struct bfa_s *bfa)
229{
230 bfa_iocfc_start(bfa);
231}
232
233/**
234 * Use this function quiese the IOC. This function will return immediately,
235 * when the IOC is actually stopped, the bfa_cb_stop() will be called.
236 *
237 * @param[in] bfa - pointer to bfa_t.
238 *
239 * @return None
240 *
241 * Special Considerations:
242 * bfa_cb_stop() could be called before or after bfa_stop() returns.
243 *
244 * @note
245 * In case of any failure, we could handle it automatically by doing a
246 * reset and then succeed the bfa_stop() call.
247 */
248void
249bfa_stop(struct bfa_s *bfa)
250{
251 bfa_iocfc_stop(bfa);
252}
253
254void
255bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q)
256{
257 INIT_LIST_HEAD(comp_q);
258 list_splice_tail_init(&bfa->comp_q, comp_q);
259}
260
261void
262bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q)
263{
264 struct list_head *qe;
265 struct list_head *qen;
266 struct bfa_cb_qe_s *hcb_qe;
267
268 list_for_each_safe(qe, qen, comp_q) {
269 hcb_qe = (struct bfa_cb_qe_s *) qe;
270 hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);
271 }
272}
273
274void
275bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q)
276{
277 struct list_head *qe;
278 struct bfa_cb_qe_s *hcb_qe;
279
280 while (!list_empty(comp_q)) {
281 bfa_q_deq(comp_q, &qe);
282 hcb_qe = (struct bfa_cb_qe_s *) qe;
283 hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE);
284 }
285}
286
287void
288bfa_attach_fcs(struct bfa_s *bfa)
289{
290 bfa->fcs = BFA_TRUE;
291}
292
293/**
294 * Periodic timer heart beat from driver
295 */
296void
297bfa_timer_tick(struct bfa_s *bfa)
298{
299 bfa_timer_beat(&bfa->timer_mod);
300}
301
302#ifndef BFA_BIOS_BUILD
303/**
304 * Return the list of PCI vendor/device id lists supported by this
305 * BFA instance.
306 */
307void
308bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids)
309{
310 static struct bfa_pciid_s __pciids[] = {
311 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P},
312 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P},
313 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT},
314 };
315
316 *npciids = sizeof(__pciids) / sizeof(__pciids[0]);
317 *pciids = __pciids;
318}
319
320/**
321 * Use this function query the default struct bfa_iocfc_cfg_s value (compiled
322 * into BFA layer). The OS driver can then turn back and overwrite entries that
323 * have been configured by the user.
324 *
325 * @param[in] cfg - pointer to bfa_ioc_cfg_t
326 *
327 * @return
328 * void
329 *
330 * Special Considerations:
331 * note
332 */
333void
334bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg)
335{
336 cfg->fwcfg.num_fabrics = DEF_CFG_NUM_FABRICS;
337 cfg->fwcfg.num_lports = DEF_CFG_NUM_LPORTS;
338 cfg->fwcfg.num_rports = DEF_CFG_NUM_RPORTS;
339 cfg->fwcfg.num_ioim_reqs = DEF_CFG_NUM_IOIM_REQS;
340 cfg->fwcfg.num_tskim_reqs = DEF_CFG_NUM_TSKIM_REQS;
341 cfg->fwcfg.num_fcxp_reqs = DEF_CFG_NUM_FCXP_REQS;
342 cfg->fwcfg.num_uf_bufs = DEF_CFG_NUM_UF_BUFS;
343 cfg->fwcfg.num_cqs = DEF_CFG_NUM_CQS;
344
345 cfg->drvcfg.num_reqq_elems = DEF_CFG_NUM_REQQ_ELEMS;
346 cfg->drvcfg.num_rspq_elems = DEF_CFG_NUM_RSPQ_ELEMS;
347 cfg->drvcfg.num_sgpgs = DEF_CFG_NUM_SGPGS;
348 cfg->drvcfg.num_sboot_tgts = DEF_CFG_NUM_SBOOT_TGTS;
349 cfg->drvcfg.num_sboot_luns = DEF_CFG_NUM_SBOOT_LUNS;
350 cfg->drvcfg.path_tov = BFA_FCPIM_PATHTOV_DEF;
351 cfg->drvcfg.ioc_recover = BFA_FALSE;
352 cfg->drvcfg.delay_comp = BFA_FALSE;
353
354}
355
356void
357bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg)
358{
359 bfa_cfg_get_default(cfg);
360 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN;
361 cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN;
362 cfg->fwcfg.num_fcxp_reqs = BFA_FCXP_MIN;
363 cfg->fwcfg.num_uf_bufs = BFA_UF_MIN;
364 cfg->fwcfg.num_rports = BFA_RPORT_MIN;
365
366 cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN;
367 cfg->drvcfg.num_reqq_elems = BFA_REQQ_NELEMS_MIN;
368 cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN;
369 cfg->drvcfg.min_cfg = BFA_TRUE;
370}
371
372void
373bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr)
374{
375 bfa_ioc_get_attr(&bfa->ioc, ioc_attr);
376}
377
378/**
379 * Retrieve firmware trace information on IOC failure.
380 */
381bfa_status_t
382bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
383{
384 return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen);
385}
386
387/**
388 * Fetch firmware trace data.
389 *
390 * @param[in] bfa BFA instance
391 * @param[out] trcdata Firmware trace buffer
392 * @param[in,out] trclen Firmware trace buffer len
393 *
394 * @retval BFA_STATUS_OK Firmware trace is fetched.
395 * @retval BFA_STATUS_INPROGRESS Firmware trace fetch is in progress.
396 */
397bfa_status_t
398bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
399{
400 return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
401}
402#endif
diff --git a/drivers/scsi/bfa/bfa_csdebug.c b/drivers/scsi/bfa/bfa_csdebug.c
new file mode 100644
index 000000000000..1b71d349451a
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_csdebug.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 2005-2009 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 <cs/bfa_debug.h>
19#include <bfa_os_inc.h>
20#include <cs/bfa_q.h>
21#include <log/bfa_log_hal.h>
22
23/**
24 * cs_debug_api
25 */
26
27
28void
29bfa_panic(int line, char *file, char *panicstr)
30{
31 bfa_log(NULL, BFA_LOG_HAL_ASSERT, file, line, panicstr);
32 bfa_os_panic();
33}
34
35void
36bfa_sm_panic(struct bfa_log_mod_s *logm, int line, char *file, int event)
37{
38 bfa_log(logm, BFA_LOG_HAL_SM_ASSERT, file, line, event);
39 bfa_os_panic();
40}
41
42int
43bfa_q_is_on_q_func(struct list_head *q, struct list_head *qe)
44{
45 struct list_head *tqe;
46
47 tqe = bfa_q_next(q);
48 while (tqe != q) {
49 if (tqe == qe)
50 return (1);
51 tqe = bfa_q_next(tqe);
52 if (tqe == NULL)
53 break;
54 }
55 return (0);
56}
57
58
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c
new file mode 100644
index 000000000000..401babe3494e
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcpim.c
@@ -0,0 +1,175 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19#include <log/bfa_log_hal.h>
20
21BFA_TRC_FILE(HAL, FCPIM);
22BFA_MODULE(fcpim);
23
24/**
25 * hal_fcpim_mod BFA FCP Initiator Mode module
26 */
27
28/**
29 * Compute and return memory needed by FCP(im) module.
30 */
31static void
32bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
33 u32 *dm_len)
34{
35 bfa_itnim_meminfo(cfg, km_len, dm_len);
36
37 /**
38 * IO memory
39 */
40 if (cfg->fwcfg.num_ioim_reqs < BFA_IOIM_MIN)
41 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN;
42 else if (cfg->fwcfg.num_ioim_reqs > BFA_IOIM_MAX)
43 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MAX;
44
45 *km_len += cfg->fwcfg.num_ioim_reqs *
46 (sizeof(struct bfa_ioim_s) + sizeof(struct bfa_ioim_sp_s));
47
48 *dm_len += cfg->fwcfg.num_ioim_reqs * BFI_IOIM_SNSLEN;
49
50 /**
51 * task management command memory
52 */
53 if (cfg->fwcfg.num_tskim_reqs < BFA_TSKIM_MIN)
54 cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN;
55 *km_len += cfg->fwcfg.num_tskim_reqs * sizeof(struct bfa_tskim_s);
56}
57
58
59static void
60bfa_fcpim_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
61 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
62{
63 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
64
65 bfa_trc(bfa, cfg->drvcfg.path_tov);
66 bfa_trc(bfa, cfg->fwcfg.num_rports);
67 bfa_trc(bfa, cfg->fwcfg.num_ioim_reqs);
68 bfa_trc(bfa, cfg->fwcfg.num_tskim_reqs);
69
70 fcpim->bfa = bfa;
71 fcpim->num_itnims = cfg->fwcfg.num_rports;
72 fcpim->num_ioim_reqs = cfg->fwcfg.num_ioim_reqs;
73 fcpim->num_tskim_reqs = cfg->fwcfg.num_tskim_reqs;
74 fcpim->path_tov = cfg->drvcfg.path_tov;
75 fcpim->delay_comp = cfg->drvcfg.delay_comp;
76
77 bfa_itnim_attach(fcpim, meminfo);
78 bfa_tskim_attach(fcpim, meminfo);
79 bfa_ioim_attach(fcpim, meminfo);
80}
81
82static void
83bfa_fcpim_initdone(struct bfa_s *bfa)
84{
85}
86
87static void
88bfa_fcpim_detach(struct bfa_s *bfa)
89{
90 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
91
92 bfa_ioim_detach(fcpim);
93 bfa_tskim_detach(fcpim);
94}
95
96static void
97bfa_fcpim_start(struct bfa_s *bfa)
98{
99}
100
101static void
102bfa_fcpim_stop(struct bfa_s *bfa)
103{
104}
105
106static void
107bfa_fcpim_iocdisable(struct bfa_s *bfa)
108{
109 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
110 struct bfa_itnim_s *itnim;
111 struct list_head *qe, *qen;
112
113 list_for_each_safe(qe, qen, &fcpim->itnim_q) {
114 itnim = (struct bfa_itnim_s *) qe;
115 bfa_itnim_iocdisable(itnim);
116 }
117}
118
119void
120bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov)
121{
122 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
123
124 fcpim->path_tov = path_tov * 1000;
125 if (fcpim->path_tov > BFA_FCPIM_PATHTOV_MAX)
126 fcpim->path_tov = BFA_FCPIM_PATHTOV_MAX;
127}
128
129u16
130bfa_fcpim_path_tov_get(struct bfa_s *bfa)
131{
132 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
133
134 return (fcpim->path_tov / 1000);
135}
136
137bfa_status_t
138bfa_fcpim_get_modstats(struct bfa_s *bfa, struct bfa_fcpim_stats_s *modstats)
139{
140 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
141
142 *modstats = fcpim->stats;
143
144 return BFA_STATUS_OK;
145}
146
147bfa_status_t
148bfa_fcpim_clr_modstats(struct bfa_s *bfa)
149{
150 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
151
152 memset(&fcpim->stats, 0, sizeof(struct bfa_fcpim_stats_s));
153
154 return BFA_STATUS_OK;
155}
156
157void
158bfa_fcpim_qdepth_set(struct bfa_s *bfa, u16 q_depth)
159{
160 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
161
162 bfa_assert(q_depth <= BFA_IOCFC_QDEPTH_MAX);
163
164 fcpim->q_depth = q_depth;
165}
166
167u16
168bfa_fcpim_qdepth_get(struct bfa_s *bfa)
169{
170 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
171
172 return (fcpim->q_depth);
173}
174
175
diff --git a/drivers/scsi/bfa/bfa_fcpim_priv.h b/drivers/scsi/bfa/bfa_fcpim_priv.h
new file mode 100644
index 000000000000..153206cfb37a
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcpim_priv.h
@@ -0,0 +1,188 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_FCPIM_PRIV_H__
19#define __BFA_FCPIM_PRIV_H__
20
21#include <bfa_fcpim.h>
22#include <defs/bfa_defs_fcpim.h>
23#include <cs/bfa_wc.h>
24#include "bfa_sgpg_priv.h"
25
26#define BFA_ITNIM_MIN 32
27#define BFA_ITNIM_MAX 1024
28
29#define BFA_IOIM_MIN 8
30#define BFA_IOIM_MAX 2000
31
32#define BFA_TSKIM_MIN 4
33#define BFA_TSKIM_MAX 512
34#define BFA_FCPIM_PATHTOV_DEF (30 * 1000) /* in millisecs */
35#define BFA_FCPIM_PATHTOV_MAX (90 * 1000) /* in millisecs */
36
37#define bfa_fcpim_stats(__fcpim, __stats) \
38 (__fcpim)->stats.__stats ++
39
40struct bfa_fcpim_mod_s {
41 struct bfa_s *bfa;
42 struct bfa_itnim_s *itnim_arr;
43 struct bfa_ioim_s *ioim_arr;
44 struct bfa_ioim_sp_s *ioim_sp_arr;
45 struct bfa_tskim_s *tskim_arr;
46 struct bfa_dma_s snsbase;
47 int num_itnims;
48 int num_ioim_reqs;
49 int num_tskim_reqs;
50 u32 path_tov;
51 u16 q_depth;
52 u16 rsvd;
53 struct list_head itnim_q; /* queue of active itnim */
54 struct list_head ioim_free_q; /* free IO resources */
55 struct list_head ioim_resfree_q; /* IOs waiting for f/w */
56 struct list_head ioim_comp_q; /* IO global comp Q */
57 struct list_head tskim_free_q;
58 u32 ios_active; /* current active IOs */
59 u32 delay_comp;
60 struct bfa_fcpim_stats_s stats;
61};
62
63struct bfa_ioim_s;
64struct bfa_tskim_s;
65
66/**
67 * BFA IO (initiator mode)
68 */
69struct bfa_ioim_s {
70 struct list_head qe; /* queue elememt */
71 bfa_sm_t sm; /* BFA ioim state machine */
72 struct bfa_s *bfa; /* BFA module */
73 struct bfa_fcpim_mod_s *fcpim; /* parent fcpim module */
74 struct bfa_itnim_s *itnim; /* i-t-n nexus for this IO */
75 struct bfad_ioim_s *dio; /* driver IO handle */
76 u16 iotag; /* FWI IO tag */
77 u16 abort_tag; /* unqiue abort request tag */
78 u16 nsges; /* number of SG elements */
79 u16 nsgpgs; /* number of SG pages */
80 struct bfa_sgpg_s *sgpg; /* first SG page */
81 struct list_head sgpg_q; /* allocated SG pages */
82 struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
83 bfa_cb_cbfn_t io_cbfn; /* IO completion handler */
84 struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */
85};
86
87struct bfa_ioim_sp_s {
88 struct bfi_msg_s comp_rspmsg; /* IO comp f/w response */
89 u8 *snsinfo; /* sense info for this IO */
90 struct bfa_sgpg_wqe_s sgpg_wqe; /* waitq elem for sgpg */
91 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
92 bfa_boolean_t abort_explicit; /* aborted by OS */
93 struct bfa_tskim_s *tskim; /* Relevant TM cmd */
94};
95
96/**
97 * BFA Task management command (initiator mode)
98 */
99struct bfa_tskim_s {
100 struct list_head qe;
101 bfa_sm_t sm;
102 struct bfa_s *bfa; /* BFA module */
103 struct bfa_fcpim_mod_s *fcpim; /* parent fcpim module */
104 struct bfa_itnim_s *itnim; /* i-t-n nexus for this IO */
105 struct bfad_tskim_s *dtsk; /* driver task mgmt cmnd */
106 bfa_boolean_t notify; /* notify itnim on TM comp */
107 lun_t lun; /* lun if applicable */
108 enum fcp_tm_cmnd tm_cmnd; /* task management command */
109 u16 tsk_tag; /* FWI IO tag */
110 u8 tsecs; /* timeout in seconds */
111 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
112 struct list_head io_q; /* queue of affected IOs */
113 struct bfa_wc_s wc; /* waiting counter */
114 struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
115 enum bfi_tskim_status tsk_status; /* TM status */
116};
117
118/**
119 * BFA i-t-n (initiator mode)
120 */
121struct bfa_itnim_s {
122 struct list_head qe; /* queue element */
123 bfa_sm_t sm; /* i-t-n im BFA state machine */
124 struct bfa_s *bfa; /* bfa instance */
125 struct bfa_rport_s *rport; /* bfa rport */
126 void *ditn; /* driver i-t-n structure */
127 struct bfi_mhdr_s mhdr; /* pre-built mhdr */
128 u8 msg_no; /* itnim/rport firmware handle */
129 u8 reqq; /* CQ for requests */
130 struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
131 struct list_head pending_q; /* queue of pending IO requests*/
132 struct list_head io_q; /* queue of active IO requests */
133 struct list_head io_cleanup_q; /* IO being cleaned up */
134 struct list_head tsk_q; /* queue of active TM commands */
135 struct list_head delay_comp_q;/* queue of failed inflight cmds */
136 bfa_boolean_t seq_rec; /* SQER supported */
137 bfa_boolean_t is_online; /* itnim is ONLINE for IO */
138 bfa_boolean_t iotov_active; /* IO TOV timer is active */
139 struct bfa_wc_s wc; /* waiting counter */
140 struct bfa_timer_s timer; /* pending IO TOV */
141 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
142 struct bfa_fcpim_mod_s *fcpim; /* fcpim module */
143 struct bfa_itnim_hal_stats_s stats;
144};
145
146#define bfa_itnim_is_online(_itnim) (_itnim)->is_online
147#define BFA_FCPIM_MOD(_hal) (&(_hal)->modules.fcpim_mod)
148#define BFA_IOIM_FROM_TAG(_fcpim, _iotag) \
149 (&fcpim->ioim_arr[_iotag])
150#define BFA_TSKIM_FROM_TAG(_fcpim, _tmtag) \
151 (&fcpim->tskim_arr[_tmtag & (fcpim->num_tskim_reqs - 1)])
152
153/*
154 * function prototypes
155 */
156void bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim,
157 struct bfa_meminfo_s *minfo);
158void bfa_ioim_detach(struct bfa_fcpim_mod_s *fcpim);
159void bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
160void bfa_ioim_good_comp_isr(struct bfa_s *bfa,
161 struct bfi_msg_s *msg);
162void bfa_ioim_cleanup(struct bfa_ioim_s *ioim);
163void bfa_ioim_cleanup_tm(struct bfa_ioim_s *ioim,
164 struct bfa_tskim_s *tskim);
165void bfa_ioim_iocdisable(struct bfa_ioim_s *ioim);
166void bfa_ioim_tov(struct bfa_ioim_s *ioim);
167
168void bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim,
169 struct bfa_meminfo_s *minfo);
170void bfa_tskim_detach(struct bfa_fcpim_mod_s *fcpim);
171void bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
172void bfa_tskim_iodone(struct bfa_tskim_s *tskim);
173void bfa_tskim_iocdisable(struct bfa_tskim_s *tskim);
174void bfa_tskim_cleanup(struct bfa_tskim_s *tskim);
175
176void bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
177 u32 *dm_len);
178void bfa_itnim_attach(struct bfa_fcpim_mod_s *fcpim,
179 struct bfa_meminfo_s *minfo);
180void bfa_itnim_detach(struct bfa_fcpim_mod_s *fcpim);
181void bfa_itnim_iocdisable(struct bfa_itnim_s *itnim);
182void bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
183void bfa_itnim_iodone(struct bfa_itnim_s *itnim);
184void bfa_itnim_tskdone(struct bfa_itnim_s *itnim);
185bfa_boolean_t bfa_itnim_hold_io(struct bfa_itnim_s *itnim);
186
187#endif /* __BFA_FCPIM_PRIV_H__ */
188
diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c
new file mode 100644
index 000000000000..992435987deb
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcport.c
@@ -0,0 +1,1671 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19#include <bfa_svc.h>
20#include <bfi/bfi_pport.h>
21#include <cs/bfa_debug.h>
22#include <aen/bfa_aen.h>
23#include <cs/bfa_plog.h>
24#include <aen/bfa_aen_port.h>
25
26BFA_TRC_FILE(HAL, PPORT);
27BFA_MODULE(pport);
28
29#define bfa_pport_callback(__pport, __event) do { \
30 if ((__pport)->bfa->fcs) { \
31 (__pport)->event_cbfn((__pport)->event_cbarg, (__event)); \
32 } else { \
33 (__pport)->hcb_event = (__event); \
34 bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe, \
35 __bfa_cb_port_event, (__pport)); \
36 } \
37} while (0)
38
39/*
40 * The port is considered disabled if corresponding physical port or IOC are
41 * disabled explicitly
42 */
43#define BFA_PORT_IS_DISABLED(bfa) \
44 ((bfa_pport_is_disabled(bfa) == BFA_TRUE) || \
45 (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
46
47/*
48 * forward declarations
49 */
50static bfa_boolean_t bfa_pport_send_enable(struct bfa_pport_s *port);
51static bfa_boolean_t bfa_pport_send_disable(struct bfa_pport_s *port);
52static void bfa_pport_update_linkinfo(struct bfa_pport_s *pport);
53static void bfa_pport_reset_linkinfo(struct bfa_pport_s *pport);
54static void bfa_pport_set_wwns(struct bfa_pport_s *port);
55static void __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete);
56static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete);
57static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete);
58static void bfa_port_stats_timeout(void *cbarg);
59static void bfa_port_stats_clr_timeout(void *cbarg);
60
61/**
62 * bfa_pport_private
63 */
64
65/**
66 * BFA port state machine events
67 */
68enum bfa_pport_sm_event {
69 BFA_PPORT_SM_START = 1, /* start port state machine */
70 BFA_PPORT_SM_STOP = 2, /* stop port state machine */
71 BFA_PPORT_SM_ENABLE = 3, /* enable port */
72 BFA_PPORT_SM_DISABLE = 4, /* disable port state machine */
73 BFA_PPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */
74 BFA_PPORT_SM_LINKUP = 6, /* firmware linkup event */
75 BFA_PPORT_SM_LINKDOWN = 7, /* firmware linkup down */
76 BFA_PPORT_SM_QRESUME = 8, /* CQ space available */
77 BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */
78};
79
80static void bfa_pport_sm_uninit(struct bfa_pport_s *pport,
81 enum bfa_pport_sm_event event);
82static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
83 enum bfa_pport_sm_event event);
84static void bfa_pport_sm_enabling(struct bfa_pport_s *pport,
85 enum bfa_pport_sm_event event);
86static void bfa_pport_sm_linkdown(struct bfa_pport_s *pport,
87 enum bfa_pport_sm_event event);
88static void bfa_pport_sm_linkup(struct bfa_pport_s *pport,
89 enum bfa_pport_sm_event event);
90static void bfa_pport_sm_disabling(struct bfa_pport_s *pport,
91 enum bfa_pport_sm_event event);
92static void bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
93 enum bfa_pport_sm_event event);
94static void bfa_pport_sm_disabled(struct bfa_pport_s *pport,
95 enum bfa_pport_sm_event event);
96static void bfa_pport_sm_stopped(struct bfa_pport_s *pport,
97 enum bfa_pport_sm_event event);
98static void bfa_pport_sm_iocdown(struct bfa_pport_s *pport,
99 enum bfa_pport_sm_event event);
100static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport,
101 enum bfa_pport_sm_event event);
102
103static struct bfa_sm_table_s hal_pport_sm_table[] = {
104 {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT},
105 {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
106 {BFA_SM(bfa_pport_sm_enabling), BFA_PPORT_ST_ENABLING},
107 {BFA_SM(bfa_pport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
108 {BFA_SM(bfa_pport_sm_linkup), BFA_PPORT_ST_LINKUP},
109 {BFA_SM(bfa_pport_sm_disabling_qwait),
110 BFA_PPORT_ST_DISABLING_QWAIT},
111 {BFA_SM(bfa_pport_sm_disabling), BFA_PPORT_ST_DISABLING},
112 {BFA_SM(bfa_pport_sm_disabled), BFA_PPORT_ST_DISABLED},
113 {BFA_SM(bfa_pport_sm_stopped), BFA_PPORT_ST_STOPPED},
114 {BFA_SM(bfa_pport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
115 {BFA_SM(bfa_pport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
116};
117
118static void
119bfa_pport_aen_post(struct bfa_pport_s *pport, enum bfa_port_aen_event event)
120{
121 union bfa_aen_data_u aen_data;
122 struct bfa_log_mod_s *logmod = pport->bfa->logm;
123 wwn_t pwwn = pport->pwwn;
124 char pwwn_ptr[BFA_STRING_32];
125 struct bfa_ioc_attr_s ioc_attr;
126
127 wwn2str(pwwn_ptr, pwwn);
128 switch (event) {
129 case BFA_PORT_AEN_ONLINE:
130 bfa_log(logmod, BFA_AEN_PORT_ONLINE, pwwn_ptr);
131 break;
132 case BFA_PORT_AEN_OFFLINE:
133 bfa_log(logmod, BFA_AEN_PORT_OFFLINE, pwwn_ptr);
134 break;
135 case BFA_PORT_AEN_ENABLE:
136 bfa_log(logmod, BFA_AEN_PORT_ENABLE, pwwn_ptr);
137 break;
138 case BFA_PORT_AEN_DISABLE:
139 bfa_log(logmod, BFA_AEN_PORT_DISABLE, pwwn_ptr);
140 break;
141 case BFA_PORT_AEN_DISCONNECT:
142 bfa_log(logmod, BFA_AEN_PORT_DISCONNECT, pwwn_ptr);
143 break;
144 case BFA_PORT_AEN_QOS_NEG:
145 bfa_log(logmod, BFA_AEN_PORT_QOS_NEG, pwwn_ptr);
146 break;
147 default:
148 break;
149 }
150
151 bfa_ioc_get_attr(&pport->bfa->ioc, &ioc_attr);
152 aen_data.port.ioc_type = ioc_attr.ioc_type;
153 aen_data.port.pwwn = pwwn;
154}
155
156static void
157bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
158{
159 bfa_trc(pport->bfa, event);
160
161 switch (event) {
162 case BFA_PPORT_SM_START:
163 /**
164 * Start event after IOC is configured and BFA is started.
165 */
166 if (bfa_pport_send_enable(pport))
167 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
168 else
169 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
170 break;
171
172 case BFA_PPORT_SM_ENABLE:
173 /**
174 * Port is persistently configured to be in enabled state. Do
175 * not change state. Port enabling is done when START event is
176 * received.
177 */
178 break;
179
180 case BFA_PPORT_SM_DISABLE:
181 /**
182 * If a port is persistently configured to be disabled, the
183 * first event will a port disable request.
184 */
185 bfa_sm_set_state(pport, bfa_pport_sm_disabled);
186 break;
187
188 case BFA_PPORT_SM_HWFAIL:
189 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
190 break;
191
192 default:
193 bfa_sm_fault(pport->bfa, event);
194 }
195}
196
197static void
198bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
199 enum bfa_pport_sm_event event)
200{
201 bfa_trc(pport->bfa, event);
202
203 switch (event) {
204 case BFA_PPORT_SM_QRESUME:
205 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
206 bfa_pport_send_enable(pport);
207 break;
208
209 case BFA_PPORT_SM_STOP:
210 bfa_reqq_wcancel(&pport->reqq_wait);
211 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
212 break;
213
214 case BFA_PPORT_SM_ENABLE:
215 /**
216 * Already enable is in progress.
217 */
218 break;
219
220 case BFA_PPORT_SM_DISABLE:
221 /**
222 * Just send disable request to firmware when room becomes
223 * available in request queue.
224 */
225 bfa_sm_set_state(pport, bfa_pport_sm_disabled);
226 bfa_reqq_wcancel(&pport->reqq_wait);
227 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
228 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
229 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
230 break;
231
232 case BFA_PPORT_SM_LINKUP:
233 case BFA_PPORT_SM_LINKDOWN:
234 /**
235 * Possible to get link events when doing back-to-back
236 * enable/disables.
237 */
238 break;
239
240 case BFA_PPORT_SM_HWFAIL:
241 bfa_reqq_wcancel(&pport->reqq_wait);
242 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
243 break;
244
245 default:
246 bfa_sm_fault(pport->bfa, event);
247 }
248}
249
250static void
251bfa_pport_sm_enabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
252{
253 bfa_trc(pport->bfa, event);
254
255 switch (event) {
256 case BFA_PPORT_SM_FWRSP:
257 case BFA_PPORT_SM_LINKDOWN:
258 bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
259 break;
260
261 case BFA_PPORT_SM_LINKUP:
262 bfa_pport_update_linkinfo(pport);
263 bfa_sm_set_state(pport, bfa_pport_sm_linkup);
264
265 bfa_assert(pport->event_cbfn);
266 bfa_pport_callback(pport, BFA_PPORT_LINKUP);
267 break;
268
269 case BFA_PPORT_SM_ENABLE:
270 /**
271 * Already being enabled.
272 */
273 break;
274
275 case BFA_PPORT_SM_DISABLE:
276 if (bfa_pport_send_disable(pport))
277 bfa_sm_set_state(pport, bfa_pport_sm_disabling);
278 else
279 bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
280
281 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
282 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
283 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
284 break;
285
286 case BFA_PPORT_SM_STOP:
287 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
288 break;
289
290 case BFA_PPORT_SM_HWFAIL:
291 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
292 break;
293
294 default:
295 bfa_sm_fault(pport->bfa, event);
296 }
297}
298
299static void
300bfa_pport_sm_linkdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
301{
302 bfa_trc(pport->bfa, event);
303
304 switch (event) {
305 case BFA_PPORT_SM_LINKUP:
306 bfa_pport_update_linkinfo(pport);
307 bfa_sm_set_state(pport, bfa_pport_sm_linkup);
308 bfa_assert(pport->event_cbfn);
309 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
310 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
311 bfa_pport_callback(pport, BFA_PPORT_LINKUP);
312 bfa_pport_aen_post(pport, BFA_PORT_AEN_ONLINE);
313 /**
314 * If QoS is enabled and it is not online,
315 * Send a separate event.
316 */
317 if ((pport->cfg.qos_enabled)
318 && (bfa_os_ntohl(pport->qos_attr.state) != BFA_QOS_ONLINE))
319 bfa_pport_aen_post(pport, BFA_PORT_AEN_QOS_NEG);
320
321 break;
322
323 case BFA_PPORT_SM_LINKDOWN:
324 /**
325 * Possible to get link down event.
326 */
327 break;
328
329 case BFA_PPORT_SM_ENABLE:
330 /**
331 * Already enabled.
332 */
333 break;
334
335 case BFA_PPORT_SM_DISABLE:
336 if (bfa_pport_send_disable(pport))
337 bfa_sm_set_state(pport, bfa_pport_sm_disabling);
338 else
339 bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
340
341 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
342 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
343 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
344 break;
345
346 case BFA_PPORT_SM_STOP:
347 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
348 break;
349
350 case BFA_PPORT_SM_HWFAIL:
351 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
352 break;
353
354 default:
355 bfa_sm_fault(pport->bfa, event);
356 }
357}
358
359static void
360bfa_pport_sm_linkup(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
361{
362 bfa_trc(pport->bfa, event);
363
364 switch (event) {
365 case BFA_PPORT_SM_ENABLE:
366 /**
367 * Already enabled.
368 */
369 break;
370
371 case BFA_PPORT_SM_DISABLE:
372 if (bfa_pport_send_disable(pport))
373 bfa_sm_set_state(pport, bfa_pport_sm_disabling);
374 else
375 bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
376
377 bfa_pport_reset_linkinfo(pport);
378 bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
379 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
380 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
381 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
382 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
383 break;
384
385 case BFA_PPORT_SM_LINKDOWN:
386 bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
387 bfa_pport_reset_linkinfo(pport);
388 bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
389 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
390 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
391 if (BFA_PORT_IS_DISABLED(pport->bfa)) {
392 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
393 } else {
394 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
395 }
396 break;
397
398 case BFA_PPORT_SM_STOP:
399 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
400 bfa_pport_reset_linkinfo(pport);
401 if (BFA_PORT_IS_DISABLED(pport->bfa)) {
402 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
403 } else {
404 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
405 }
406 break;
407
408 case BFA_PPORT_SM_HWFAIL:
409 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
410 bfa_pport_reset_linkinfo(pport);
411 bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
412 if (BFA_PORT_IS_DISABLED(pport->bfa)) {
413 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
414 } else {
415 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
416 }
417 break;
418
419 default:
420 bfa_sm_fault(pport->bfa, event);
421 }
422}
423
424static void
425bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
426 enum bfa_pport_sm_event event)
427{
428 bfa_trc(pport->bfa, event);
429
430 switch (event) {
431 case BFA_PPORT_SM_QRESUME:
432 bfa_sm_set_state(pport, bfa_pport_sm_disabling);
433 bfa_pport_send_disable(pport);
434 break;
435
436 case BFA_PPORT_SM_STOP:
437 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
438 bfa_reqq_wcancel(&pport->reqq_wait);
439 break;
440
441 case BFA_PPORT_SM_DISABLE:
442 /**
443 * Already being disabled.
444 */
445 break;
446
447 case BFA_PPORT_SM_LINKUP:
448 case BFA_PPORT_SM_LINKDOWN:
449 /**
450 * Possible to get link events when doing back-to-back
451 * enable/disables.
452 */
453 break;
454
455 case BFA_PPORT_SM_HWFAIL:
456 bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
457 bfa_reqq_wcancel(&pport->reqq_wait);
458 break;
459
460 default:
461 bfa_sm_fault(pport->bfa, event);
462 }
463}
464
465static void
466bfa_pport_sm_disabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
467{
468 bfa_trc(pport->bfa, event);
469
470 switch (event) {
471 case BFA_PPORT_SM_FWRSP:
472 bfa_sm_set_state(pport, bfa_pport_sm_disabled);
473 break;
474
475 case BFA_PPORT_SM_DISABLE:
476 /**
477 * Already being disabled.
478 */
479 break;
480
481 case BFA_PPORT_SM_ENABLE:
482 if (bfa_pport_send_enable(pport))
483 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
484 else
485 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
486
487 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
488 BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
489 bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
490 break;
491
492 case BFA_PPORT_SM_STOP:
493 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
494 break;
495
496 case BFA_PPORT_SM_LINKUP:
497 case BFA_PPORT_SM_LINKDOWN:
498 /**
499 * Possible to get link events when doing back-to-back
500 * enable/disables.
501 */
502 break;
503
504 case BFA_PPORT_SM_HWFAIL:
505 bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
506 break;
507
508 default:
509 bfa_sm_fault(pport->bfa, event);
510 }
511}
512
513static void
514bfa_pport_sm_disabled(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
515{
516 bfa_trc(pport->bfa, event);
517
518 switch (event) {
519 case BFA_PPORT_SM_START:
520 /**
521 * Ignore start event for a port that is disabled.
522 */
523 break;
524
525 case BFA_PPORT_SM_STOP:
526 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
527 break;
528
529 case BFA_PPORT_SM_ENABLE:
530 if (bfa_pport_send_enable(pport))
531 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
532 else
533 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
534
535 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
536 BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
537 bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
538 break;
539
540 case BFA_PPORT_SM_DISABLE:
541 /**
542 * Already disabled.
543 */
544 break;
545
546 case BFA_PPORT_SM_HWFAIL:
547 bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
548 break;
549
550 default:
551 bfa_sm_fault(pport->bfa, event);
552 }
553}
554
555static void
556bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
557{
558 bfa_trc(pport->bfa, event);
559
560 switch (event) {
561 case BFA_PPORT_SM_START:
562 if (bfa_pport_send_enable(pport))
563 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
564 else
565 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
566 break;
567
568 default:
569 /**
570 * Ignore all other events.
571 */
572 ;
573 }
574}
575
576/**
577 * Port is enabled. IOC is down/failed.
578 */
579static void
580bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
581{
582 bfa_trc(pport->bfa, event);
583
584 switch (event) {
585 case BFA_PPORT_SM_START:
586 if (bfa_pport_send_enable(pport))
587 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
588 else
589 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
590 break;
591
592 default:
593 /**
594 * Ignore all events.
595 */
596 ;
597 }
598}
599
600/**
601 * Port is disabled. IOC is down/failed.
602 */
603static void
604bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
605{
606 bfa_trc(pport->bfa, event);
607
608 switch (event) {
609 case BFA_PPORT_SM_START:
610 bfa_sm_set_state(pport, bfa_pport_sm_disabled);
611 break;
612
613 case BFA_PPORT_SM_ENABLE:
614 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
615 break;
616
617 default:
618 /**
619 * Ignore all events.
620 */
621 ;
622 }
623}
624
625
626
627/**
628 * bfa_pport_private
629 */
630
631static void
632__bfa_cb_port_event(void *cbarg, bfa_boolean_t complete)
633{
634 struct bfa_pport_s *pport = cbarg;
635
636 if (complete)
637 pport->event_cbfn(pport->event_cbarg, pport->hcb_event);
638}
639
640#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \
641 BFA_CACHELINE_SZ))
642
643static void
644bfa_pport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
645 u32 *dm_len)
646{
647 *dm_len += PPORT_STATS_DMA_SZ;
648}
649
650static void
651bfa_pport_qresume(void *cbarg)
652{
653 struct bfa_pport_s *port = cbarg;
654
655 bfa_sm_send_event(port, BFA_PPORT_SM_QRESUME);
656}
657
658static void
659bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
660{
661 u8 *dm_kva;
662 u64 dm_pa;
663
664 dm_kva = bfa_meminfo_dma_virt(meminfo);
665 dm_pa = bfa_meminfo_dma_phys(meminfo);
666
667 pport->stats_kva = dm_kva;
668 pport->stats_pa = dm_pa;
669 pport->stats = (union bfa_pport_stats_u *)dm_kva;
670
671 dm_kva += PPORT_STATS_DMA_SZ;
672 dm_pa += PPORT_STATS_DMA_SZ;
673
674 bfa_meminfo_dma_virt(meminfo) = dm_kva;
675 bfa_meminfo_dma_phys(meminfo) = dm_pa;
676}
677
678/**
679 * Memory initialization.
680 */
681static void
682bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
683 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
684{
685 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
686 struct bfa_pport_cfg_s *port_cfg = &pport->cfg;
687
688 bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s));
689 pport->bfa = bfa;
690
691 bfa_pport_mem_claim(pport, meminfo);
692
693 bfa_sm_set_state(pport, bfa_pport_sm_uninit);
694
695 /**
696 * initialize and set default configuration
697 */
698 port_cfg->topology = BFA_PPORT_TOPOLOGY_P2P;
699 port_cfg->speed = BFA_PPORT_SPEED_AUTO;
700 port_cfg->trunked = BFA_FALSE;
701 port_cfg->maxfrsize = 0;
702
703 port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS;
704
705 bfa_reqq_winit(&pport->reqq_wait, bfa_pport_qresume, pport);
706}
707
708static void
709bfa_pport_initdone(struct bfa_s *bfa)
710{
711 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
712
713 /**
714 * Initialize port attributes from IOC hardware data.
715 */
716 bfa_pport_set_wwns(pport);
717 if (pport->cfg.maxfrsize == 0)
718 pport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
719 pport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
720 pport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
721
722 bfa_assert(pport->cfg.maxfrsize);
723 bfa_assert(pport->cfg.rx_bbcredit);
724 bfa_assert(pport->speed_sup);
725}
726
727static void
728bfa_pport_detach(struct bfa_s *bfa)
729{
730}
731
732/**
733 * Called when IOC is ready.
734 */
735static void
736bfa_pport_start(struct bfa_s *bfa)
737{
738 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_START);
739}
740
741/**
742 * Called before IOC is stopped.
743 */
744static void
745bfa_pport_stop(struct bfa_s *bfa)
746{
747 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_STOP);
748}
749
750/**
751 * Called when IOC failure is detected.
752 */
753static void
754bfa_pport_iocdisable(struct bfa_s *bfa)
755{
756 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_HWFAIL);
757}
758
759static void
760bfa_pport_update_linkinfo(struct bfa_pport_s *pport)
761{
762 struct bfi_pport_event_s *pevent = pport->event_arg.i2hmsg.event;
763
764 pport->speed = pevent->link_state.speed;
765 pport->topology = pevent->link_state.topology;
766
767 if (pport->topology == BFA_PPORT_TOPOLOGY_LOOP)
768 pport->myalpa = pevent->link_state.tl.loop_info.myalpa;
769
770 /*
771 * QoS Details
772 */
773 bfa_os_assign(pport->qos_attr, pevent->link_state.qos_attr);
774 bfa_os_assign(pport->qos_vc_attr, pevent->link_state.qos_vc_attr);
775
776 bfa_trc(pport->bfa, pport->speed);
777 bfa_trc(pport->bfa, pport->topology);
778}
779
780static void
781bfa_pport_reset_linkinfo(struct bfa_pport_s *pport)
782{
783 pport->speed = BFA_PPORT_SPEED_UNKNOWN;
784 pport->topology = BFA_PPORT_TOPOLOGY_NONE;
785}
786
787/**
788 * Send port enable message to firmware.
789 */
790static bfa_boolean_t
791bfa_pport_send_enable(struct bfa_pport_s *port)
792{
793 struct bfi_pport_enable_req_s *m;
794
795 /**
796 * Increment message tag before queue check, so that responses to old
797 * requests are discarded.
798 */
799 port->msgtag++;
800
801 /**
802 * check for room in queue to send request now
803 */
804 m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
805 if (!m) {
806 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
807 return BFA_FALSE;
808 }
809
810 bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_ENABLE_REQ,
811 bfa_lpuid(port->bfa));
812 m->nwwn = port->nwwn;
813 m->pwwn = port->pwwn;
814 m->port_cfg = port->cfg;
815 m->msgtag = port->msgtag;
816 m->port_cfg.maxfrsize = bfa_os_htons(port->cfg.maxfrsize);
817 bfa_dma_be_addr_set(m->stats_dma_addr, port->stats_pa);
818 bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_lo);
819 bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_hi);
820
821 /**
822 * queue I/O message to firmware
823 */
824 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
825 return BFA_TRUE;
826}
827
828/**
829 * Send port disable message to firmware.
830 */
831static bfa_boolean_t
832bfa_pport_send_disable(struct bfa_pport_s *port)
833{
834 bfi_pport_disable_req_t *m;
835
836 /**
837 * Increment message tag before queue check, so that responses to old
838 * requests are discarded.
839 */
840 port->msgtag++;
841
842 /**
843 * check for room in queue to send request now
844 */
845 m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
846 if (!m) {
847 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
848 return BFA_FALSE;
849 }
850
851 bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_DISABLE_REQ,
852 bfa_lpuid(port->bfa));
853 m->msgtag = port->msgtag;
854
855 /**
856 * queue I/O message to firmware
857 */
858 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
859
860 return BFA_TRUE;
861}
862
863static void
864bfa_pport_set_wwns(struct bfa_pport_s *port)
865{
866 port->pwwn = bfa_ioc_get_pwwn(&port->bfa->ioc);
867 port->nwwn = bfa_ioc_get_nwwn(&port->bfa->ioc);
868
869 bfa_trc(port->bfa, port->pwwn);
870 bfa_trc(port->bfa, port->nwwn);
871}
872
873static void
874bfa_port_send_txcredit(void *port_cbarg)
875{
876
877 struct bfa_pport_s *port = port_cbarg;
878 struct bfi_pport_set_svc_params_req_s *m;
879
880 /**
881 * check for room in queue to send request now
882 */
883 m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
884 if (!m) {
885 bfa_trc(port->bfa, port->cfg.tx_bbcredit);
886 return;
887 }
888
889 bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_SET_SVC_PARAMS_REQ,
890 bfa_lpuid(port->bfa));
891 m->tx_bbcredit = bfa_os_htons((u16) port->cfg.tx_bbcredit);
892
893 /**
894 * queue I/O message to firmware
895 */
896 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
897}
898
899
900
901/**
902 * bfa_pport_public
903 */
904
905/**
906 * Firmware message handler.
907 */
908void
909bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
910{
911 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
912 union bfi_pport_i2h_msg_u i2hmsg;
913
914 i2hmsg.msg = msg;
915 pport->event_arg.i2hmsg = i2hmsg;
916
917 switch (msg->mhdr.msg_id) {
918 case BFI_PPORT_I2H_ENABLE_RSP:
919 if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
920 bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
921 break;
922
923 case BFI_PPORT_I2H_DISABLE_RSP:
924 if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
925 bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
926 break;
927
928 case BFI_PPORT_I2H_EVENT:
929 switch (i2hmsg.event->link_state.linkstate) {
930 case BFA_PPORT_LINKUP:
931 bfa_sm_send_event(pport, BFA_PPORT_SM_LINKUP);
932 break;
933 case BFA_PPORT_LINKDOWN:
934 bfa_sm_send_event(pport, BFA_PPORT_SM_LINKDOWN);
935 break;
936 case BFA_PPORT_TRUNK_LINKDOWN:
937 /** todo: event notification */
938 break;
939 }
940 break;
941
942 case BFI_PPORT_I2H_GET_STATS_RSP:
943 case BFI_PPORT_I2H_GET_QOS_STATS_RSP:
944 /*
945 * check for timer pop before processing the rsp
946 */
947 if (pport->stats_busy == BFA_FALSE
948 || pport->stats_status == BFA_STATUS_ETIMER)
949 break;
950
951 bfa_timer_stop(&pport->timer);
952 pport->stats_status = i2hmsg.getstats_rsp->status;
953 bfa_cb_queue(pport->bfa, &pport->hcb_qe, __bfa_cb_port_stats,
954 pport);
955 break;
956 case BFI_PPORT_I2H_CLEAR_STATS_RSP:
957 case BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP:
958 /*
959 * check for timer pop before processing the rsp
960 */
961 if (pport->stats_busy == BFA_FALSE
962 || pport->stats_status == BFA_STATUS_ETIMER)
963 break;
964
965 bfa_timer_stop(&pport->timer);
966 pport->stats_status = BFA_STATUS_OK;
967 bfa_cb_queue(pport->bfa, &pport->hcb_qe,
968 __bfa_cb_port_stats_clr, pport);
969 break;
970
971 default:
972 bfa_assert(0);
973 }
974}
975
976
977
978/**
979 * bfa_pport_api
980 */
981
982/**
983 * Registered callback for port events.
984 */
985void
986bfa_pport_event_register(struct bfa_s *bfa,
987 void (*cbfn) (void *cbarg, bfa_pport_event_t event),
988 void *cbarg)
989{
990 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
991
992 pport->event_cbfn = cbfn;
993 pport->event_cbarg = cbarg;
994}
995
996bfa_status_t
997bfa_pport_enable(struct bfa_s *bfa)
998{
999 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1000
1001 if (pport->diag_busy)
1002 return (BFA_STATUS_DIAG_BUSY);
1003 else if (bfa_sm_cmp_state
1004 (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait))
1005 return (BFA_STATUS_DEVBUSY);
1006
1007 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE);
1008 return BFA_STATUS_OK;
1009}
1010
1011bfa_status_t
1012bfa_pport_disable(struct bfa_s *bfa)
1013{
1014 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_DISABLE);
1015 return BFA_STATUS_OK;
1016}
1017
1018/**
1019 * Configure port speed.
1020 */
1021bfa_status_t
1022bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1023{
1024 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1025
1026 bfa_trc(bfa, speed);
1027
1028 if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > pport->speed_sup)) {
1029 bfa_trc(bfa, pport->speed_sup);
1030 return BFA_STATUS_UNSUPP_SPEED;
1031 }
1032
1033 pport->cfg.speed = speed;
1034
1035 return (BFA_STATUS_OK);
1036}
1037
1038/**
1039 * Get current speed.
1040 */
1041enum bfa_pport_speed
1042bfa_pport_get_speed(struct bfa_s *bfa)
1043{
1044 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1045
1046 return port->speed;
1047}
1048
1049/**
1050 * Configure port topology.
1051 */
1052bfa_status_t
1053bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
1054{
1055 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1056
1057 bfa_trc(bfa, topology);
1058 bfa_trc(bfa, pport->cfg.topology);
1059
1060 switch (topology) {
1061 case BFA_PPORT_TOPOLOGY_P2P:
1062 case BFA_PPORT_TOPOLOGY_LOOP:
1063 case BFA_PPORT_TOPOLOGY_AUTO:
1064 break;
1065
1066 default:
1067 return BFA_STATUS_EINVAL;
1068 }
1069
1070 pport->cfg.topology = topology;
1071 return (BFA_STATUS_OK);
1072}
1073
1074/**
1075 * Get current topology.
1076 */
1077enum bfa_pport_topology
1078bfa_pport_get_topology(struct bfa_s *bfa)
1079{
1080 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1081
1082 return port->topology;
1083}
1084
1085bfa_status_t
1086bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
1087{
1088 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1089
1090 bfa_trc(bfa, alpa);
1091 bfa_trc(bfa, pport->cfg.cfg_hardalpa);
1092 bfa_trc(bfa, pport->cfg.hardalpa);
1093
1094 pport->cfg.cfg_hardalpa = BFA_TRUE;
1095 pport->cfg.hardalpa = alpa;
1096
1097 return (BFA_STATUS_OK);
1098}
1099
1100bfa_status_t
1101bfa_pport_clr_hardalpa(struct bfa_s *bfa)
1102{
1103 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1104
1105 bfa_trc(bfa, pport->cfg.cfg_hardalpa);
1106 bfa_trc(bfa, pport->cfg.hardalpa);
1107
1108 pport->cfg.cfg_hardalpa = BFA_FALSE;
1109 return (BFA_STATUS_OK);
1110}
1111
1112bfa_boolean_t
1113bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
1114{
1115 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1116
1117 *alpa = port->cfg.hardalpa;
1118 return port->cfg.cfg_hardalpa;
1119}
1120
1121u8
1122bfa_pport_get_myalpa(struct bfa_s *bfa)
1123{
1124 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1125
1126 return port->myalpa;
1127}
1128
1129bfa_status_t
1130bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
1131{
1132 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1133
1134 bfa_trc(bfa, maxfrsize);
1135 bfa_trc(bfa, pport->cfg.maxfrsize);
1136
1137 /*
1138 * with in range
1139 */
1140 if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ))
1141 return (BFA_STATUS_INVLD_DFSZ);
1142
1143 /*
1144 * power of 2, if not the max frame size of 2112
1145 */
1146 if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
1147 return (BFA_STATUS_INVLD_DFSZ);
1148
1149 pport->cfg.maxfrsize = maxfrsize;
1150 return (BFA_STATUS_OK);
1151}
1152
1153u16
1154bfa_pport_get_maxfrsize(struct bfa_s *bfa)
1155{
1156 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1157
1158 return port->cfg.maxfrsize;
1159}
1160
1161u32
1162bfa_pport_mypid(struct bfa_s *bfa)
1163{
1164 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1165
1166 return port->mypid;
1167}
1168
1169u8
1170bfa_pport_get_rx_bbcredit(struct bfa_s *bfa)
1171{
1172 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1173
1174 return port->cfg.rx_bbcredit;
1175}
1176
1177void
1178bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
1179{
1180 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1181
1182 port->cfg.tx_bbcredit = (u8) tx_bbcredit;
1183 bfa_port_send_txcredit(port);
1184}
1185
1186/**
1187 * Get port attributes.
1188 */
1189
1190wwn_t
1191bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
1192{
1193 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1194 if (node)
1195 return pport->nwwn;
1196 else
1197 return pport->pwwn;
1198}
1199
1200void
1201bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
1202{
1203 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1204
1205 bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s));
1206
1207 attr->nwwn = pport->nwwn;
1208 attr->pwwn = pport->pwwn;
1209
1210 bfa_os_memcpy(&attr->pport_cfg, &pport->cfg,
1211 sizeof(struct bfa_pport_cfg_s));
1212 /*
1213 * speed attributes
1214 */
1215 attr->pport_cfg.speed = pport->cfg.speed;
1216 attr->speed_supported = pport->speed_sup;
1217 attr->speed = pport->speed;
1218 attr->cos_supported = FC_CLASS_3;
1219
1220 /*
1221 * topology attributes
1222 */
1223 attr->pport_cfg.topology = pport->cfg.topology;
1224 attr->topology = pport->topology;
1225
1226 /*
1227 * beacon attributes
1228 */
1229 attr->beacon = pport->beacon;
1230 attr->link_e2e_beacon = pport->link_e2e_beacon;
1231 attr->plog_enabled = bfa_plog_get_setting(pport->bfa->plog);
1232
1233 attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
1234 attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
1235 attr->port_state = bfa_sm_to_state(hal_pport_sm_table, pport->sm);
1236 if (bfa_ioc_is_disabled(&pport->bfa->ioc))
1237 attr->port_state = BFA_PPORT_ST_IOCDIS;
1238 else if (bfa_ioc_fw_mismatch(&pport->bfa->ioc))
1239 attr->port_state = BFA_PPORT_ST_FWMISMATCH;
1240}
1241
1242static void
1243bfa_port_stats_query(void *cbarg)
1244{
1245 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1246 bfi_pport_get_stats_req_t *msg;
1247
1248 msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
1249
1250 if (!msg) {
1251 port->stats_qfull = BFA_TRUE;
1252 bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_query,
1253 port);
1254 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
1255 return;
1256 }
1257 port->stats_qfull = BFA_FALSE;
1258
1259 bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t));
1260 bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ,
1261 bfa_lpuid(port->bfa));
1262 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
1263
1264 return;
1265}
1266
1267static void
1268bfa_port_stats_clear(void *cbarg)
1269{
1270 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1271 bfi_pport_clear_stats_req_t *msg;
1272
1273 msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
1274
1275 if (!msg) {
1276 port->stats_qfull = BFA_TRUE;
1277 bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_clear,
1278 port);
1279 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
1280 return;
1281 }
1282 port->stats_qfull = BFA_FALSE;
1283
1284 bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t));
1285 bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ,
1286 bfa_lpuid(port->bfa));
1287 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
1288 return;
1289}
1290
1291static void
1292bfa_port_qos_stats_clear(void *cbarg)
1293{
1294 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1295 bfi_pport_clear_qos_stats_req_t *msg;
1296
1297 msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
1298
1299 if (!msg) {
1300 port->stats_qfull = BFA_TRUE;
1301 bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_qos_stats_clear,
1302 port);
1303 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
1304 return;
1305 }
1306 port->stats_qfull = BFA_FALSE;
1307
1308 bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_qos_stats_req_t));
1309 bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ,
1310 bfa_lpuid(port->bfa));
1311 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
1312 return;
1313}
1314
1315static void
1316bfa_pport_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s)
1317{
1318 u32 *dip = (u32 *) d;
1319 u32 *sip = (u32 *) s;
1320 int i;
1321
1322 /*
1323 * Do 64 bit fields swap first
1324 */
1325 for (i = 0;
1326 i <
1327 ((sizeof(union bfa_pport_stats_u) -
1328 sizeof(struct bfa_qos_stats_s)) / sizeof(u32)); i = i + 2) {
1329#ifdef __BIGENDIAN
1330 dip[i] = bfa_os_ntohl(sip[i]);
1331 dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
1332#else
1333 dip[i] = bfa_os_ntohl(sip[i + 1]);
1334 dip[i + 1] = bfa_os_ntohl(sip[i]);
1335#endif
1336 }
1337
1338 /*
1339 * Now swap the 32 bit fields
1340 */
1341 for (; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); ++i)
1342 dip[i] = bfa_os_ntohl(sip[i]);
1343}
1344
1345static void
1346__bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete)
1347{
1348 struct bfa_pport_s *port = cbarg;
1349
1350 if (complete) {
1351 port->stats_cbfn(port->stats_cbarg, port->stats_status);
1352 } else {
1353 port->stats_busy = BFA_FALSE;
1354 port->stats_status = BFA_STATUS_OK;
1355 }
1356}
1357
1358static void
1359bfa_port_stats_clr_timeout(void *cbarg)
1360{
1361 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1362
1363 bfa_trc(port->bfa, port->stats_qfull);
1364
1365 if (port->stats_qfull) {
1366 bfa_reqq_wcancel(&port->stats_reqq_wait);
1367 port->stats_qfull = BFA_FALSE;
1368 }
1369
1370 port->stats_status = BFA_STATUS_ETIMER;
1371 bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats_clr, port);
1372}
1373
1374static void
1375__bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete)
1376{
1377 struct bfa_pport_s *port = cbarg;
1378
1379 if (complete) {
1380 if (port->stats_status == BFA_STATUS_OK)
1381 bfa_pport_stats_swap(port->stats_ret, port->stats);
1382 port->stats_cbfn(port->stats_cbarg, port->stats_status);
1383 } else {
1384 port->stats_busy = BFA_FALSE;
1385 port->stats_status = BFA_STATUS_OK;
1386 }
1387}
1388
1389static void
1390bfa_port_stats_timeout(void *cbarg)
1391{
1392 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1393
1394 bfa_trc(port->bfa, port->stats_qfull);
1395
1396 if (port->stats_qfull) {
1397 bfa_reqq_wcancel(&port->stats_reqq_wait);
1398 port->stats_qfull = BFA_FALSE;
1399 }
1400
1401 port->stats_status = BFA_STATUS_ETIMER;
1402 bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats, port);
1403}
1404
1405#define BFA_PORT_STATS_TOV 1000
1406
1407/**
1408 * Fetch port attributes.
1409 */
1410bfa_status_t
1411bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
1412 bfa_cb_pport_t cbfn, void *cbarg)
1413{
1414 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1415
1416 if (port->stats_busy) {
1417 bfa_trc(bfa, port->stats_busy);
1418 return (BFA_STATUS_DEVBUSY);
1419 }
1420
1421 port->stats_busy = BFA_TRUE;
1422 port->stats_ret = stats;
1423 port->stats_cbfn = cbfn;
1424 port->stats_cbarg = cbarg;
1425
1426 bfa_port_stats_query(port);
1427
1428 bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port,
1429 BFA_PORT_STATS_TOV);
1430 return (BFA_STATUS_OK);
1431}
1432
1433bfa_status_t
1434bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1435{
1436 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1437
1438 if (port->stats_busy) {
1439 bfa_trc(bfa, port->stats_busy);
1440 return (BFA_STATUS_DEVBUSY);
1441 }
1442
1443 port->stats_busy = BFA_TRUE;
1444 port->stats_cbfn = cbfn;
1445 port->stats_cbarg = cbarg;
1446
1447 bfa_port_stats_clear(port);
1448
1449 bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
1450 BFA_PORT_STATS_TOV);
1451 return (BFA_STATUS_OK);
1452}
1453
1454bfa_status_t
1455bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
1456{
1457 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1458
1459 bfa_trc(bfa, bitmap);
1460 bfa_trc(bfa, pport->cfg.trunked);
1461 bfa_trc(bfa, pport->cfg.trunk_ports);
1462
1463 if (!bitmap || (bitmap & (bitmap - 1)))
1464 return BFA_STATUS_EINVAL;
1465
1466 pport->cfg.trunked = BFA_TRUE;
1467 pport->cfg.trunk_ports = bitmap;
1468
1469 return BFA_STATUS_OK;
1470}
1471
1472void
1473bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
1474{
1475 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1476
1477 qos_attr->state = bfa_os_ntohl(pport->qos_attr.state);
1478 qos_attr->total_bb_cr = bfa_os_ntohl(pport->qos_attr.total_bb_cr);
1479}
1480
1481void
1482bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
1483 struct bfa_qos_vc_attr_s *qos_vc_attr)
1484{
1485 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1486 struct bfa_qos_vc_attr_s *bfa_vc_attr = &pport->qos_vc_attr;
1487 u32 i = 0;
1488
1489 qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count);
1490 qos_vc_attr->shared_credit = bfa_os_ntohs(bfa_vc_attr->shared_credit);
1491 qos_vc_attr->elp_opmode_flags =
1492 bfa_os_ntohl(bfa_vc_attr->elp_opmode_flags);
1493
1494 /*
1495 * Individual VC info
1496 */
1497 while (i < qos_vc_attr->total_vc_count) {
1498 qos_vc_attr->vc_info[i].vc_credit =
1499 bfa_vc_attr->vc_info[i].vc_credit;
1500 qos_vc_attr->vc_info[i].borrow_credit =
1501 bfa_vc_attr->vc_info[i].borrow_credit;
1502 qos_vc_attr->vc_info[i].priority =
1503 bfa_vc_attr->vc_info[i].priority;
1504 ++i;
1505 }
1506}
1507
1508/**
1509 * Fetch QoS Stats.
1510 */
1511bfa_status_t
1512bfa_pport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
1513 bfa_cb_pport_t cbfn, void *cbarg)
1514{
1515 /*
1516 * QoS stats is embedded in port stats
1517 */
1518 return (bfa_pport_get_stats(bfa, stats, cbfn, cbarg));
1519}
1520
1521bfa_status_t
1522bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1523{
1524 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1525
1526 if (port->stats_busy) {
1527 bfa_trc(bfa, port->stats_busy);
1528 return (BFA_STATUS_DEVBUSY);
1529 }
1530
1531 port->stats_busy = BFA_TRUE;
1532 port->stats_cbfn = cbfn;
1533 port->stats_cbarg = cbarg;
1534
1535 bfa_port_qos_stats_clear(port);
1536
1537 bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
1538 BFA_PORT_STATS_TOV);
1539 return (BFA_STATUS_OK);
1540}
1541
1542/**
1543 * Fetch port attributes.
1544 */
1545bfa_status_t
1546bfa_pport_trunk_disable(struct bfa_s *bfa)
1547{
1548 return (BFA_STATUS_OK);
1549}
1550
1551bfa_boolean_t
1552bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
1553{
1554 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1555
1556 *bitmap = port->cfg.trunk_ports;
1557 return port->cfg.trunked;
1558}
1559
1560bfa_boolean_t
1561bfa_pport_is_disabled(struct bfa_s *bfa)
1562{
1563 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1564
1565 return (bfa_sm_to_state(hal_pport_sm_table, port->sm) ==
1566 BFA_PPORT_ST_DISABLED);
1567
1568}
1569
1570bfa_boolean_t
1571bfa_pport_is_ratelim(struct bfa_s *bfa)
1572{
1573 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1574
1575return (pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE);
1576
1577}
1578
1579void
1580bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
1581{
1582 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1583
1584 bfa_trc(bfa, on_off);
1585 bfa_trc(bfa, pport->cfg.qos_enabled);
1586
1587 pport->cfg.qos_enabled = on_off;
1588}
1589
1590void
1591bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
1592{
1593 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1594
1595 bfa_trc(bfa, on_off);
1596 bfa_trc(bfa, pport->cfg.ratelimit);
1597
1598 pport->cfg.ratelimit = on_off;
1599 if (pport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
1600 pport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
1601}
1602
1603/**
1604 * Configure default minimum ratelim speed
1605 */
1606bfa_status_t
1607bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1608{
1609 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1610
1611 bfa_trc(bfa, speed);
1612
1613 /*
1614 * Auto and speeds greater than the supported speed, are invalid
1615 */
1616 if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > pport->speed_sup)) {
1617 bfa_trc(bfa, pport->speed_sup);
1618 return BFA_STATUS_UNSUPP_SPEED;
1619 }
1620
1621 pport->cfg.trl_def_speed = speed;
1622
1623 return (BFA_STATUS_OK);
1624}
1625
1626/**
1627 * Get default minimum ratelim speed
1628 */
1629enum bfa_pport_speed
1630bfa_pport_get_ratelim_speed(struct bfa_s *bfa)
1631{
1632 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1633
1634 bfa_trc(bfa, pport->cfg.trl_def_speed);
1635 return (pport->cfg.trl_def_speed);
1636
1637}
1638
1639void
1640bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status)
1641{
1642 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1643
1644 bfa_trc(bfa, status);
1645 bfa_trc(bfa, pport->diag_busy);
1646
1647 pport->diag_busy = status;
1648}
1649
1650void
1651bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
1652 bfa_boolean_t link_e2e_beacon)
1653{
1654 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1655
1656 bfa_trc(bfa, beacon);
1657 bfa_trc(bfa, link_e2e_beacon);
1658 bfa_trc(bfa, pport->beacon);
1659 bfa_trc(bfa, pport->link_e2e_beacon);
1660
1661 pport->beacon = beacon;
1662 pport->link_e2e_beacon = link_e2e_beacon;
1663}
1664
1665bfa_boolean_t
1666bfa_pport_is_linkup(struct bfa_s *bfa)
1667{
1668 return bfa_sm_cmp_state(BFA_PORT_MOD(bfa), bfa_pport_sm_linkup);
1669}
1670
1671
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
new file mode 100644
index 000000000000..7cb39a306ea9
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -0,0 +1,182 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcs.c BFA FCS main
20 */
21
22#include <fcs/bfa_fcs.h>
23#include "fcs_port.h"
24#include "fcs_uf.h"
25#include "fcs_vport.h"
26#include "fcs_rport.h"
27#include "fcs_fabric.h"
28#include "fcs_fcpim.h"
29#include "fcs_fcptm.h"
30#include "fcbuild.h"
31#include "fcs.h"
32#include "bfad_drv.h"
33#include <fcb/bfa_fcb.h>
34
35/**
36 * FCS sub-modules
37 */
38struct bfa_fcs_mod_s {
39 void (*modinit) (struct bfa_fcs_s *fcs);
40 void (*modexit) (struct bfa_fcs_s *fcs);
41};
42
43#define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
44
45static struct bfa_fcs_mod_s fcs_modules[] = {
46 BFA_FCS_MODULE(bfa_fcs_pport),
47 BFA_FCS_MODULE(bfa_fcs_uf),
48 BFA_FCS_MODULE(bfa_fcs_fabric),
49 BFA_FCS_MODULE(bfa_fcs_vport),
50 BFA_FCS_MODULE(bfa_fcs_rport),
51 BFA_FCS_MODULE(bfa_fcs_fcpim),
52};
53
54/**
55 * fcs_api BFA FCS API
56 */
57
58static void
59bfa_fcs_exit_comp(void *fcs_cbarg)
60{
61 struct bfa_fcs_s *fcs = fcs_cbarg;
62 struct bfad_s *bfad = fcs->bfad;
63
64 complete(&bfad->comp);
65}
66
67
68
69/**
70 * fcs_api BFA FCS API
71 */
72
73/**
74 * FCS instance initialization.
75 *
76 * param[in] fcs FCS instance
77 * param[in] bfa BFA instance
78 * param[in] bfad BFA driver instance
79 *
80 * return None
81 */
82void
83bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
84 bfa_boolean_t min_cfg)
85{
86 int i;
87 struct bfa_fcs_mod_s *mod;
88
89 fcs->bfa = bfa;
90 fcs->bfad = bfad;
91 fcs->min_cfg = min_cfg;
92
93 bfa_attach_fcs(bfa);
94 fcbuild_init();
95
96 for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
97 mod = &fcs_modules[i];
98 mod->modinit(fcs);
99 }
100}
101
102/**
103 * Start FCS operations.
104 */
105void
106bfa_fcs_start(struct bfa_fcs_s *fcs)
107{
108 bfa_fcs_fabric_modstart(fcs);
109}
110
111/**
112 * FCS driver details initialization.
113 *
114 * param[in] fcs FCS instance
115 * param[in] driver_info Driver Details
116 *
117 * return None
118 */
119void
120bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
121 struct bfa_fcs_driver_info_s *driver_info)
122{
123
124 fcs->driver_info = *driver_info;
125
126 bfa_fcs_fabric_psymb_init(&fcs->fabric);
127}
128
129/**
130 * FCS instance cleanup and exit.
131 *
132 * param[in] fcs FCS instance
133 * return None
134 */
135void
136bfa_fcs_exit(struct bfa_fcs_s *fcs)
137{
138 struct bfa_fcs_mod_s *mod;
139 int nmods, i;
140
141 bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);
142
143 nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
144
145 for (i = 0; i < nmods; i++) {
146 bfa_wc_up(&fcs->wc);
147
148 mod = &fcs_modules[i];
149 mod->modexit(fcs);
150 }
151
152 bfa_wc_wait(&fcs->wc);
153}
154
155
156void
157bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod)
158{
159 fcs->trcmod = trcmod;
160}
161
162
163void
164bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod)
165{
166 fcs->logm = logmod;
167}
168
169
170void
171bfa_fcs_aen_init(struct bfa_fcs_s *fcs, struct bfa_aen_s *aen)
172{
173 fcs->aen = aen;
174}
175
176void
177bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs)
178{
179 bfa_wc_down(&fcs->wc);
180}
181
182
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
new file mode 100644
index 000000000000..8975ed041dc0
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -0,0 +1,940 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcs_port.c BFA FCS port
20 */
21
22#include <fcs/bfa_fcs.h>
23#include <fcs/bfa_fcs_lport.h>
24#include <fcs/bfa_fcs_rport.h>
25#include <fcb/bfa_fcb_port.h>
26#include <bfa_svc.h>
27#include <log/bfa_log_fcs.h>
28#include "fcs.h"
29#include "fcs_lport.h"
30#include "fcs_vport.h"
31#include "fcs_rport.h"
32#include "fcs_fcxp.h"
33#include "fcs_trcmod.h"
34#include "lport_priv.h"
35#include <aen/bfa_aen_lport.h>
36
37BFA_TRC_FILE(FCS, PORT);
38
39/**
40 * Forward declarations
41 */
42
43static void bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port,
44 enum bfa_lport_aen_event event);
45static void bfa_fcs_port_send_ls_rjt(struct bfa_fcs_port_s *port,
46 struct fchs_s *rx_fchs, u8 reason_code,
47 u8 reason_code_expl);
48static void bfa_fcs_port_plogi(struct bfa_fcs_port_s *port,
49 struct fchs_s *rx_fchs,
50 struct fc_logi_s *plogi);
51static void bfa_fcs_port_online_actions(struct bfa_fcs_port_s *port);
52static void bfa_fcs_port_offline_actions(struct bfa_fcs_port_s *port);
53static void bfa_fcs_port_unknown_init(struct bfa_fcs_port_s *port);
54static void bfa_fcs_port_unknown_online(struct bfa_fcs_port_s *port);
55static void bfa_fcs_port_unknown_offline(struct bfa_fcs_port_s *port);
56static void bfa_fcs_port_deleted(struct bfa_fcs_port_s *port);
57static void bfa_fcs_port_echo(struct bfa_fcs_port_s *port,
58 struct fchs_s *rx_fchs,
59 struct fc_echo_s *echo, u16 len);
60static void bfa_fcs_port_rnid(struct bfa_fcs_port_s *port,
61 struct fchs_s *rx_fchs,
62 struct fc_rnid_cmd_s *rnid, u16 len);
63static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_port_s *port,
64 struct fc_rnid_general_topology_data_s *gen_topo_data);
65
66static struct {
67 void (*init) (struct bfa_fcs_port_s *port);
68 void (*online) (struct bfa_fcs_port_s *port);
69 void (*offline) (struct bfa_fcs_port_s *port);
70} __port_action[] = {
71 {
72 bfa_fcs_port_unknown_init, bfa_fcs_port_unknown_online,
73 bfa_fcs_port_unknown_offline}, {
74 bfa_fcs_port_fab_init, bfa_fcs_port_fab_online,
75 bfa_fcs_port_fab_offline}, {
76 bfa_fcs_port_loop_init, bfa_fcs_port_loop_online,
77 bfa_fcs_port_loop_offline}, {
78bfa_fcs_port_n2n_init, bfa_fcs_port_n2n_online,
79 bfa_fcs_port_n2n_offline},};
80
81/**
82 * fcs_port_sm FCS logical port state machine
83 */
84
85enum bfa_fcs_port_event {
86 BFA_FCS_PORT_SM_CREATE = 1,
87 BFA_FCS_PORT_SM_ONLINE = 2,
88 BFA_FCS_PORT_SM_OFFLINE = 3,
89 BFA_FCS_PORT_SM_DELETE = 4,
90 BFA_FCS_PORT_SM_DELRPORT = 5,
91};
92
93static void bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port,
94 enum bfa_fcs_port_event event);
95static void bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port,
96 enum bfa_fcs_port_event event);
97static void bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port,
98 enum bfa_fcs_port_event event);
99static void bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port,
100 enum bfa_fcs_port_event event);
101static void bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port,
102 enum bfa_fcs_port_event event);
103
104static void
105bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port,
106 enum bfa_fcs_port_event event)
107{
108 bfa_trc(port->fcs, port->port_cfg.pwwn);
109 bfa_trc(port->fcs, event);
110
111 switch (event) {
112 case BFA_FCS_PORT_SM_CREATE:
113 bfa_sm_set_state(port, bfa_fcs_port_sm_init);
114 break;
115
116 default:
117 bfa_assert(0);
118 }
119}
120
121static void
122bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event)
123{
124 bfa_trc(port->fcs, port->port_cfg.pwwn);
125 bfa_trc(port->fcs, event);
126
127 switch (event) {
128 case BFA_FCS_PORT_SM_ONLINE:
129 bfa_sm_set_state(port, bfa_fcs_port_sm_online);
130 bfa_fcs_port_online_actions(port);
131 break;
132
133 case BFA_FCS_PORT_SM_DELETE:
134 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
135 bfa_fcs_port_deleted(port);
136 break;
137
138 default:
139 bfa_assert(0);
140 }
141}
142
143static void
144bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port,
145 enum bfa_fcs_port_event event)
146{
147 struct bfa_fcs_rport_s *rport;
148 struct list_head *qe, *qen;
149
150 bfa_trc(port->fcs, port->port_cfg.pwwn);
151 bfa_trc(port->fcs, event);
152
153 switch (event) {
154 case BFA_FCS_PORT_SM_OFFLINE:
155 bfa_sm_set_state(port, bfa_fcs_port_sm_offline);
156 bfa_fcs_port_offline_actions(port);
157 break;
158
159 case BFA_FCS_PORT_SM_DELETE:
160
161 __port_action[port->fabric->fab_type].offline(port);
162
163 if (port->num_rports == 0) {
164 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
165 bfa_fcs_port_deleted(port);
166 } else {
167 bfa_sm_set_state(port, bfa_fcs_port_sm_deleting);
168 list_for_each_safe(qe, qen, &port->rport_q) {
169 rport = (struct bfa_fcs_rport_s *)qe;
170 bfa_fcs_rport_delete(rport);
171 }
172 }
173 break;
174
175 case BFA_FCS_PORT_SM_DELRPORT:
176 break;
177
178 default:
179 bfa_assert(0);
180 }
181}
182
183static void
184bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port,
185 enum bfa_fcs_port_event event)
186{
187 struct bfa_fcs_rport_s *rport;
188 struct list_head *qe, *qen;
189
190 bfa_trc(port->fcs, port->port_cfg.pwwn);
191 bfa_trc(port->fcs, event);
192
193 switch (event) {
194 case BFA_FCS_PORT_SM_ONLINE:
195 bfa_sm_set_state(port, bfa_fcs_port_sm_online);
196 bfa_fcs_port_online_actions(port);
197 break;
198
199 case BFA_FCS_PORT_SM_DELETE:
200 if (port->num_rports == 0) {
201 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
202 bfa_fcs_port_deleted(port);
203 } else {
204 bfa_sm_set_state(port, bfa_fcs_port_sm_deleting);
205 list_for_each_safe(qe, qen, &port->rport_q) {
206 rport = (struct bfa_fcs_rport_s *)qe;
207 bfa_fcs_rport_delete(rport);
208 }
209 }
210 break;
211
212 case BFA_FCS_PORT_SM_DELRPORT:
213 case BFA_FCS_PORT_SM_OFFLINE:
214 break;
215
216 default:
217 bfa_assert(0);
218 }
219}
220
221static void
222bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port,
223 enum bfa_fcs_port_event event)
224{
225 bfa_trc(port->fcs, port->port_cfg.pwwn);
226 bfa_trc(port->fcs, event);
227
228 switch (event) {
229 case BFA_FCS_PORT_SM_DELRPORT:
230 if (port->num_rports == 0) {
231 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
232 bfa_fcs_port_deleted(port);
233 }
234 break;
235
236 default:
237 bfa_assert(0);
238 }
239}
240
241
242
243/**
244 * fcs_port_pvt
245 */
246
247/**
248 * Send AEN notification
249 */
250static void
251bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port,
252 enum bfa_lport_aen_event event)
253{
254 union bfa_aen_data_u aen_data;
255 struct bfa_log_mod_s *logmod = port->fcs->logm;
256 enum bfa_port_role role = port->port_cfg.roles;
257 wwn_t lpwwn = bfa_fcs_port_get_pwwn(port);
258 char lpwwn_ptr[BFA_STRING_32];
259 char *role_str[BFA_PORT_ROLE_FCP_MAX / 2 + 1] =
260 { "Initiator", "Target", "IPFC" };
261
262 wwn2str(lpwwn_ptr, lpwwn);
263
264 bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
265
266 switch (event) {
267 case BFA_LPORT_AEN_ONLINE:
268 bfa_log(logmod, BFA_AEN_LPORT_ONLINE, lpwwn_ptr,
269 role_str[role / 2]);
270 break;
271 case BFA_LPORT_AEN_OFFLINE:
272 bfa_log(logmod, BFA_AEN_LPORT_OFFLINE, lpwwn_ptr,
273 role_str[role / 2]);
274 break;
275 case BFA_LPORT_AEN_NEW:
276 bfa_log(logmod, BFA_AEN_LPORT_NEW, lpwwn_ptr,
277 role_str[role / 2]);
278 break;
279 case BFA_LPORT_AEN_DELETE:
280 bfa_log(logmod, BFA_AEN_LPORT_DELETE, lpwwn_ptr,
281 role_str[role / 2]);
282 break;
283 case BFA_LPORT_AEN_DISCONNECT:
284 bfa_log(logmod, BFA_AEN_LPORT_DISCONNECT, lpwwn_ptr,
285 role_str[role / 2]);
286 break;
287 default:
288 break;
289 }
290
291 aen_data.lport.vf_id = port->fabric->vf_id;
292 aen_data.lport.roles = role;
293 aen_data.lport.ppwwn =
294 bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port->fcs));
295 aen_data.lport.lpwwn = lpwwn;
296}
297
298/*
299 * Send a LS reject
300 */
301static void
302bfa_fcs_port_send_ls_rjt(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
303 u8 reason_code, u8 reason_code_expl)
304{
305 struct fchs_s fchs;
306 struct bfa_fcxp_s *fcxp;
307 struct bfa_rport_s *bfa_rport = NULL;
308 int len;
309
310 bfa_trc(port->fcs, rx_fchs->s_id);
311
312 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
313 if (!fcxp)
314 return;
315
316 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
317 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
318 reason_code, reason_code_expl);
319
320 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
321 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
322 FC_MAX_PDUSZ, 0);
323}
324
325/**
326 * Process incoming plogi from a remote port.
327 */
328static void
329bfa_fcs_port_plogi(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
330 struct fc_logi_s *plogi)
331{
332 struct bfa_fcs_rport_s *rport;
333
334 bfa_trc(port->fcs, rx_fchs->d_id);
335 bfa_trc(port->fcs, rx_fchs->s_id);
336
337 /*
338 * If min cfg mode is enabled, drop any incoming PLOGIs
339 */
340 if (__fcs_min_cfg(port->fcs)) {
341 bfa_trc(port->fcs, rx_fchs->s_id);
342 return;
343 }
344
345 if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) {
346 bfa_trc(port->fcs, rx_fchs->s_id);
347 /*
348 * send a LS reject
349 */
350 bfa_fcs_port_send_ls_rjt(port, rx_fchs,
351 FC_LS_RJT_RSN_PROTOCOL_ERROR,
352 FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS);
353 return;
354 }
355
356 /**
357* Direct Attach P2P mode : verify address assigned by the r-port.
358 */
359 if ((!bfa_fcs_fabric_is_switched(port->fabric))
360 &&
361 (memcmp
362 ((void *)&bfa_fcs_port_get_pwwn(port), (void *)&plogi->port_name,
363 sizeof(wwn_t)) < 0)) {
364 if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) {
365 /*
366 * Address assigned to us cannot be a WKA
367 */
368 bfa_fcs_port_send_ls_rjt(port, rx_fchs,
369 FC_LS_RJT_RSN_PROTOCOL_ERROR,
370 FC_LS_RJT_EXP_INVALID_NPORT_ID);
371 return;
372 }
373 port->pid = rx_fchs->d_id;
374 }
375
376 /**
377 * First, check if we know the device by pwwn.
378 */
379 rport = bfa_fcs_port_get_rport_by_pwwn(port, plogi->port_name);
380 if (rport) {
381 /**
382 * Direct Attach P2P mode: handle address assigned by the rport.
383 */
384 if ((!bfa_fcs_fabric_is_switched(port->fabric))
385 &&
386 (memcmp
387 ((void *)&bfa_fcs_port_get_pwwn(port),
388 (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
389 port->pid = rx_fchs->d_id;
390 rport->pid = rx_fchs->s_id;
391 }
392 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
393 return;
394 }
395
396 /**
397 * Next, lookup rport by PID.
398 */
399 rport = bfa_fcs_port_get_rport_by_pid(port, rx_fchs->s_id);
400 if (!rport) {
401 /**
402 * Inbound PLOGI from a new device.
403 */
404 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
405 return;
406 }
407
408 /**
409 * Rport is known only by PID.
410 */
411 if (rport->pwwn) {
412 /**
413 * This is a different device with the same pid. Old device
414 * disappeared. Send implicit LOGO to old device.
415 */
416 bfa_assert(rport->pwwn != plogi->port_name);
417 bfa_fcs_rport_logo_imp(rport);
418
419 /**
420 * Inbound PLOGI from a new device (with old PID).
421 */
422 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
423 return;
424 }
425
426 /**
427 * PLOGI crossing each other.
428 */
429 bfa_assert(rport->pwwn == WWN_NULL);
430 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
431}
432
433/*
434 * Process incoming ECHO.
435 * Since it does not require a login, it is processed here.
436 */
437static void
438bfa_fcs_port_echo(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
439 struct fc_echo_s *echo, u16 rx_len)
440{
441 struct fchs_s fchs;
442 struct bfa_fcxp_s *fcxp;
443 struct bfa_rport_s *bfa_rport = NULL;
444 int len, pyld_len;
445
446 bfa_trc(port->fcs, rx_fchs->s_id);
447 bfa_trc(port->fcs, rx_fchs->d_id);
448 bfa_trc(port->fcs, rx_len);
449
450 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
451 if (!fcxp)
452 return;
453
454 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
455 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id);
456
457 /*
458 * Copy the payload (if any) from the echo frame
459 */
460 pyld_len = rx_len - sizeof(struct fchs_s);
461 bfa_trc(port->fcs, pyld_len);
462
463 if (pyld_len > len)
464 memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) +
465 sizeof(struct fc_echo_s), (echo + 1),
466 (pyld_len - sizeof(struct fc_echo_s)));
467
468 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
469 BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL,
470 FC_MAX_PDUSZ, 0);
471}
472
473/*
474 * Process incoming RNID.
475 * Since it does not require a login, it is processed here.
476 */
477static void
478bfa_fcs_port_rnid(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
479 struct fc_rnid_cmd_s *rnid, u16 rx_len)
480{
481 struct fc_rnid_common_id_data_s common_id_data;
482 struct fc_rnid_general_topology_data_s gen_topo_data;
483 struct fchs_s fchs;
484 struct bfa_fcxp_s *fcxp;
485 struct bfa_rport_s *bfa_rport = NULL;
486 u16 len;
487 u32 data_format;
488
489 bfa_trc(port->fcs, rx_fchs->s_id);
490 bfa_trc(port->fcs, rx_fchs->d_id);
491 bfa_trc(port->fcs, rx_len);
492
493 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
494 if (!fcxp)
495 return;
496
497 /*
498 * Check Node Indentification Data Format
499 * We only support General Topology Discovery Format.
500 * For any other requested Data Formats, we return Common Node Id Data
501 * only, as per FC-LS.
502 */
503 bfa_trc(port->fcs, rnid->node_id_data_format);
504 if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
505 data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY;
506 /*
507 * Get General topology data for this port
508 */
509 bfa_fs_port_get_gen_topo_data(port, &gen_topo_data);
510 } else {
511 data_format = RNID_NODEID_DATA_FORMAT_COMMON;
512 }
513
514 /*
515 * Copy the Node Id Info
516 */
517 common_id_data.port_name = bfa_fcs_port_get_pwwn(port);
518 common_id_data.node_name = bfa_fcs_port_get_nwwn(port);
519
520 len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
521 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
522 data_format, &common_id_data, &gen_topo_data);
523
524 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
525 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
526 FC_MAX_PDUSZ, 0);
527
528 return;
529}
530
531/*
532 * Fill out General Topolpgy Discovery Data for RNID ELS.
533 */
534static void
535bfa_fs_port_get_gen_topo_data(struct bfa_fcs_port_s *port,
536 struct fc_rnid_general_topology_data_s *gen_topo_data)
537{
538
539 bfa_os_memset(gen_topo_data, 0,
540 sizeof(struct fc_rnid_general_topology_data_s));
541
542 gen_topo_data->asso_type = bfa_os_htonl(RNID_ASSOCIATED_TYPE_HOST);
543 gen_topo_data->phy_port_num = 0; /* @todo */
544 gen_topo_data->num_attached_nodes = bfa_os_htonl(1);
545}
546
547static void
548bfa_fcs_port_online_actions(struct bfa_fcs_port_s *port)
549{
550 bfa_trc(port->fcs, port->fabric->oper_type);
551
552 __port_action[port->fabric->fab_type].init(port);
553 __port_action[port->fabric->fab_type].online(port);
554
555 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_ONLINE);
556 bfa_fcb_port_online(port->fcs->bfad, port->port_cfg.roles,
557 port->fabric->vf_drv, (port->vport == NULL) ?
558 NULL : port->vport->vport_drv);
559}
560
561static void
562bfa_fcs_port_offline_actions(struct bfa_fcs_port_s *port)
563{
564 struct list_head *qe, *qen;
565 struct bfa_fcs_rport_s *rport;
566
567 bfa_trc(port->fcs, port->fabric->oper_type);
568
569 __port_action[port->fabric->fab_type].offline(port);
570
571 if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE) {
572 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_DISCONNECT);
573 } else {
574 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_OFFLINE);
575 }
576 bfa_fcb_port_offline(port->fcs->bfad, port->port_cfg.roles,
577 port->fabric->vf_drv,
578 (port->vport == NULL) ? NULL : port->vport->vport_drv);
579
580 list_for_each_safe(qe, qen, &port->rport_q) {
581 rport = (struct bfa_fcs_rport_s *)qe;
582 bfa_fcs_rport_offline(rport);
583 }
584}
585
586static void
587bfa_fcs_port_unknown_init(struct bfa_fcs_port_s *port)
588{
589 bfa_assert(0);
590}
591
592static void
593bfa_fcs_port_unknown_online(struct bfa_fcs_port_s *port)
594{
595 bfa_assert(0);
596}
597
598static void
599bfa_fcs_port_unknown_offline(struct bfa_fcs_port_s *port)
600{
601 bfa_assert(0);
602}
603
604static void
605bfa_fcs_port_deleted(struct bfa_fcs_port_s *port)
606{
607 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_DELETE);
608
609 /*
610 * Base port will be deleted by the OS driver
611 */
612 if (port->vport) {
613 bfa_fcb_port_delete(port->fcs->bfad, port->port_cfg.roles,
614 port->fabric->vf_drv,
615 port->vport ? port->vport->vport_drv : NULL);
616 bfa_fcs_vport_delete_comp(port->vport);
617 } else {
618 bfa_fcs_fabric_port_delete_comp(port->fabric);
619 }
620}
621
622
623
624/**
625 * fcs_lport_api BFA FCS port API
626 */
627/**
628 * Module initialization
629 */
630void
631bfa_fcs_port_modinit(struct bfa_fcs_s *fcs)
632{
633
634}
635
636/**
637 * Module cleanup
638 */
639void
640bfa_fcs_port_modexit(struct bfa_fcs_s *fcs)
641{
642 bfa_fcs_modexit_comp(fcs);
643}
644
645/**
646 * Unsolicited frame receive handling.
647 */
648void
649bfa_fcs_port_uf_recv(struct bfa_fcs_port_s *lport, struct fchs_s *fchs,
650 u16 len)
651{
652 u32 pid = fchs->s_id;
653 struct bfa_fcs_rport_s *rport = NULL;
654 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
655
656 bfa_stats(lport, uf_recvs);
657
658 if (!bfa_fcs_port_is_online(lport)) {
659 bfa_stats(lport, uf_recv_drops);
660 return;
661 }
662
663 /**
664 * First, handle ELSs that donot require a login.
665 */
666 /*
667 * Handle PLOGI first
668 */
669 if ((fchs->type == FC_TYPE_ELS) &&
670 (els_cmd->els_code == FC_ELS_PLOGI)) {
671 bfa_fcs_port_plogi(lport, fchs, (struct fc_logi_s *) els_cmd);
672 return;
673 }
674
675 /*
676 * Handle ECHO separately.
677 */
678 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) {
679 bfa_fcs_port_echo(lport, fchs,
680 (struct fc_echo_s *) els_cmd, len);
681 return;
682 }
683
684 /*
685 * Handle RNID separately.
686 */
687 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) {
688 bfa_fcs_port_rnid(lport, fchs,
689 (struct fc_rnid_cmd_s *) els_cmd, len);
690 return;
691 }
692
693 /**
694 * look for a matching remote port ID
695 */
696 rport = bfa_fcs_port_get_rport_by_pid(lport, pid);
697 if (rport) {
698 bfa_trc(rport->fcs, fchs->s_id);
699 bfa_trc(rport->fcs, fchs->d_id);
700 bfa_trc(rport->fcs, fchs->type);
701
702 bfa_fcs_rport_uf_recv(rport, fchs, len);
703 return;
704 }
705
706 /**
707 * Only handles ELS frames for now.
708 */
709 if (fchs->type != FC_TYPE_ELS) {
710 bfa_trc(lport->fcs, fchs->type);
711 bfa_assert(0);
712 return;
713 }
714
715 bfa_trc(lport->fcs, els_cmd->els_code);
716 if (els_cmd->els_code == FC_ELS_RSCN) {
717 bfa_fcs_port_scn_process_rscn(lport, fchs, len);
718 return;
719 }
720
721 if (els_cmd->els_code == FC_ELS_LOGO) {
722 /**
723 * @todo Handle LOGO frames received.
724 */
725 bfa_trc(lport->fcs, els_cmd->els_code);
726 return;
727 }
728
729 if (els_cmd->els_code == FC_ELS_PRLI) {
730 /**
731 * @todo Handle PRLI frames received.
732 */
733 bfa_trc(lport->fcs, els_cmd->els_code);
734 return;
735 }
736
737 /**
738 * Unhandled ELS frames. Send a LS_RJT.
739 */
740 bfa_fcs_port_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP,
741 FC_LS_RJT_EXP_NO_ADDL_INFO);
742
743}
744
745/**
746 * PID based Lookup for a R-Port in the Port R-Port Queue
747 */
748struct bfa_fcs_rport_s *
749bfa_fcs_port_get_rport_by_pid(struct bfa_fcs_port_s *port, u32 pid)
750{
751 struct bfa_fcs_rport_s *rport;
752 struct list_head *qe;
753
754 list_for_each(qe, &port->rport_q) {
755 rport = (struct bfa_fcs_rport_s *)qe;
756 if (rport->pid == pid)
757 return rport;
758 }
759
760 bfa_trc(port->fcs, pid);
761 return NULL;
762}
763
764/**
765 * PWWN based Lookup for a R-Port in the Port R-Port Queue
766 */
767struct bfa_fcs_rport_s *
768bfa_fcs_port_get_rport_by_pwwn(struct bfa_fcs_port_s *port, wwn_t pwwn)
769{
770 struct bfa_fcs_rport_s *rport;
771 struct list_head *qe;
772
773 list_for_each(qe, &port->rport_q) {
774 rport = (struct bfa_fcs_rport_s *)qe;
775 if (wwn_is_equal(rport->pwwn, pwwn))
776 return rport;
777 }
778
779 bfa_trc(port->fcs, pwwn);
780 return (NULL);
781}
782
783/**
784 * NWWN based Lookup for a R-Port in the Port R-Port Queue
785 */
786struct bfa_fcs_rport_s *
787bfa_fcs_port_get_rport_by_nwwn(struct bfa_fcs_port_s *port, wwn_t nwwn)
788{
789 struct bfa_fcs_rport_s *rport;
790 struct list_head *qe;
791
792 list_for_each(qe, &port->rport_q) {
793 rport = (struct bfa_fcs_rport_s *)qe;
794 if (wwn_is_equal(rport->nwwn, nwwn))
795 return rport;
796 }
797
798 bfa_trc(port->fcs, nwwn);
799 return (NULL);
800}
801
802/**
803 * Called by rport module when new rports are discovered.
804 */
805void
806bfa_fcs_port_add_rport(struct bfa_fcs_port_s *port,
807 struct bfa_fcs_rport_s *rport)
808{
809 list_add_tail(&rport->qe, &port->rport_q);
810 port->num_rports++;
811}
812
813/**
814 * Called by rport module to when rports are deleted.
815 */
816void
817bfa_fcs_port_del_rport(struct bfa_fcs_port_s *port,
818 struct bfa_fcs_rport_s *rport)
819{
820 bfa_assert(bfa_q_is_on_q(&port->rport_q, rport));
821 list_del(&rport->qe);
822 port->num_rports--;
823
824 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT);
825}
826
827/**
828 * Called by fabric for base port when fabric login is complete.
829 * Called by vport for virtual ports when FDISC is complete.
830 */
831void
832bfa_fcs_port_online(struct bfa_fcs_port_s *port)
833{
834 bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE);
835}
836
837/**
838 * Called by fabric for base port when fabric goes offline.
839 * Called by vport for virtual ports when virtual port becomes offline.
840 */
841void
842bfa_fcs_port_offline(struct bfa_fcs_port_s *port)
843{
844 bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE);
845}
846
847/**
848 * Called by fabric to delete base lport and associated resources.
849 *
850 * Called by vport to delete lport and associated resources. Should call
851 * bfa_fcs_vport_delete_comp() for vports on completion.
852 */
853void
854bfa_fcs_port_delete(struct bfa_fcs_port_s *port)
855{
856 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE);
857}
858
859/**
860 * Called by fabric in private loop topology to process LIP event.
861 */
862void
863bfa_fcs_port_lip(struct bfa_fcs_port_s *port)
864{
865}
866
867/**
868 * Return TRUE if port is online, else return FALSE
869 */
870bfa_boolean_t
871bfa_fcs_port_is_online(struct bfa_fcs_port_s *port)
872{
873 return (bfa_sm_cmp_state(port, bfa_fcs_port_sm_online));
874}
875
876/**
877 * Logical port initialization of base or virtual port.
878 * Called by fabric for base port or by vport for virtual ports.
879 */
880void
881bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
882 u16 vf_id, struct bfa_port_cfg_s *port_cfg,
883 struct bfa_fcs_vport_s *vport)
884{
885 lport->fcs = fcs;
886 lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
887 bfa_os_assign(lport->port_cfg, *port_cfg);
888 lport->vport = vport;
889 lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) :
890 bfa_lps_get_tag(lport->fabric->lps);
891
892 INIT_LIST_HEAD(&lport->rport_q);
893 lport->num_rports = 0;
894
895 lport->bfad_port =
896 bfa_fcb_port_new(fcs->bfad, lport, lport->port_cfg.roles,
897 lport->fabric->vf_drv,
898 vport ? vport->vport_drv : NULL);
899 bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW);
900
901 bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit);
902 bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
903}
904
905
906
907/**
908 * fcs_lport_api
909 */
910
911void
912bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port,
913 struct bfa_port_attr_s *port_attr)
914{
915 if (bfa_sm_cmp_state(port, bfa_fcs_port_sm_online))
916 port_attr->pid = port->pid;
917 else
918 port_attr->pid = 0;
919
920 port_attr->port_cfg = port->port_cfg;
921
922 if (port->fabric) {
923 port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric);
924 port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric);
925 port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port);
926 memcpy(port_attr->fabric_ip_addr,
927 bfa_fcs_port_get_fabric_ipaddr(port),
928 BFA_FCS_FABRIC_IPADDR_SZ);
929
930 if (port->vport != NULL)
931 port_attr->port_type = BFA_PPORT_TYPE_VPORT;
932
933 } else {
934 port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN;
935 port_attr->state = BFA_PORT_UNINIT;
936 }
937
938}
939
940
diff --git a/drivers/scsi/bfa/bfa_fcs_port.c b/drivers/scsi/bfa/bfa_fcs_port.c
new file mode 100644
index 000000000000..9c4b24e62de1
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcs_port.c
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcs_pport.c BFA FCS PPORT ( physical port)
20 */
21
22#include <fcs/bfa_fcs.h>
23#include <bfa_svc.h>
24#include <fcs/bfa_fcs_fabric.h>
25#include "fcs_trcmod.h"
26#include "fcs.h"
27#include "fcs_fabric.h"
28#include "fcs_port.h"
29
30BFA_TRC_FILE(FCS, PPORT);
31
32static void
33bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event)
34{
35 struct bfa_fcs_s *fcs = cbarg;
36
37 bfa_trc(fcs, event);
38
39 switch (event) {
40 case BFA_PPORT_LINKUP:
41 bfa_fcs_fabric_link_up(&fcs->fabric);
42 break;
43
44 case BFA_PPORT_LINKDOWN:
45 bfa_fcs_fabric_link_down(&fcs->fabric);
46 break;
47
48 case BFA_PPORT_TRUNK_LINKDOWN:
49 bfa_assert(0);
50 break;
51
52 default:
53 bfa_assert(0);
54 }
55}
56
57void
58bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs)
59{
60 bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler,
61 fcs);
62}
63
64void
65bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs)
66{
67 bfa_fcs_modexit_comp(fcs);
68}
diff --git a/drivers/scsi/bfa/bfa_fcs_uf.c b/drivers/scsi/bfa/bfa_fcs_uf.c
new file mode 100644
index 000000000000..ad01db6444b2
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcs_uf.c
@@ -0,0 +1,105 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcs_uf.c BFA FCS UF ( Unsolicited Frames)
20 */
21
22#include <fcs/bfa_fcs.h>
23#include <bfa_svc.h>
24#include <fcs/bfa_fcs_fabric.h>
25#include "fcs.h"
26#include "fcs_trcmod.h"
27#include "fcs_fabric.h"
28#include "fcs_uf.h"
29
30BFA_TRC_FILE(FCS, UF);
31
32/**
33 * BFA callback for unsolicited frame receive handler.
34 *
35 * @param[in] cbarg callback arg for receive handler
36 * @param[in] uf unsolicited frame descriptor
37 *
38 * @return None
39 */
40static void
41bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
42{
43 struct bfa_fcs_s *fcs = (struct bfa_fcs_s *) cbarg;
44 struct fchs_s *fchs = bfa_uf_get_frmbuf(uf);
45 u16 len = bfa_uf_get_frmlen(uf);
46 struct fc_vft_s *vft;
47 struct bfa_fcs_fabric_s *fabric;
48
49 /**
50 * check for VFT header
51 */
52 if (fchs->routing == FC_RTG_EXT_HDR &&
53 fchs->cat_info == FC_CAT_VFT_HDR) {
54 bfa_stats(fcs, uf.tagged);
55 vft = bfa_uf_get_frmbuf(uf);
56 if (fcs->port_vfid == vft->vf_id)
57 fabric = &fcs->fabric;
58 else
59 fabric = bfa_fcs_vf_lookup(fcs, (u16) vft->vf_id);
60
61 /**
62 * drop frame if vfid is unknown
63 */
64 if (!fabric) {
65 bfa_assert(0);
66 bfa_stats(fcs, uf.vfid_unknown);
67 bfa_uf_free(uf);
68 return;
69 }
70
71 /**
72 * skip vft header
73 */
74 fchs = (struct fchs_s *) (vft + 1);
75 len -= sizeof(struct fc_vft_s);
76
77 bfa_trc(fcs, vft->vf_id);
78 } else {
79 bfa_stats(fcs, uf.untagged);
80 fabric = &fcs->fabric;
81 }
82
83 bfa_trc(fcs, ((u32 *) fchs)[0]);
84 bfa_trc(fcs, ((u32 *) fchs)[1]);
85 bfa_trc(fcs, ((u32 *) fchs)[2]);
86 bfa_trc(fcs, ((u32 *) fchs)[3]);
87 bfa_trc(fcs, ((u32 *) fchs)[4]);
88 bfa_trc(fcs, ((u32 *) fchs)[5]);
89 bfa_trc(fcs, len);
90
91 bfa_fcs_fabric_uf_recv(fabric, fchs, len);
92 bfa_uf_free(uf);
93}
94
95void
96bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs)
97{
98 bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);
99}
100
101void
102bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs)
103{
104 bfa_fcs_modexit_comp(fcs);
105}
diff --git a/drivers/scsi/bfa/bfa_fcxp.c b/drivers/scsi/bfa/bfa_fcxp.c
new file mode 100644
index 000000000000..4754a0e9006a
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcxp.c
@@ -0,0 +1,782 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19#include <bfi/bfi_uf.h>
20#include <cs/bfa_debug.h>
21
22BFA_TRC_FILE(HAL, FCXP);
23BFA_MODULE(fcxp);
24
25/**
26 * forward declarations
27 */
28static void __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete);
29static void hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
30 struct bfi_fcxp_send_rsp_s *fcxp_rsp);
31static void hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen,
32 struct bfa_fcxp_s *fcxp, struct fchs_s *fchs);
33static void bfa_fcxp_qresume(void *cbarg);
34static void bfa_fcxp_queue(struct bfa_fcxp_s *fcxp,
35 struct bfi_fcxp_send_req_s *send_req);
36
37/**
38 * fcxp_pvt BFA FCXP private functions
39 */
40
41static void
42claim_fcxp_req_rsp_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
43{
44 u8 *dm_kva = NULL;
45 u64 dm_pa;
46 u32 buf_pool_sz;
47
48 dm_kva = bfa_meminfo_dma_virt(mi);
49 dm_pa = bfa_meminfo_dma_phys(mi);
50
51 buf_pool_sz = mod->req_pld_sz * mod->num_fcxps;
52
53 /*
54 * Initialize the fcxp req payload list
55 */
56 mod->req_pld_list_kva = dm_kva;
57 mod->req_pld_list_pa = dm_pa;
58 dm_kva += buf_pool_sz;
59 dm_pa += buf_pool_sz;
60 bfa_os_memset(mod->req_pld_list_kva, 0, buf_pool_sz);
61
62 /*
63 * Initialize the fcxp rsp payload list
64 */
65 buf_pool_sz = mod->rsp_pld_sz * mod->num_fcxps;
66 mod->rsp_pld_list_kva = dm_kva;
67 mod->rsp_pld_list_pa = dm_pa;
68 dm_kva += buf_pool_sz;
69 dm_pa += buf_pool_sz;
70 bfa_os_memset(mod->rsp_pld_list_kva, 0, buf_pool_sz);
71
72 bfa_meminfo_dma_virt(mi) = dm_kva;
73 bfa_meminfo_dma_phys(mi) = dm_pa;
74}
75
76static void
77claim_fcxps_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
78{
79 u16 i;
80 struct bfa_fcxp_s *fcxp;
81
82 fcxp = (struct bfa_fcxp_s *) bfa_meminfo_kva(mi);
83 bfa_os_memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps);
84
85 INIT_LIST_HEAD(&mod->fcxp_free_q);
86 INIT_LIST_HEAD(&mod->fcxp_active_q);
87
88 mod->fcxp_list = fcxp;
89
90 for (i = 0; i < mod->num_fcxps; i++) {
91 fcxp->fcxp_mod = mod;
92 fcxp->fcxp_tag = i;
93
94 list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
95 bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp);
96 fcxp->reqq_waiting = BFA_FALSE;
97
98 fcxp = fcxp + 1;
99 }
100
101 bfa_meminfo_kva(mi) = (void *)fcxp;
102}
103
104static void
105bfa_fcxp_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
106 u32 *dm_len)
107{
108 u16 num_fcxp_reqs = cfg->fwcfg.num_fcxp_reqs;
109
110 if (num_fcxp_reqs == 0)
111 return;
112
113 /*
114 * Account for req/rsp payload
115 */
116 *dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs;
117 if (cfg->drvcfg.min_cfg)
118 *dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs;
119 else
120 *dm_len += BFA_FCXP_MAX_LBUF_SZ * num_fcxp_reqs;
121
122 /*
123 * Account for fcxp structs
124 */
125 *ndm_len += sizeof(struct bfa_fcxp_s) * num_fcxp_reqs;
126}
127
128static void
129bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
130 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
131{
132 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
133
134 bfa_os_memset(mod, 0, sizeof(struct bfa_fcxp_mod_s));
135 mod->bfa = bfa;
136 mod->num_fcxps = cfg->fwcfg.num_fcxp_reqs;
137
138 /**
139 * Initialize FCXP request and response payload sizes.
140 */
141 mod->req_pld_sz = mod->rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ;
142 if (!cfg->drvcfg.min_cfg)
143 mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ;
144
145 INIT_LIST_HEAD(&mod->wait_q);
146
147 claim_fcxp_req_rsp_mem(mod, meminfo);
148 claim_fcxps_mem(mod, meminfo);
149}
150
151static void
152bfa_fcxp_initdone(struct bfa_s *bfa)
153{
154}
155
156static void
157bfa_fcxp_detach(struct bfa_s *bfa)
158{
159}
160
161static void
162bfa_fcxp_start(struct bfa_s *bfa)
163{
164}
165
166static void
167bfa_fcxp_stop(struct bfa_s *bfa)
168{
169}
170
171static void
172bfa_fcxp_iocdisable(struct bfa_s *bfa)
173{
174 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
175 struct bfa_fcxp_s *fcxp;
176 struct list_head *qe, *qen;
177
178 list_for_each_safe(qe, qen, &mod->fcxp_active_q) {
179 fcxp = (struct bfa_fcxp_s *) qe;
180 if (fcxp->caller == NULL) {
181 fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
182 BFA_STATUS_IOC_FAILURE, 0, 0, NULL);
183 bfa_fcxp_free(fcxp);
184 } else {
185 fcxp->rsp_status = BFA_STATUS_IOC_FAILURE;
186 bfa_cb_queue(bfa, &fcxp->hcb_qe,
187 __bfa_fcxp_send_cbfn, fcxp);
188 }
189 }
190}
191
192static struct bfa_fcxp_s *
193bfa_fcxp_get(struct bfa_fcxp_mod_s *fm)
194{
195 struct bfa_fcxp_s *fcxp;
196
197 bfa_q_deq(&fm->fcxp_free_q, &fcxp);
198
199 if (fcxp)
200 list_add_tail(&fcxp->qe, &fm->fcxp_active_q);
201
202 return (fcxp);
203}
204
205static void
206bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
207{
208 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
209 struct bfa_fcxp_wqe_s *wqe;
210
211 bfa_q_deq(&mod->wait_q, &wqe);
212 if (wqe) {
213 bfa_trc(mod->bfa, fcxp->fcxp_tag);
214 wqe->alloc_cbfn(wqe->alloc_cbarg, fcxp);
215 return;
216 }
217
218 bfa_assert(bfa_q_is_on_q(&mod->fcxp_active_q, fcxp));
219 list_del(&fcxp->qe);
220 list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
221}
222
223static void
224bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg,
225 bfa_status_t req_status, u32 rsp_len,
226 u32 resid_len, struct fchs_s *rsp_fchs)
227{
228 /**discarded fcxp completion */
229}
230
231static void
232__bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete)
233{
234 struct bfa_fcxp_s *fcxp = cbarg;
235
236 if (complete) {
237 fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
238 fcxp->rsp_status, fcxp->rsp_len,
239 fcxp->residue_len, &fcxp->rsp_fchs);
240 } else {
241 bfa_fcxp_free(fcxp);
242 }
243}
244
245static void
246hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp)
247{
248 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
249 struct bfa_fcxp_s *fcxp;
250 u16 fcxp_tag = bfa_os_ntohs(fcxp_rsp->fcxp_tag);
251
252 bfa_trc(bfa, fcxp_tag);
253
254 fcxp_rsp->rsp_len = bfa_os_ntohl(fcxp_rsp->rsp_len);
255
256 /**
257 * @todo f/w should not set residue to non-0 when everything
258 * is received.
259 */
260 if (fcxp_rsp->req_status == BFA_STATUS_OK)
261 fcxp_rsp->residue_len = 0;
262 else
263 fcxp_rsp->residue_len = bfa_os_ntohl(fcxp_rsp->residue_len);
264
265 fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag);
266
267 bfa_assert(fcxp->send_cbfn != NULL);
268
269 hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp);
270
271 if (fcxp->send_cbfn != NULL) {
272 if (fcxp->caller == NULL) {
273 bfa_trc(mod->bfa, fcxp->fcxp_tag);
274
275 fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
276 fcxp_rsp->req_status, fcxp_rsp->rsp_len,
277 fcxp_rsp->residue_len, &fcxp_rsp->fchs);
278 /*
279 * fcxp automatically freed on return from the callback
280 */
281 bfa_fcxp_free(fcxp);
282 } else {
283 bfa_trc(mod->bfa, fcxp->fcxp_tag);
284 fcxp->rsp_status = fcxp_rsp->req_status;
285 fcxp->rsp_len = fcxp_rsp->rsp_len;
286 fcxp->residue_len = fcxp_rsp->residue_len;
287 fcxp->rsp_fchs = fcxp_rsp->fchs;
288
289 bfa_cb_queue(bfa, &fcxp->hcb_qe,
290 __bfa_fcxp_send_cbfn, fcxp);
291 }
292 } else {
293 bfa_trc(bfa, fcxp_tag);
294 }
295}
296
297static void
298hal_fcxp_set_local_sges(struct bfi_sge_s *sge, u32 reqlen, u64 req_pa)
299{
300 union bfi_addr_u sga_zero = { {0} };
301
302 sge->sg_len = reqlen;
303 sge->flags = BFI_SGE_DATA_LAST;
304 bfa_dma_addr_set(sge[0].sga, req_pa);
305 bfa_sge_to_be(sge);
306 sge++;
307
308 sge->sga = sga_zero;
309 sge->sg_len = reqlen;
310 sge->flags = BFI_SGE_PGDLEN;
311 bfa_sge_to_be(sge);
312}
313
314static void
315hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp,
316 struct fchs_s *fchs)
317{
318 /*
319 * TODO: TX ox_id
320 */
321 if (reqlen > 0) {
322 if (fcxp->use_ireqbuf) {
323 u32 pld_w0 =
324 *((u32 *) BFA_FCXP_REQ_PLD(fcxp));
325
326 bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
327 BFA_PL_EID_TX,
328 reqlen + sizeof(struct fchs_s), fchs, pld_w0);
329 } else {
330 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
331 BFA_PL_EID_TX, reqlen + sizeof(struct fchs_s),
332 fchs);
333 }
334 } else {
335 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX,
336 reqlen + sizeof(struct fchs_s), fchs);
337 }
338}
339
340static void
341hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
342 struct bfi_fcxp_send_rsp_s *fcxp_rsp)
343{
344 if (fcxp_rsp->rsp_len > 0) {
345 if (fcxp->use_irspbuf) {
346 u32 pld_w0 =
347 *((u32 *) BFA_FCXP_RSP_PLD(fcxp));
348
349 bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
350 BFA_PL_EID_RX,
351 (u16) fcxp_rsp->rsp_len,
352 &fcxp_rsp->fchs, pld_w0);
353 } else {
354 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
355 BFA_PL_EID_RX,
356 (u16) fcxp_rsp->rsp_len,
357 &fcxp_rsp->fchs);
358 }
359 } else {
360 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_RX,
361 (u16) fcxp_rsp->rsp_len, &fcxp_rsp->fchs);
362 }
363}
364
365/**
366 * Handler to resume sending fcxp when space in available in cpe queue.
367 */
368static void
369bfa_fcxp_qresume(void *cbarg)
370{
371 struct bfa_fcxp_s *fcxp = cbarg;
372 struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
373 struct bfi_fcxp_send_req_s *send_req;
374
375 fcxp->reqq_waiting = BFA_FALSE;
376 send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
377 bfa_fcxp_queue(fcxp, send_req);
378}
379
380/**
381 * Queue fcxp send request to foimrware.
382 */
383static void
384bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
385{
386 struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
387 struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info;
388 struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info;
389 struct bfa_rport_s *rport = reqi->bfa_rport;
390
391 bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ,
392 bfa_lpuid(bfa));
393
394 send_req->fcxp_tag = bfa_os_htons(fcxp->fcxp_tag);
395 if (rport) {
396 send_req->rport_fw_hndl = rport->fw_handle;
397 send_req->max_frmsz = bfa_os_htons(rport->rport_info.max_frmsz);
398 if (send_req->max_frmsz == 0)
399 send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
400 } else {
401 send_req->rport_fw_hndl = 0;
402 send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
403 }
404
405 send_req->vf_id = bfa_os_htons(reqi->vf_id);
406 send_req->lp_tag = reqi->lp_tag;
407 send_req->class = reqi->class;
408 send_req->rsp_timeout = rspi->rsp_timeout;
409 send_req->cts = reqi->cts;
410 send_req->fchs = reqi->fchs;
411
412 send_req->req_len = bfa_os_htonl(reqi->req_tot_len);
413 send_req->rsp_maxlen = bfa_os_htonl(rspi->rsp_maxlen);
414
415 /*
416 * setup req sgles
417 */
418 if (fcxp->use_ireqbuf == 1) {
419 hal_fcxp_set_local_sges(send_req->req_sge, reqi->req_tot_len,
420 BFA_FCXP_REQ_PLD_PA(fcxp));
421 } else {
422 if (fcxp->nreq_sgles > 0) {
423 bfa_assert(fcxp->nreq_sgles == 1);
424 hal_fcxp_set_local_sges(send_req->req_sge,
425 reqi->req_tot_len,
426 fcxp->req_sga_cbfn(fcxp->caller,
427 0));
428 } else {
429 bfa_assert(reqi->req_tot_len == 0);
430 hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
431 }
432 }
433
434 /*
435 * setup rsp sgles
436 */
437 if (fcxp->use_irspbuf == 1) {
438 bfa_assert(rspi->rsp_maxlen <= BFA_FCXP_MAX_LBUF_SZ);
439
440 hal_fcxp_set_local_sges(send_req->rsp_sge, rspi->rsp_maxlen,
441 BFA_FCXP_RSP_PLD_PA(fcxp));
442
443 } else {
444 if (fcxp->nrsp_sgles > 0) {
445 bfa_assert(fcxp->nrsp_sgles == 1);
446 hal_fcxp_set_local_sges(send_req->rsp_sge,
447 rspi->rsp_maxlen,
448 fcxp->rsp_sga_cbfn(fcxp->caller,
449 0));
450 } else {
451 bfa_assert(rspi->rsp_maxlen == 0);
452 hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
453 }
454 }
455
456 hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs);
457
458 bfa_reqq_produce(bfa, BFA_REQQ_FCXP);
459
460 bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP));
461 bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP));
462}
463
464
465/**
466 * hal_fcxp_api BFA FCXP API
467 */
468
469/**
470 * Allocate an FCXP instance to send a response or to send a request
471 * that has a response. Request/response buffers are allocated by caller.
472 *
473 * @param[in] bfa BFA bfa instance
474 * @param[in] nreq_sgles Number of SG elements required for request
475 * buffer. 0, if fcxp internal buffers are used.
476 * Use bfa_fcxp_get_reqbuf() to get the
477 * internal req buffer.
478 * @param[in] req_sgles SG elements describing request buffer. Will be
479 * copied in by BFA and hence can be freed on
480 * return from this function.
481 * @param[in] get_req_sga function ptr to be called to get a request SG
482 * Address (given the sge index).
483 * @param[in] get_req_sglen function ptr to be called to get a request SG
484 * len (given the sge index).
485 * @param[in] get_rsp_sga function ptr to be called to get a response SG
486 * Address (given the sge index).
487 * @param[in] get_rsp_sglen function ptr to be called to get a response SG
488 * len (given the sge index).
489 *
490 * @return FCXP instance. NULL on failure.
491 */
492struct bfa_fcxp_s *
493bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
494 int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
495 bfa_fcxp_get_sglen_t req_sglen_cbfn,
496 bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
497 bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
498{
499 struct bfa_fcxp_s *fcxp = NULL;
500 u32 nreq_sgpg, nrsp_sgpg;
501
502 bfa_assert(bfa != NULL);
503
504 fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa));
505 if (fcxp == NULL)
506 return (NULL);
507
508 bfa_trc(bfa, fcxp->fcxp_tag);
509
510 fcxp->caller = caller;
511
512 if (nreq_sgles == 0) {
513 fcxp->use_ireqbuf = 1;
514 } else {
515 bfa_assert(req_sga_cbfn != NULL);
516 bfa_assert(req_sglen_cbfn != NULL);
517
518 fcxp->use_ireqbuf = 0;
519 fcxp->req_sga_cbfn = req_sga_cbfn;
520 fcxp->req_sglen_cbfn = req_sglen_cbfn;
521
522 fcxp->nreq_sgles = nreq_sgles;
523
524 /*
525 * alloc required sgpgs
526 */
527 if (nreq_sgles > BFI_SGE_INLINE) {
528 nreq_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
529
530 if (bfa_sgpg_malloc
531 (bfa, &fcxp->req_sgpg_q, nreq_sgpg)
532 != BFA_STATUS_OK) {
533 /* bfa_sgpg_wait(bfa, &fcxp->req_sgpg_wqe,
534 nreq_sgpg); */
535 /*
536 * TODO
537 */
538 }
539 }
540 }
541
542 if (nrsp_sgles == 0) {
543 fcxp->use_irspbuf = 1;
544 } else {
545 bfa_assert(rsp_sga_cbfn != NULL);
546 bfa_assert(rsp_sglen_cbfn != NULL);
547
548 fcxp->use_irspbuf = 0;
549 fcxp->rsp_sga_cbfn = rsp_sga_cbfn;
550 fcxp->rsp_sglen_cbfn = rsp_sglen_cbfn;
551
552 fcxp->nrsp_sgles = nrsp_sgles;
553 /*
554 * alloc required sgpgs
555 */
556 if (nrsp_sgles > BFI_SGE_INLINE) {
557 nrsp_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
558
559 if (bfa_sgpg_malloc
560 (bfa, &fcxp->rsp_sgpg_q, nrsp_sgpg)
561 != BFA_STATUS_OK) {
562 /* bfa_sgpg_wait(bfa, &fcxp->rsp_sgpg_wqe,
563 nrsp_sgpg); */
564 /*
565 * TODO
566 */
567 }
568 }
569 }
570
571 return (fcxp);
572}
573
574/**
575 * Get the internal request buffer pointer
576 *
577 * @param[in] fcxp BFA fcxp pointer
578 *
579 * @return pointer to the internal request buffer
580 */
581void *
582bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp)
583{
584 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
585 void *reqbuf;
586
587 bfa_assert(fcxp->use_ireqbuf == 1);
588 reqbuf = ((u8 *)mod->req_pld_list_kva) +
589 fcxp->fcxp_tag * mod->req_pld_sz;
590 return reqbuf;
591}
592
593u32
594bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp)
595{
596 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
597
598 return mod->req_pld_sz;
599}
600
601/**
602 * Get the internal response buffer pointer
603 *
604 * @param[in] fcxp BFA fcxp pointer
605 *
606 * @return pointer to the internal request buffer
607 */
608void *
609bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
610{
611 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
612 void *rspbuf;
613
614 bfa_assert(fcxp->use_irspbuf == 1);
615
616 rspbuf = ((u8 *)mod->rsp_pld_list_kva) +
617 fcxp->fcxp_tag * mod->rsp_pld_sz;
618 return rspbuf;
619}
620
621/**
622 * Free the BFA FCXP
623 *
624 * @param[in] fcxp BFA fcxp pointer
625 *
626 * @return void
627 */
628void
629bfa_fcxp_free(struct bfa_fcxp_s *fcxp)
630{
631 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
632
633 bfa_assert(fcxp != NULL);
634 bfa_trc(mod->bfa, fcxp->fcxp_tag);
635 bfa_fcxp_put(fcxp);
636}
637
638/**
639 * Send a FCXP request
640 *
641 * @param[in] fcxp BFA fcxp pointer
642 * @param[in] rport BFA rport pointer. Could be left NULL for WKA rports
643 * @param[in] vf_id virtual Fabric ID
644 * @param[in] lp_tag lport tag
645 * @param[in] cts use Continous sequence
646 * @param[in] cos fc Class of Service
647 * @param[in] reqlen request length, does not include FCHS length
648 * @param[in] fchs fc Header Pointer. The header content will be copied
649 * in by BFA.
650 *
651 * @param[in] cbfn call back function to be called on receiving
652 * the response
653 * @param[in] cbarg arg for cbfn
654 * @param[in] rsp_timeout
655 * response timeout
656 *
657 * @return bfa_status_t
658 */
659void
660bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
661 u16 vf_id, u8 lp_tag, bfa_boolean_t cts, enum fc_cos cos,
662 u32 reqlen, struct fchs_s *fchs, bfa_cb_fcxp_send_t cbfn,
663 void *cbarg, u32 rsp_maxlen, u8 rsp_timeout)
664{
665 struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
666 struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info;
667 struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info;
668 struct bfi_fcxp_send_req_s *send_req;
669
670 bfa_trc(bfa, fcxp->fcxp_tag);
671
672 /**
673 * setup request/response info
674 */
675 reqi->bfa_rport = rport;
676 reqi->vf_id = vf_id;
677 reqi->lp_tag = lp_tag;
678 reqi->class = cos;
679 rspi->rsp_timeout = rsp_timeout;
680 reqi->cts = cts;
681 reqi->fchs = *fchs;
682 reqi->req_tot_len = reqlen;
683 rspi->rsp_maxlen = rsp_maxlen;
684 fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp;
685 fcxp->send_cbarg = cbarg;
686
687 /**
688 * If no room in CPE queue, wait for
689 */
690 send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
691 if (!send_req) {
692 bfa_trc(bfa, fcxp->fcxp_tag);
693 fcxp->reqq_waiting = BFA_TRUE;
694 bfa_reqq_wait(bfa, BFA_REQQ_FCXP, &fcxp->reqq_wqe);
695 return;
696 }
697
698 bfa_fcxp_queue(fcxp, send_req);
699}
700
701/**
702 * Abort a BFA FCXP
703 *
704 * @param[in] fcxp BFA fcxp pointer
705 *
706 * @return void
707 */
708bfa_status_t
709bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
710{
711 bfa_assert(0);
712 return (BFA_STATUS_OK);
713}
714
715void
716bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
717 bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg)
718{
719 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
720
721 bfa_assert(list_empty(&mod->fcxp_free_q));
722
723 wqe->alloc_cbfn = alloc_cbfn;
724 wqe->alloc_cbarg = alloc_cbarg;
725 list_add_tail(&wqe->qe, &mod->wait_q);
726}
727
728void
729bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe)
730{
731 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
732
733 bfa_assert(bfa_q_is_on_q(&mod->wait_q, wqe));
734 list_del(&wqe->qe);
735}
736
737void
738bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
739{
740 /**
741 * If waiting for room in request queue, cancel reqq wait
742 * and free fcxp.
743 */
744 if (fcxp->reqq_waiting) {
745 fcxp->reqq_waiting = BFA_FALSE;
746 bfa_reqq_wcancel(&fcxp->reqq_wqe);
747 bfa_fcxp_free(fcxp);
748 return;
749 }
750
751 fcxp->send_cbfn = bfa_fcxp_null_comp;
752}
753
754
755
756/**
757 * hal_fcxp_public BFA FCXP public functions
758 */
759
760void
761bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
762{
763 switch (msg->mhdr.msg_id) {
764 case BFI_FCXP_I2H_SEND_RSP:
765 hal_fcxp_send_comp(bfa, (struct bfi_fcxp_send_rsp_s *) msg);
766 break;
767
768 default:
769 bfa_trc(bfa, msg->mhdr.msg_id);
770 bfa_assert(0);
771 }
772}
773
774u32
775bfa_fcxp_get_maxrsp(struct bfa_s *bfa)
776{
777 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
778
779 return mod->rsp_pld_sz;
780}
781
782
diff --git a/drivers/scsi/bfa/bfa_fcxp_priv.h b/drivers/scsi/bfa/bfa_fcxp_priv.h
new file mode 100644
index 000000000000..4cda49397da0
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcxp_priv.h
@@ -0,0 +1,138 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_FCXP_PRIV_H__
19#define __BFA_FCXP_PRIV_H__
20
21#include <cs/bfa_sm.h>
22#include <protocol/fc.h>
23#include <bfa_svc.h>
24#include <bfi/bfi_fcxp.h>
25
26#define BFA_FCXP_MIN (1)
27#define BFA_FCXP_MAX_IBUF_SZ (2 * 1024 + 256)
28#define BFA_FCXP_MAX_LBUF_SZ (4 * 1024 + 256)
29
30struct bfa_fcxp_mod_s {
31 struct bfa_s *bfa; /* backpointer to BFA */
32 struct bfa_fcxp_s *fcxp_list; /* array of FCXPs */
33 u16 num_fcxps; /* max num FCXP requests */
34 struct list_head fcxp_free_q; /* free FCXPs */
35 struct list_head fcxp_active_q; /* active FCXPs */
36 void *req_pld_list_kva; /* list of FCXP req pld */
37 u64 req_pld_list_pa; /* list of FCXP req pld */
38 void *rsp_pld_list_kva; /* list of FCXP resp pld */
39 u64 rsp_pld_list_pa; /* list of FCXP resp pld */
40 struct list_head wait_q; /* wait queue for free fcxp */
41 u32 req_pld_sz;
42 u32 rsp_pld_sz;
43};
44
45#define BFA_FCXP_MOD(__bfa) (&(__bfa)->modules.fcxp_mod)
46#define BFA_FCXP_FROM_TAG(__mod, __tag) (&(__mod)->fcxp_list[__tag])
47
48typedef void (*fcxp_send_cb_t) (struct bfa_s *ioc, struct bfa_fcxp_s *fcxp,
49 void *cb_arg, bfa_status_t req_status,
50 u32 rsp_len, u32 resid_len,
51 struct fchs_s *rsp_fchs);
52
53/**
54 * Information needed for a FCXP request
55 */
56struct bfa_fcxp_req_info_s {
57 struct bfa_rport_s *bfa_rport; /* Pointer to the bfa rport that was
58 *returned from bfa_rport_create().
59 *This could be left NULL for WKA or for
60 *FCXP interactions before the rport
61 *nexus is established
62 */
63 struct fchs_s fchs; /* request FC header structure */
64 u8 cts; /* continous sequence */
65 u8 class; /* FC class for the request/response */
66 u16 max_frmsz; /* max send frame size */
67 u16 vf_id; /* vsan tag if applicable */
68 u8 lp_tag; /* lport tag */
69 u32 req_tot_len; /* request payload total length */
70};
71
72struct bfa_fcxp_rsp_info_s {
73 struct fchs_s rsp_fchs; /* Response frame's FC header will
74 * be *sent back in this field */
75 u8 rsp_timeout; /* timeout in seconds, 0-no response
76 */
77 u8 rsvd2[3];
78 u32 rsp_maxlen; /* max response length expected */
79};
80
81struct bfa_fcxp_s {
82 struct list_head qe; /* fcxp queue element */
83 bfa_sm_t sm; /* state machine */
84 void *caller; /* driver or fcs */
85 struct bfa_fcxp_mod_s *fcxp_mod;
86 /* back pointer to fcxp mod */
87 u16 fcxp_tag; /* internal tag */
88 struct bfa_fcxp_req_info_s req_info;
89 /* request info */
90 struct bfa_fcxp_rsp_info_s rsp_info;
91 /* response info */
92 u8 use_ireqbuf; /* use internal req buf */
93 u8 use_irspbuf; /* use internal rsp buf */
94 u32 nreq_sgles; /* num request SGLEs */
95 u32 nrsp_sgles; /* num response SGLEs */
96 struct list_head req_sgpg_q; /* SG pages for request buf */
97 struct list_head req_sgpg_wqe; /* wait queue for req SG page */
98 struct list_head rsp_sgpg_q; /* SG pages for response buf */
99 struct list_head rsp_sgpg_wqe; /* wait queue for rsp SG page */
100
101 bfa_fcxp_get_sgaddr_t req_sga_cbfn;
102 /* SG elem addr user function */
103 bfa_fcxp_get_sglen_t req_sglen_cbfn;
104 /* SG elem len user function */
105 bfa_fcxp_get_sgaddr_t rsp_sga_cbfn;
106 /* SG elem addr user function */
107 bfa_fcxp_get_sglen_t rsp_sglen_cbfn;
108 /* SG elem len user function */
109 bfa_cb_fcxp_send_t send_cbfn; /* send completion callback */
110 void *send_cbarg; /* callback arg */
111 struct bfa_sge_s req_sge[BFA_FCXP_MAX_SGES];
112 /* req SG elems */
113 struct bfa_sge_s rsp_sge[BFA_FCXP_MAX_SGES];
114 /* rsp SG elems */
115 u8 rsp_status; /* comp: rsp status */
116 u32 rsp_len; /* comp: actual response len */
117 u32 residue_len; /* comp: residual rsp length */
118 struct fchs_s rsp_fchs; /* comp: response fchs */
119 struct bfa_cb_qe_s hcb_qe; /* comp: callback qelem */
120 struct bfa_reqq_wait_s reqq_wqe;
121 bfa_boolean_t reqq_waiting;
122};
123
124#define BFA_FCXP_REQ_PLD(_fcxp) (bfa_fcxp_get_reqbuf(_fcxp))
125
126#define BFA_FCXP_RSP_FCHS(_fcxp) (&((_fcxp)->rsp_info.fchs))
127#define BFA_FCXP_RSP_PLD(_fcxp) (bfa_fcxp_get_rspbuf(_fcxp))
128
129#define BFA_FCXP_REQ_PLD_PA(_fcxp) \
130 ((_fcxp)->fcxp_mod->req_pld_list_pa + \
131 ((_fcxp)->fcxp_mod->req_pld_sz * (_fcxp)->fcxp_tag))
132
133#define BFA_FCXP_RSP_PLD_PA(_fcxp) \
134 ((_fcxp)->fcxp_mod->rsp_pld_list_pa + \
135 ((_fcxp)->fcxp_mod->rsp_pld_sz * (_fcxp)->fcxp_tag))
136
137void bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
138#endif /* __BFA_FCXP_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_fwimg_priv.h b/drivers/scsi/bfa/bfa_fwimg_priv.h
new file mode 100644
index 000000000000..1ec1355924d9
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fwimg_priv.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_FWIMG_PRIV_H__
19#define __BFA_FWIMG_PRIV_H__
20
21#define BFI_FLASH_CHUNK_SZ 256 /* Flash chunk size */
22#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32))
23
24extern u32 *bfi_image_ct_get_chunk(u32 off);
25extern u32 bfi_image_ct_size;
26extern u32 *bfi_image_cb_get_chunk(u32 off);
27extern u32 bfi_image_cb_size;
28extern u32 *bfi_image_cb;
29extern u32 *bfi_image_ct;
30
31#endif /* __BFA_FWIMG_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c
new file mode 100644
index 000000000000..ede1438619e2
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_hw_cb.c
@@ -0,0 +1,142 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa_priv.h>
19#include <bfi/bfi_cbreg.h>
20
21void
22bfa_hwcb_reginit(struct bfa_s *bfa)
23{
24 struct bfa_iocfc_regs_s *bfa_regs = &bfa->iocfc.bfa_regs;
25 bfa_os_addr_t kva = bfa_ioc_bar0(&bfa->ioc);
26 int i, q, fn = bfa_ioc_pcifn(&bfa->ioc);
27
28 if (fn == 0) {
29 bfa_regs->intr_status = (kva + HOSTFN0_INT_STATUS);
30 bfa_regs->intr_mask = (kva + HOSTFN0_INT_MSK);
31 } else {
32 bfa_regs->intr_status = (kva + HOSTFN1_INT_STATUS);
33 bfa_regs->intr_mask = (kva + HOSTFN1_INT_MSK);
34 }
35
36 for (i = 0; i < BFI_IOC_MAX_CQS; i++) {
37 /*
38 * CPE registers
39 */
40 q = CPE_Q_NUM(fn, i);
41 bfa_regs->cpe_q_pi[i] = (kva + CPE_Q_PI(q));
42 bfa_regs->cpe_q_ci[i] = (kva + CPE_Q_CI(q));
43 bfa_regs->cpe_q_depth[i] = (kva + CPE_Q_DEPTH(q));
44
45 /*
46 * RME registers
47 */
48 q = CPE_Q_NUM(fn, i);
49 bfa_regs->rme_q_pi[i] = (kva + RME_Q_PI(q));
50 bfa_regs->rme_q_ci[i] = (kva + RME_Q_CI(q));
51 bfa_regs->rme_q_depth[i] = (kva + RME_Q_DEPTH(q));
52 }
53}
54
55void
56bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq)
57{
58}
59
60static void
61bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq)
62{
63 bfa_reg_write(bfa->iocfc.bfa_regs.intr_status,
64 __HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq));
65}
66
67void
68bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
69 u32 *num_vecs, u32 *max_vec_bit)
70{
71#define __HFN_NUMINTS 13
72 if (bfa_ioc_pcifn(&bfa->ioc) == 0) {
73 *msix_vecs_bmap = (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
74 __HFN_INT_CPE_Q2 | __HFN_INT_CPE_Q3 |
75 __HFN_INT_RME_Q0 | __HFN_INT_RME_Q1 |
76 __HFN_INT_RME_Q2 | __HFN_INT_RME_Q3 |
77 __HFN_INT_MBOX_LPU0);
78 *max_vec_bit = __HFN_INT_MBOX_LPU0;
79 } else {
80 *msix_vecs_bmap = (__HFN_INT_CPE_Q4 | __HFN_INT_CPE_Q5 |
81 __HFN_INT_CPE_Q6 | __HFN_INT_CPE_Q7 |
82 __HFN_INT_RME_Q4 | __HFN_INT_RME_Q5 |
83 __HFN_INT_RME_Q6 | __HFN_INT_RME_Q7 |
84 __HFN_INT_MBOX_LPU1);
85 *max_vec_bit = __HFN_INT_MBOX_LPU1;
86 }
87
88 *msix_vecs_bmap |= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
89 __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS);
90 *num_vecs = __HFN_NUMINTS;
91}
92
93/**
94 * No special setup required for crossbow -- vector assignments are implicit.
95 */
96void
97bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs)
98{
99 int i;
100
101 bfa_assert((nvecs == 1) || (nvecs == __HFN_NUMINTS));
102
103 bfa->msix.nvecs = nvecs;
104 if (nvecs == 1) {
105 for (i = 0; i < BFA_MSIX_CB_MAX; i++)
106 bfa->msix.handler[i] = bfa_msix_all;
107 return;
108 }
109
110 for (i = BFA_MSIX_CPE_Q0; i <= BFA_MSIX_CPE_Q7; i++)
111 bfa->msix.handler[i] = bfa_msix_reqq;
112
113 for (i = BFA_MSIX_RME_Q0; i <= BFA_MSIX_RME_Q7; i++)
114 bfa->msix.handler[i] = bfa_msix_rspq;
115
116 for (; i < BFA_MSIX_CB_MAX; i++)
117 bfa->msix.handler[i] = bfa_msix_lpu_err;
118}
119
120/**
121 * Crossbow -- dummy, interrupts are masked
122 */
123void
124bfa_hwcb_msix_install(struct bfa_s *bfa)
125{
126}
127
128void
129bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
130{
131}
132
133/**
134 * No special enable/disable -- vector assignments are implicit.
135 */
136void
137bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
138{
139 bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
140}
141
142
diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c
new file mode 100644
index 000000000000..51ae5740e6e9
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_hw_ct.c
@@ -0,0 +1,162 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa_priv.h>
19#include <bfi/bfi_ctreg.h>
20#include <bfa_ioc.h>
21
22BFA_TRC_FILE(HAL, IOCFC_CT);
23
24static u32 __ct_msix_err_vec_reg[] = {
25 HOST_MSIX_ERR_INDEX_FN0,
26 HOST_MSIX_ERR_INDEX_FN1,
27 HOST_MSIX_ERR_INDEX_FN2,
28 HOST_MSIX_ERR_INDEX_FN3,
29};
30
31static void
32bfa_hwct_msix_lpu_err_set(struct bfa_s *bfa, bfa_boolean_t msix, int vec)
33{
34 int fn = bfa_ioc_pcifn(&bfa->ioc);
35 bfa_os_addr_t kva = bfa_ioc_bar0(&bfa->ioc);
36
37 if (msix)
38 bfa_reg_write(kva + __ct_msix_err_vec_reg[fn], vec);
39 else
40 bfa_reg_write(kva + __ct_msix_err_vec_reg[fn], 0);
41}
42
43/**
44 * Dummy interrupt handler for handling spurious interrupt during chip-reinit.
45 */
46static void
47bfa_hwct_msix_dummy(struct bfa_s *bfa, int vec)
48{
49}
50
51void
52bfa_hwct_reginit(struct bfa_s *bfa)
53{
54 struct bfa_iocfc_regs_s *bfa_regs = &bfa->iocfc.bfa_regs;
55 bfa_os_addr_t kva = bfa_ioc_bar0(&bfa->ioc);
56 int i, q, fn = bfa_ioc_pcifn(&bfa->ioc);
57
58 if (fn == 0) {
59 bfa_regs->intr_status = (kva + HOSTFN0_INT_STATUS);
60 bfa_regs->intr_mask = (kva + HOSTFN0_INT_MSK);
61 } else {
62 bfa_regs->intr_status = (kva + HOSTFN1_INT_STATUS);
63 bfa_regs->intr_mask = (kva + HOSTFN1_INT_MSK);
64 }
65
66 for (i = 0; i < BFI_IOC_MAX_CQS; i++) {
67 /*
68 * CPE registers
69 */
70 q = CPE_Q_NUM(fn, i);
71 bfa_regs->cpe_q_pi[i] = (kva + CPE_PI_PTR_Q(q << 5));
72 bfa_regs->cpe_q_ci[i] = (kva + CPE_CI_PTR_Q(q << 5));
73 bfa_regs->cpe_q_depth[i] = (kva + CPE_DEPTH_Q(q << 5));
74 bfa_regs->cpe_q_ctrl[i] = (kva + CPE_QCTRL_Q(q << 5));
75
76 /*
77 * RME registers
78 */
79 q = CPE_Q_NUM(fn, i);
80 bfa_regs->rme_q_pi[i] = (kva + RME_PI_PTR_Q(q << 5));
81 bfa_regs->rme_q_ci[i] = (kva + RME_CI_PTR_Q(q << 5));
82 bfa_regs->rme_q_depth[i] = (kva + RME_DEPTH_Q(q << 5));
83 bfa_regs->rme_q_ctrl[i] = (kva + RME_QCTRL_Q(q << 5));
84 }
85}
86
87void
88bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq)
89{
90 u32 r32;
91
92 r32 = bfa_reg_read(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]);
93 bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq], r32);
94}
95
96void
97bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
98 u32 *num_vecs, u32 *max_vec_bit)
99{
100 *msix_vecs_bmap = (1 << BFA_MSIX_CT_MAX) - 1;
101 *max_vec_bit = (1 << (BFA_MSIX_CT_MAX - 1));
102 *num_vecs = BFA_MSIX_CT_MAX;
103}
104
105/**
106 * Setup MSI-X vector for catapult
107 */
108void
109bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs)
110{
111 bfa_assert((nvecs == 1) || (nvecs == BFA_MSIX_CT_MAX));
112 bfa_trc(bfa, nvecs);
113
114 bfa->msix.nvecs = nvecs;
115 bfa_hwct_msix_uninstall(bfa);
116}
117
118void
119bfa_hwct_msix_install(struct bfa_s *bfa)
120{
121 int i;
122
123 if (bfa->msix.nvecs == 0)
124 return;
125
126 if (bfa->msix.nvecs == 1) {
127 for (i = 0; i < BFA_MSIX_CT_MAX; i++)
128 bfa->msix.handler[i] = bfa_msix_all;
129 return;
130 }
131
132 for (i = BFA_MSIX_CPE_Q0; i <= BFA_MSIX_CPE_Q3; i++)
133 bfa->msix.handler[i] = bfa_msix_reqq;
134
135 for (; i <= BFA_MSIX_RME_Q3; i++)
136 bfa->msix.handler[i] = bfa_msix_rspq;
137
138 bfa_assert(i == BFA_MSIX_LPU_ERR);
139 bfa->msix.handler[BFA_MSIX_LPU_ERR] = bfa_msix_lpu_err;
140}
141
142void
143bfa_hwct_msix_uninstall(struct bfa_s *bfa)
144{
145 int i;
146
147 for (i = 0; i < BFA_MSIX_CT_MAX; i++)
148 bfa->msix.handler[i] = bfa_hwct_msix_dummy;
149}
150
151/**
152 * Enable MSI-X vectors
153 */
154void
155bfa_hwct_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
156{
157 bfa_trc(bfa, 0);
158 bfa_hwct_msix_lpu_err_set(bfa, msix, BFA_MSIX_LPU_ERR);
159 bfa_ioc_isr_mode_set(&bfa->ioc, msix);
160}
161
162
diff --git a/drivers/scsi/bfa/bfa_intr.c b/drivers/scsi/bfa/bfa_intr.c
new file mode 100644
index 000000000000..0ca125712a04
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_intr.c
@@ -0,0 +1,218 @@
1/*
2 * Copyright (c) 2005-2009 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#include <bfa.h>
18#include <bfi/bfi_cbreg.h>
19#include <bfa_port_priv.h>
20#include <bfa_intr_priv.h>
21#include <cs/bfa_debug.h>
22
23BFA_TRC_FILE(HAL, INTR);
24
25static void
26bfa_msix_errint(struct bfa_s *bfa, u32 intr)
27{
28 bfa_ioc_error_isr(&bfa->ioc);
29}
30
31static void
32bfa_msix_lpu(struct bfa_s *bfa)
33{
34 bfa_ioc_mbox_isr(&bfa->ioc);
35}
36
37void
38bfa_msix_all(struct bfa_s *bfa, int vec)
39{
40 bfa_intx(bfa);
41}
42
43/**
44 * hal_intr_api
45 */
46bfa_boolean_t
47bfa_intx(struct bfa_s *bfa)
48{
49 u32 intr, qintr;
50 int queue;
51
52 intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
53 if (!intr)
54 return BFA_FALSE;
55
56 /**
57 * RME completion queue interrupt
58 */
59 qintr = intr & __HFN_INT_RME_MASK;
60 bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, qintr);
61
62 for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue ++) {
63 if (intr & (__HFN_INT_RME_Q0 << queue))
64 bfa_msix_rspq(bfa, queue & (BFI_IOC_MAX_CQS - 1));
65 }
66 intr &= ~qintr;
67 if (!intr)
68 return BFA_TRUE;
69
70 /**
71 * CPE completion queue interrupt
72 */
73 qintr = intr & __HFN_INT_CPE_MASK;
74 bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, qintr);
75
76 for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue++) {
77 if (intr & (__HFN_INT_CPE_Q0 << queue))
78 bfa_msix_reqq(bfa, queue & (BFI_IOC_MAX_CQS - 1));
79 }
80 intr &= ~qintr;
81 if (!intr)
82 return BFA_TRUE;
83
84 bfa_msix_lpu_err(bfa, intr);
85
86 return BFA_TRUE;
87}
88
89void
90bfa_isr_enable(struct bfa_s *bfa)
91{
92 u32 intr_unmask;
93 int pci_func = bfa_ioc_pcifn(&bfa->ioc);
94
95 bfa_trc(bfa, pci_func);
96
97 bfa_msix_install(bfa);
98 intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
99 __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS);
100
101 if (pci_func == 0)
102 intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
103 __HFN_INT_CPE_Q2 | __HFN_INT_CPE_Q3 |
104 __HFN_INT_RME_Q0 | __HFN_INT_RME_Q1 |
105 __HFN_INT_RME_Q2 | __HFN_INT_RME_Q3 |
106 __HFN_INT_MBOX_LPU0);
107 else
108 intr_unmask |= (__HFN_INT_CPE_Q4 | __HFN_INT_CPE_Q5 |
109 __HFN_INT_CPE_Q6 | __HFN_INT_CPE_Q7 |
110 __HFN_INT_RME_Q4 | __HFN_INT_RME_Q5 |
111 __HFN_INT_RME_Q6 | __HFN_INT_RME_Q7 |
112 __HFN_INT_MBOX_LPU1);
113
114 bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr_unmask);
115 bfa_reg_write(bfa->iocfc.bfa_regs.intr_mask, ~intr_unmask);
116 bfa_isr_mode_set(bfa, bfa->msix.nvecs != 0);
117}
118
119void
120bfa_isr_disable(struct bfa_s *bfa)
121{
122 bfa_isr_mode_set(bfa, BFA_FALSE);
123 bfa_reg_write(bfa->iocfc.bfa_regs.intr_mask, -1L);
124 bfa_msix_uninstall(bfa);
125}
126
127void
128bfa_msix_reqq(struct bfa_s *bfa, int qid)
129{
130 struct list_head *waitq, *qe, *qen;
131 struct bfa_reqq_wait_s *wqe;
132
133 qid &= (BFI_IOC_MAX_CQS - 1);
134
135 waitq = bfa_reqq(bfa, qid);
136 list_for_each_safe(qe, qen, waitq) {
137 /**
138 * Callback only as long as there is room in request queue
139 */
140 if (bfa_reqq_full(bfa, qid))
141 break;
142
143 list_del(qe);
144 wqe = (struct bfa_reqq_wait_s *) qe;
145 wqe->qresume(wqe->cbarg);
146 }
147}
148
149void
150bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
151{
152 bfa_trc(bfa, m->mhdr.msg_class);
153 bfa_trc(bfa, m->mhdr.msg_id);
154 bfa_trc(bfa, m->mhdr.mtag.i2htok);
155 bfa_assert(0);
156 bfa_trc_stop(bfa->trcmod);
157}
158
159void
160bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
161{
162 struct bfi_msg_s *m;
163 u32 pi, ci;
164
165 bfa_trc_fp(bfa, rsp_qid);
166
167 rsp_qid &= (BFI_IOC_MAX_CQS - 1);
168
169 bfa->iocfc.hwif.hw_rspq_ack(bfa, rsp_qid);
170
171 ci = bfa_rspq_ci(bfa, rsp_qid);
172 pi = bfa_rspq_pi(bfa, rsp_qid);
173
174 bfa_trc_fp(bfa, ci);
175 bfa_trc_fp(bfa, pi);
176
177 if (bfa->rme_process) {
178 while (ci != pi) {
179 m = bfa_rspq_elem(bfa, rsp_qid, ci);
180 bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX);
181
182 bfa_isrs[m->mhdr.msg_class] (bfa, m);
183
184 CQ_INCR(ci, bfa->iocfc.cfg.drvcfg.num_rspq_elems);
185 }
186 }
187
188 /**
189 * update CI
190 */
191 bfa_rspq_ci(bfa, rsp_qid) = pi;
192 bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[rsp_qid], pi);
193 bfa_os_mmiowb();
194}
195
196void
197bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
198{
199 u32 intr;
200
201 intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
202
203 if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1))
204 bfa_msix_lpu(bfa);
205
206 if (intr & (__HFN_INT_ERR_EMC |
207 __HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 |
208 __HFN_INT_ERR_PSS))
209 bfa_msix_errint(bfa, intr);
210}
211
212void
213bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func)
214{
215 bfa_isrs[mc] = isr_func;
216}
217
218
diff --git a/drivers/scsi/bfa/bfa_intr_priv.h b/drivers/scsi/bfa/bfa_intr_priv.h
new file mode 100644
index 000000000000..8ce6e6b105c8
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_intr_priv.h
@@ -0,0 +1,115 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_INTR_PRIV_H__
19#define __BFA_INTR_PRIV_H__
20
21/**
22 * Message handler
23 */
24typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m);
25void bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m);
26void bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func);
27
28
29#define bfa_reqq_pi(__bfa, __reqq) (__bfa)->iocfc.req_cq_pi[__reqq]
30#define bfa_reqq_ci(__bfa, __reqq) \
31 *(u32 *)((__bfa)->iocfc.req_cq_shadow_ci[__reqq].kva)
32
33#define bfa_reqq_full(__bfa, __reqq) \
34 (((bfa_reqq_pi(__bfa, __reqq) + 1) & \
35 ((__bfa)->iocfc.cfg.drvcfg.num_reqq_elems - 1)) == \
36 bfa_reqq_ci(__bfa, __reqq))
37
38#define bfa_reqq_next(__bfa, __reqq) \
39 (bfa_reqq_full(__bfa, __reqq) ? NULL : \
40 ((void *)((struct bfi_msg_s *)((__bfa)->iocfc.req_cq_ba[__reqq].kva) \
41 + bfa_reqq_pi((__bfa), (__reqq)))))
42
43#define bfa_reqq_produce(__bfa, __reqq) do { \
44 (__bfa)->iocfc.req_cq_pi[__reqq]++; \
45 (__bfa)->iocfc.req_cq_pi[__reqq] &= \
46 ((__bfa)->iocfc.cfg.drvcfg.num_reqq_elems - 1); \
47 bfa_reg_write((__bfa)->iocfc.bfa_regs.cpe_q_pi[__reqq], \
48 (__bfa)->iocfc.req_cq_pi[__reqq]); \
49 bfa_os_mmiowb(); \
50} while (0)
51
52#define bfa_rspq_pi(__bfa, __rspq) \
53 *(u32 *)((__bfa)->iocfc.rsp_cq_shadow_pi[__rspq].kva)
54
55#define bfa_rspq_ci(__bfa, __rspq) (__bfa)->iocfc.rsp_cq_ci[__rspq]
56#define bfa_rspq_elem(__bfa, __rspq, __ci) \
57 &((struct bfi_msg_s *)((__bfa)->iocfc.rsp_cq_ba[__rspq].kva))[__ci]
58
59#define CQ_INCR(__index, __size) \
60 (__index)++; (__index) &= ((__size) - 1)
61
62/**
63 * Queue element to wait for room in request queue. FIFO order is
64 * maintained when fullfilling requests.
65 */
66struct bfa_reqq_wait_s {
67 struct list_head qe;
68 void (*qresume) (void *cbarg);
69 void *cbarg;
70};
71
72/**
73 * Circular queue usage assignments
74 */
75enum {
76 BFA_REQQ_IOC = 0, /* all low-priority IOC msgs */
77 BFA_REQQ_FCXP = 0, /* all FCXP messages */
78 BFA_REQQ_LPS = 0, /* all lport service msgs */
79 BFA_REQQ_PORT = 0, /* all port messages */
80 BFA_REQQ_FLASH = 0, /* for flash module */
81 BFA_REQQ_DIAG = 0, /* for diag module */
82 BFA_REQQ_RPORT = 0, /* all port messages */
83 BFA_REQQ_SBOOT = 0, /* all san boot messages */
84 BFA_REQQ_QOS_LO = 1, /* all low priority IO */
85 BFA_REQQ_QOS_MD = 2, /* all medium priority IO */
86 BFA_REQQ_QOS_HI = 3, /* all high priority IO */
87};
88
89static inline void
90bfa_reqq_winit(struct bfa_reqq_wait_s *wqe, void (*qresume) (void *cbarg),
91 void *cbarg)
92{
93 wqe->qresume = qresume;
94 wqe->cbarg = cbarg;
95}
96
97#define bfa_reqq(__bfa, __reqq) &(__bfa)->reqq_waitq[__reqq]
98
99/**
100 * static inline void
101 * bfa_reqq_wait(struct bfa_s *bfa, int reqq, struct bfa_reqq_wait_s *wqe)
102 */
103#define bfa_reqq_wait(__bfa, __reqq, __wqe) do { \
104 \
105 struct list_head *waitq = bfa_reqq(__bfa, __reqq); \
106 \
107 bfa_assert(((__reqq) < BFI_IOC_MAX_CQS)); \
108 bfa_assert((__wqe)->qresume && (__wqe)->cbarg); \
109 \
110 list_add_tail(&(__wqe)->qe, waitq); \
111} while (0)
112
113#define bfa_reqq_wcancel(__wqe) list_del(&(__wqe)->qe)
114
115#endif /* __BFA_INTR_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
new file mode 100644
index 000000000000..149348934ce3
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -0,0 +1,2382 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19#include <bfa_ioc.h>
20#include <bfa_fwimg_priv.h>
21#include <bfa_trcmod_priv.h>
22#include <cs/bfa_debug.h>
23#include <bfi/bfi_ioc.h>
24#include <bfi/bfi_ctreg.h>
25#include <aen/bfa_aen_ioc.h>
26#include <aen/bfa_aen.h>
27#include <log/bfa_log_hal.h>
28#include <defs/bfa_defs_pci.h>
29
30BFA_TRC_FILE(HAL, IOC);
31
32/**
33 * IOC local definitions
34 */
35#define BFA_IOC_TOV 2000 /* msecs */
36#define BFA_IOC_HB_TOV 1000 /* msecs */
37#define BFA_IOC_HB_FAIL_MAX 4
38#define BFA_IOC_HWINIT_MAX 2
39#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
40#define BFA_IOC_TOV_RECOVER (BFA_IOC_HB_FAIL_MAX * BFA_IOC_HB_TOV \
41 + BFA_IOC_TOV)
42
43#define bfa_ioc_timer_start(__ioc) \
44 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \
45 bfa_ioc_timeout, (__ioc), BFA_IOC_TOV)
46#define bfa_ioc_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->ioc_timer)
47
48#define BFA_DBG_FWTRC_ENTS (BFI_IOC_TRC_ENTS)
49#define BFA_DBG_FWTRC_LEN \
50 (BFA_DBG_FWTRC_ENTS * sizeof(struct bfa_trc_s) + \
51 (sizeof(struct bfa_trc_mod_s) - \
52 BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
53#define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
54#define bfa_ioc_stats(_ioc, _stats) (_ioc)->stats._stats ++
55
56#define BFA_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS)
57#define BFA_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS)
58#define BFA_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
59bfa_boolean_t bfa_auto_recover = BFA_FALSE;
60
61/*
62 * forward declarations
63 */
64static void bfa_ioc_aen_post(struct bfa_ioc_s *bfa,
65 enum bfa_ioc_aen_event event);
66static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
67static void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
68static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc);
69static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
70static void bfa_ioc_timeout(void *ioc);
71static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc);
72static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc);
73static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc);
74static void bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc);
75static void bfa_ioc_hb_stop(struct bfa_ioc_s *ioc);
76static void bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force);
77static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
78static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
79static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
80static bfa_boolean_t bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc);
81static void bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc);
82static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
83static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
84
85/**
86 * bfa_ioc_sm
87 */
88
89/**
90 * IOC state machine events
91 */
92enum ioc_event {
93 IOC_E_ENABLE = 1, /* IOC enable request */
94 IOC_E_DISABLE = 2, /* IOC disable request */
95 IOC_E_TIMEOUT = 3, /* f/w response timeout */
96 IOC_E_FWREADY = 4, /* f/w initialization done */
97 IOC_E_FWRSP_GETATTR = 5, /* IOC get attribute response */
98 IOC_E_FWRSP_ENABLE = 6, /* enable f/w response */
99 IOC_E_FWRSP_DISABLE = 7, /* disable f/w response */
100 IOC_E_HBFAIL = 8, /* heartbeat failure */
101 IOC_E_HWERROR = 9, /* hardware error interrupt */
102 IOC_E_SEMLOCKED = 10, /* h/w semaphore is locked */
103 IOC_E_DETACH = 11, /* driver detach cleanup */
104};
105
106bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event);
107bfa_fsm_state_decl(bfa_ioc, fwcheck, struct bfa_ioc_s, enum ioc_event);
108bfa_fsm_state_decl(bfa_ioc, mismatch, struct bfa_ioc_s, enum ioc_event);
109bfa_fsm_state_decl(bfa_ioc, semwait, struct bfa_ioc_s, enum ioc_event);
110bfa_fsm_state_decl(bfa_ioc, hwinit, struct bfa_ioc_s, enum ioc_event);
111bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event);
112bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event);
113bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event);
114bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc_s, enum ioc_event);
115bfa_fsm_state_decl(bfa_ioc, hbfail, struct bfa_ioc_s, enum ioc_event);
116bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
117bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
118
119static struct bfa_sm_table_s ioc_sm_table[] = {
120 {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET},
121 {BFA_SM(bfa_ioc_sm_fwcheck), BFA_IOC_FWMISMATCH},
122 {BFA_SM(bfa_ioc_sm_mismatch), BFA_IOC_FWMISMATCH},
123 {BFA_SM(bfa_ioc_sm_semwait), BFA_IOC_SEMWAIT},
124 {BFA_SM(bfa_ioc_sm_hwinit), BFA_IOC_HWINIT},
125 {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_HWINIT},
126 {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
127 {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
128 {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL},
129 {BFA_SM(bfa_ioc_sm_hbfail), BFA_IOC_HBFAIL},
130 {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
131 {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
132};
133
134/**
135 * Reset entry actions -- initialize state machine
136 */
137static void
138bfa_ioc_sm_reset_entry(struct bfa_ioc_s *ioc)
139{
140 ioc->retry_count = 0;
141 ioc->auto_recover = bfa_auto_recover;
142}
143
144/**
145 * Beginning state. IOC is in reset state.
146 */
147static void
148bfa_ioc_sm_reset(struct bfa_ioc_s *ioc, enum ioc_event event)
149{
150 bfa_trc(ioc, event);
151
152 switch (event) {
153 case IOC_E_ENABLE:
154 bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
155 break;
156
157 case IOC_E_DISABLE:
158 bfa_ioc_disable_comp(ioc);
159 break;
160
161 case IOC_E_DETACH:
162 break;
163
164 default:
165 bfa_sm_fault(ioc, event);
166 }
167}
168
169/**
170 * Semaphore should be acquired for version check.
171 */
172static void
173bfa_ioc_sm_fwcheck_entry(struct bfa_ioc_s *ioc)
174{
175 bfa_ioc_hw_sem_get(ioc);
176}
177
178/**
179 * Awaiting h/w semaphore to continue with version check.
180 */
181static void
182bfa_ioc_sm_fwcheck(struct bfa_ioc_s *ioc, enum ioc_event event)
183{
184 bfa_trc(ioc, event);
185
186 switch (event) {
187 case IOC_E_SEMLOCKED:
188 if (bfa_ioc_firmware_lock(ioc)) {
189 ioc->retry_count = 0;
190 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
191 } else {
192 bfa_ioc_hw_sem_release(ioc);
193 bfa_fsm_set_state(ioc, bfa_ioc_sm_mismatch);
194 }
195 break;
196
197 case IOC_E_DISABLE:
198 bfa_ioc_disable_comp(ioc);
199 /*
200 * fall through
201 */
202
203 case IOC_E_DETACH:
204 bfa_ioc_hw_sem_get_cancel(ioc);
205 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
206 break;
207
208 case IOC_E_FWREADY:
209 break;
210
211 default:
212 bfa_sm_fault(ioc, event);
213 }
214}
215
216/**
217 * Notify enable completion callback and generate mismatch AEN.
218 */
219static void
220bfa_ioc_sm_mismatch_entry(struct bfa_ioc_s *ioc)
221{
222 /**
223 * Provide enable completion callback and AEN notification only once.
224 */
225 if (ioc->retry_count == 0) {
226 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
227 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_FWMISMATCH);
228 }
229 ioc->retry_count++;
230 bfa_ioc_timer_start(ioc);
231}
232
233/**
234 * Awaiting firmware version match.
235 */
236static void
237bfa_ioc_sm_mismatch(struct bfa_ioc_s *ioc, enum ioc_event event)
238{
239 bfa_trc(ioc, event);
240
241 switch (event) {
242 case IOC_E_TIMEOUT:
243 bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
244 break;
245
246 case IOC_E_DISABLE:
247 bfa_ioc_disable_comp(ioc);
248 /*
249 * fall through
250 */
251
252 case IOC_E_DETACH:
253 bfa_ioc_timer_stop(ioc);
254 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
255 break;
256
257 case IOC_E_FWREADY:
258 break;
259
260 default:
261 bfa_sm_fault(ioc, event);
262 }
263}
264
265/**
266 * Request for semaphore.
267 */
268static void
269bfa_ioc_sm_semwait_entry(struct bfa_ioc_s *ioc)
270{
271 bfa_ioc_hw_sem_get(ioc);
272}
273
274/**
275 * Awaiting semaphore for h/w initialzation.
276 */
277static void
278bfa_ioc_sm_semwait(struct bfa_ioc_s *ioc, enum ioc_event event)
279{
280 bfa_trc(ioc, event);
281
282 switch (event) {
283 case IOC_E_SEMLOCKED:
284 ioc->retry_count = 0;
285 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
286 break;
287
288 case IOC_E_DISABLE:
289 bfa_ioc_hw_sem_get_cancel(ioc);
290 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
291 break;
292
293 default:
294 bfa_sm_fault(ioc, event);
295 }
296}
297
298
299static void
300bfa_ioc_sm_hwinit_entry(struct bfa_ioc_s *ioc)
301{
302 bfa_ioc_timer_start(ioc);
303 bfa_ioc_reset(ioc, BFA_FALSE);
304}
305
306/**
307 * Hardware is being initialized. Interrupts are enabled.
308 * Holding hardware semaphore lock.
309 */
310static void
311bfa_ioc_sm_hwinit(struct bfa_ioc_s *ioc, enum ioc_event event)
312{
313 bfa_trc(ioc, event);
314
315 switch (event) {
316 case IOC_E_FWREADY:
317 bfa_ioc_timer_stop(ioc);
318 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
319 break;
320
321 case IOC_E_HWERROR:
322 bfa_ioc_timer_stop(ioc);
323 /*
324 * fall through
325 */
326
327 case IOC_E_TIMEOUT:
328 ioc->retry_count++;
329 if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
330 bfa_ioc_timer_start(ioc);
331 bfa_ioc_reset(ioc, BFA_TRUE);
332 break;
333 }
334
335 bfa_ioc_hw_sem_release(ioc);
336 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
337 break;
338
339 case IOC_E_DISABLE:
340 bfa_ioc_hw_sem_release(ioc);
341 bfa_ioc_timer_stop(ioc);
342 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
343 break;
344
345 default:
346 bfa_sm_fault(ioc, event);
347 }
348}
349
350
351static void
352bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc)
353{
354 bfa_ioc_timer_start(ioc);
355 bfa_ioc_send_enable(ioc);
356}
357
358/**
359 * Host IOC function is being enabled, awaiting response from firmware.
360 * Semaphore is acquired.
361 */
362static void
363bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
364{
365 bfa_trc(ioc, event);
366
367 switch (event) {
368 case IOC_E_FWRSP_ENABLE:
369 bfa_ioc_timer_stop(ioc);
370 bfa_ioc_hw_sem_release(ioc);
371 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
372 break;
373
374 case IOC_E_HWERROR:
375 bfa_ioc_timer_stop(ioc);
376 /*
377 * fall through
378 */
379
380 case IOC_E_TIMEOUT:
381 ioc->retry_count++;
382 if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
383 bfa_reg_write(ioc->ioc_regs.ioc_fwstate,
384 BFI_IOC_UNINIT);
385 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
386 break;
387 }
388
389 bfa_ioc_hw_sem_release(ioc);
390 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
391 break;
392
393 case IOC_E_DISABLE:
394 bfa_ioc_timer_stop(ioc);
395 bfa_ioc_hw_sem_release(ioc);
396 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
397 break;
398
399 case IOC_E_FWREADY:
400 bfa_ioc_send_enable(ioc);
401 break;
402
403 default:
404 bfa_sm_fault(ioc, event);
405 }
406}
407
408
409static void
410bfa_ioc_sm_getattr_entry(struct bfa_ioc_s *ioc)
411{
412 bfa_ioc_timer_start(ioc);
413 bfa_ioc_send_getattr(ioc);
414}
415
416/**
417 * IOC configuration in progress. Timer is active.
418 */
419static void
420bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
421{
422 bfa_trc(ioc, event);
423
424 switch (event) {
425 case IOC_E_FWRSP_GETATTR:
426 bfa_ioc_timer_stop(ioc);
427 bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
428 break;
429
430 case IOC_E_HWERROR:
431 bfa_ioc_timer_stop(ioc);
432 /*
433 * fall through
434 */
435
436 case IOC_E_TIMEOUT:
437 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
438 break;
439
440 case IOC_E_DISABLE:
441 bfa_ioc_timer_stop(ioc);
442 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
443 break;
444
445 default:
446 bfa_sm_fault(ioc, event);
447 }
448}
449
450
451static void
452bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
453{
454 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
455 bfa_ioc_hb_monitor(ioc);
456 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_ENABLE);
457}
458
459static void
460bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event)
461{
462 bfa_trc(ioc, event);
463
464 switch (event) {
465 case IOC_E_ENABLE:
466 break;
467
468 case IOC_E_DISABLE:
469 bfa_ioc_hb_stop(ioc);
470 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
471 break;
472
473 case IOC_E_HWERROR:
474 case IOC_E_FWREADY:
475 /**
476 * Hard error or IOC recovery by other function.
477 * Treat it same as heartbeat failure.
478 */
479 bfa_ioc_hb_stop(ioc);
480 /*
481 * !!! fall through !!!
482 */
483
484 case IOC_E_HBFAIL:
485 bfa_fsm_set_state(ioc, bfa_ioc_sm_hbfail);
486 break;
487
488 default:
489 bfa_sm_fault(ioc, event);
490 }
491}
492
493
494static void
495bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
496{
497 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_DISABLE);
498 bfa_ioc_timer_start(ioc);
499 bfa_ioc_send_disable(ioc);
500}
501
502/**
503 * IOC is being disabled
504 */
505static void
506bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
507{
508 bfa_trc(ioc, event);
509
510 switch (event) {
511 case IOC_E_HWERROR:
512 case IOC_E_FWRSP_DISABLE:
513 bfa_ioc_timer_stop(ioc);
514 /*
515 * !!! fall through !!!
516 */
517
518 case IOC_E_TIMEOUT:
519 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
520 break;
521
522 default:
523 bfa_sm_fault(ioc, event);
524 }
525}
526
527/**
528 * IOC disable completion entry.
529 */
530static void
531bfa_ioc_sm_disabled_entry(struct bfa_ioc_s *ioc)
532{
533 bfa_ioc_disable_comp(ioc);
534}
535
536static void
537bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event)
538{
539 bfa_trc(ioc, event);
540
541 switch (event) {
542 case IOC_E_ENABLE:
543 bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
544 break;
545
546 case IOC_E_DISABLE:
547 ioc->cbfn->disable_cbfn(ioc->bfa);
548 break;
549
550 case IOC_E_FWREADY:
551 break;
552
553 case IOC_E_DETACH:
554 bfa_ioc_firmware_unlock(ioc);
555 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
556 break;
557
558 default:
559 bfa_sm_fault(ioc, event);
560 }
561}
562
563
564static void
565bfa_ioc_sm_initfail_entry(struct bfa_ioc_s *ioc)
566{
567 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
568 bfa_ioc_timer_start(ioc);
569}
570
571/**
572 * Hardware initialization failed.
573 */
574static void
575bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
576{
577 bfa_trc(ioc, event);
578
579 switch (event) {
580 case IOC_E_DISABLE:
581 bfa_ioc_timer_stop(ioc);
582 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
583 break;
584
585 case IOC_E_DETACH:
586 bfa_ioc_timer_stop(ioc);
587 bfa_ioc_firmware_unlock(ioc);
588 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
589 break;
590
591 case IOC_E_TIMEOUT:
592 bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
593 break;
594
595 default:
596 bfa_sm_fault(ioc, event);
597 }
598}
599
600
601static void
602bfa_ioc_sm_hbfail_entry(struct bfa_ioc_s *ioc)
603{
604 struct list_head *qe;
605 struct bfa_ioc_hbfail_notify_s *notify;
606
607 /**
608 * Mark IOC as failed in hardware and stop firmware.
609 */
610 bfa_ioc_lpu_stop(ioc);
611 bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_HBFAIL);
612
613 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
614 bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
615 /*
616 * Wait for halt to take effect
617 */
618 bfa_reg_read(ioc->ioc_regs.ll_halt);
619 }
620
621 /**
622 * Notify driver and common modules registered for notification.
623 */
624 ioc->cbfn->hbfail_cbfn(ioc->bfa);
625 list_for_each(qe, &ioc->hb_notify_q) {
626 notify = (struct bfa_ioc_hbfail_notify_s *)qe;
627 notify->cbfn(notify->cbarg);
628 }
629
630 /**
631 * Flush any queued up mailbox requests.
632 */
633 bfa_ioc_mbox_hbfail(ioc);
634 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_HBFAIL);
635
636 /**
637 * Trigger auto-recovery after a delay.
638 */
639 if (ioc->auto_recover) {
640 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer,
641 bfa_ioc_timeout, ioc, BFA_IOC_TOV_RECOVER);
642 }
643}
644
645/**
646 * IOC heartbeat failure.
647 */
648static void
649bfa_ioc_sm_hbfail(struct bfa_ioc_s *ioc, enum ioc_event event)
650{
651 bfa_trc(ioc, event);
652
653 switch (event) {
654
655 case IOC_E_ENABLE:
656 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
657 break;
658
659 case IOC_E_DISABLE:
660 if (ioc->auto_recover)
661 bfa_ioc_timer_stop(ioc);
662 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
663 break;
664
665 case IOC_E_TIMEOUT:
666 bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
667 break;
668
669 case IOC_E_FWREADY:
670 /**
671 * Recovery is already initiated by other function.
672 */
673 break;
674
675 default:
676 bfa_sm_fault(ioc, event);
677 }
678}
679
680
681
682/**
683 * bfa_ioc_pvt BFA IOC private functions
684 */
685
686static void
687bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
688{
689 struct list_head *qe;
690 struct bfa_ioc_hbfail_notify_s *notify;
691
692 ioc->cbfn->disable_cbfn(ioc->bfa);
693
694 /**
695 * Notify common modules registered for notification.
696 */
697 list_for_each(qe, &ioc->hb_notify_q) {
698 notify = (struct bfa_ioc_hbfail_notify_s *)qe;
699 notify->cbfn(notify->cbarg);
700 }
701}
702
703static void
704bfa_ioc_sem_timeout(void *ioc_arg)
705{
706 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
707
708 bfa_ioc_hw_sem_get(ioc);
709}
710
711static void
712bfa_ioc_usage_sem_get(struct bfa_ioc_s *ioc)
713{
714 u32 r32;
715 int cnt = 0;
716#define BFA_SEM_SPINCNT 1000
717
718 do {
719 r32 = bfa_reg_read(ioc->ioc_regs.ioc_usage_sem_reg);
720 cnt++;
721 if (cnt > BFA_SEM_SPINCNT)
722 break;
723 } while (r32 != 0);
724 bfa_assert(cnt < BFA_SEM_SPINCNT);
725}
726
727static void
728bfa_ioc_usage_sem_release(struct bfa_ioc_s *ioc)
729{
730 bfa_reg_write(ioc->ioc_regs.ioc_usage_sem_reg, 1);
731}
732
733static void
734bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
735{
736 u32 r32;
737
738 /**
739 * First read to the semaphore register will return 0, subsequent reads
740 * will return 1. Semaphore is released by writing 0 to the register
741 */
742 r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
743 if (r32 == 0) {
744 bfa_fsm_send_event(ioc, IOC_E_SEMLOCKED);
745 return;
746 }
747
748 bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout,
749 ioc, BFA_IOC_TOV);
750}
751
752static void
753bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc)
754{
755 bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1);
756}
757
758static void
759bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc)
760{
761 bfa_timer_stop(&ioc->sem_timer);
762}
763
764/**
765 * Initialize LPU local memory (aka secondary memory / SRAM)
766 */
767static void
768bfa_ioc_lmem_init(struct bfa_ioc_s *ioc)
769{
770 u32 pss_ctl;
771 int i;
772#define PSS_LMEM_INIT_TIME 10000
773
774 pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
775 pss_ctl &= ~__PSS_LMEM_RESET;
776 pss_ctl |= __PSS_LMEM_INIT_EN;
777 pss_ctl |= __PSS_I2C_CLK_DIV(3UL); /* i2c workaround 12.5khz clock */
778 bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
779
780 /**
781 * wait for memory initialization to be complete
782 */
783 i = 0;
784 do {
785 pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
786 i++;
787 } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME));
788
789 /**
790 * If memory initialization is not successful, IOC timeout will catch
791 * such failures.
792 */
793 bfa_assert(pss_ctl & __PSS_LMEM_INIT_DONE);
794 bfa_trc(ioc, pss_ctl);
795
796 pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN);
797 bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
798}
799
800static void
801bfa_ioc_lpu_start(struct bfa_ioc_s *ioc)
802{
803 u32 pss_ctl;
804
805 /**
806 * Take processor out of reset.
807 */
808 pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
809 pss_ctl &= ~__PSS_LPU0_RESET;
810
811 bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
812}
813
814static void
815bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
816{
817 u32 pss_ctl;
818
819 /**
820 * Put processors in reset.
821 */
822 pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
823 pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
824
825 bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
826}
827
828/**
829 * Get driver and firmware versions.
830 */
831static void
832bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
833{
834 u32 pgnum, pgoff;
835 u32 loff = 0;
836 int i;
837 u32 *fwsig = (u32 *) fwhdr;
838
839 pgnum = bfa_ioc_smem_pgnum(ioc, loff);
840 pgoff = bfa_ioc_smem_pgoff(ioc, loff);
841 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
842
843 for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32));
844 i++) {
845 fwsig[i] = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
846 loff += sizeof(u32);
847 }
848}
849
850static u32 *
851bfa_ioc_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
852{
853 if (ioc->ctdev)
854 return bfi_image_ct_get_chunk(off);
855 return bfi_image_cb_get_chunk(off);
856}
857
858static u32
859bfa_ioc_fwimg_get_size(struct bfa_ioc_s *ioc)
860{
861return (ioc->ctdev) ? bfi_image_ct_size : bfi_image_cb_size;
862}
863
864/**
865 * Returns TRUE if same.
866 */
867static bfa_boolean_t
868bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
869{
870 struct bfi_ioc_image_hdr_s *drv_fwhdr;
871 int i;
872
873 drv_fwhdr =
874 (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0);
875
876 for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) {
877 if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) {
878 bfa_trc(ioc, i);
879 bfa_trc(ioc, fwhdr->md5sum[i]);
880 bfa_trc(ioc, drv_fwhdr->md5sum[i]);
881 return BFA_FALSE;
882 }
883 }
884
885 bfa_trc(ioc, fwhdr->md5sum[0]);
886 return BFA_TRUE;
887}
888
889/**
890 * Return true if current running version is valid. Firmware signature and
891 * execution context (driver/bios) must match.
892 */
893static bfa_boolean_t
894bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc)
895{
896 struct bfi_ioc_image_hdr_s fwhdr, *drv_fwhdr;
897
898 /**
899 * If bios/efi boot (flash based) -- return true
900 */
901 if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
902 return BFA_TRUE;
903
904 bfa_ioc_fwver_get(ioc, &fwhdr);
905 drv_fwhdr =
906 (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0);
907
908 if (fwhdr.signature != drv_fwhdr->signature) {
909 bfa_trc(ioc, fwhdr.signature);
910 bfa_trc(ioc, drv_fwhdr->signature);
911 return BFA_FALSE;
912 }
913
914 if (fwhdr.exec != drv_fwhdr->exec) {
915 bfa_trc(ioc, fwhdr.exec);
916 bfa_trc(ioc, drv_fwhdr->exec);
917 return BFA_FALSE;
918 }
919
920 return bfa_ioc_fwver_cmp(ioc, &fwhdr);
921}
922
923/**
924 * Return true if firmware of current driver matches the running firmware.
925 */
926static bfa_boolean_t
927bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc)
928{
929 enum bfi_ioc_state ioc_fwstate;
930 u32 usecnt;
931 struct bfi_ioc_image_hdr_s fwhdr;
932
933 /**
934 * Firmware match check is relevant only for CNA.
935 */
936 if (!ioc->cna)
937 return BFA_TRUE;
938
939 /**
940 * If bios boot (flash based) -- do not increment usage count
941 */
942 if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
943 return BFA_TRUE;
944
945 bfa_ioc_usage_sem_get(ioc);
946 usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
947
948 /**
949 * If usage count is 0, always return TRUE.
950 */
951 if (usecnt == 0) {
952 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
953 bfa_ioc_usage_sem_release(ioc);
954 bfa_trc(ioc, usecnt);
955 return BFA_TRUE;
956 }
957
958 ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
959 bfa_trc(ioc, ioc_fwstate);
960
961 /**
962 * Use count cannot be non-zero and chip in uninitialized state.
963 */
964 bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
965
966 /**
967 * Check if another driver with a different firmware is active
968 */
969 bfa_ioc_fwver_get(ioc, &fwhdr);
970 if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
971 bfa_ioc_usage_sem_release(ioc);
972 bfa_trc(ioc, usecnt);
973 return BFA_FALSE;
974 }
975
976 /**
977 * Same firmware version. Increment the reference count.
978 */
979 usecnt++;
980 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
981 bfa_ioc_usage_sem_release(ioc);
982 bfa_trc(ioc, usecnt);
983 return BFA_TRUE;
984}
985
986static void
987bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc)
988{
989 u32 usecnt;
990
991 /**
992 * Firmware lock is relevant only for CNA.
993 * If bios boot (flash based) -- do not decrement usage count
994 */
995 if (!ioc->cna || (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ))
996 return;
997
998 /**
999 * decrement usage count
1000 */
1001 bfa_ioc_usage_sem_get(ioc);
1002 usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
1003 bfa_assert(usecnt > 0);
1004
1005 usecnt--;
1006 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
1007 bfa_trc(ioc, usecnt);
1008
1009 bfa_ioc_usage_sem_release(ioc);
1010}
1011
1012/**
1013 * Conditionally flush any pending message from firmware at start.
1014 */
1015static void
1016bfa_ioc_msgflush(struct bfa_ioc_s *ioc)
1017{
1018 u32 r32;
1019
1020 r32 = bfa_reg_read(ioc->ioc_regs.lpu_mbox_cmd);
1021 if (r32)
1022 bfa_reg_write(ioc->ioc_regs.lpu_mbox_cmd, 1);
1023}
1024
1025
1026static void
1027bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
1028{
1029 enum bfi_ioc_state ioc_fwstate;
1030 bfa_boolean_t fwvalid;
1031
1032 ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
1033
1034 if (force)
1035 ioc_fwstate = BFI_IOC_UNINIT;
1036
1037 bfa_trc(ioc, ioc_fwstate);
1038
1039 /**
1040 * check if firmware is valid
1041 */
1042 fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ?
1043 BFA_FALSE : bfa_ioc_fwver_valid(ioc);
1044
1045 if (!fwvalid) {
1046 bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id);
1047 return;
1048 }
1049
1050 /**
1051 * If hardware initialization is in progress (initialized by other IOC),
1052 * just wait for an initialization completion interrupt.
1053 */
1054 if (ioc_fwstate == BFI_IOC_INITING) {
1055 bfa_trc(ioc, ioc_fwstate);
1056 ioc->cbfn->reset_cbfn(ioc->bfa);
1057 return;
1058 }
1059
1060 /**
1061 * If IOC function is disabled and firmware version is same,
1062 * just re-enable IOC.
1063 */
1064 if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) {
1065 bfa_trc(ioc, ioc_fwstate);
1066
1067 /**
1068 * When using MSI-X any pending firmware ready event should
1069 * be flushed. Otherwise MSI-X interrupts are not delivered.
1070 */
1071 bfa_ioc_msgflush(ioc);
1072 ioc->cbfn->reset_cbfn(ioc->bfa);
1073 bfa_fsm_send_event(ioc, IOC_E_FWREADY);
1074 return;
1075 }
1076
1077 /**
1078 * Initialize the h/w for any other states.
1079 */
1080 bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id);
1081}
1082
1083static void
1084bfa_ioc_timeout(void *ioc_arg)
1085{
1086 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
1087
1088 bfa_trc(ioc, 0);
1089 bfa_fsm_send_event(ioc, IOC_E_TIMEOUT);
1090}
1091
1092void
1093bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len)
1094{
1095 u32 *msgp = (u32 *) ioc_msg;
1096 u32 i;
1097
1098 bfa_trc(ioc, msgp[0]);
1099 bfa_trc(ioc, len);
1100
1101 bfa_assert(len <= BFI_IOC_MSGLEN_MAX);
1102
1103 /*
1104 * first write msg to mailbox registers
1105 */
1106 for (i = 0; i < len / sizeof(u32); i++)
1107 bfa_reg_write(ioc->ioc_regs.hfn_mbox + i * sizeof(u32),
1108 bfa_os_wtole(msgp[i]));
1109
1110 for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++)
1111 bfa_reg_write(ioc->ioc_regs.hfn_mbox + i * sizeof(u32), 0);
1112
1113 /*
1114 * write 1 to mailbox CMD to trigger LPU event
1115 */
1116 bfa_reg_write(ioc->ioc_regs.hfn_mbox_cmd, 1);
1117 (void)bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
1118}
1119
1120static void
1121bfa_ioc_send_enable(struct bfa_ioc_s *ioc)
1122{
1123 struct bfi_ioc_ctrl_req_s enable_req;
1124
1125 bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
1126 bfa_ioc_portid(ioc));
1127 enable_req.ioc_class = ioc->ioc_mc;
1128 bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1129}
1130
1131static void
1132bfa_ioc_send_disable(struct bfa_ioc_s *ioc)
1133{
1134 struct bfi_ioc_ctrl_req_s disable_req;
1135
1136 bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ,
1137 bfa_ioc_portid(ioc));
1138 bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1139}
1140
1141static void
1142bfa_ioc_send_getattr(struct bfa_ioc_s *ioc)
1143{
1144 struct bfi_ioc_getattr_req_s attr_req;
1145
1146 bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ,
1147 bfa_ioc_portid(ioc));
1148 bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa);
1149 bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req));
1150}
1151
1152static void
1153bfa_ioc_hb_check(void *cbarg)
1154{
1155 struct bfa_ioc_s *ioc = cbarg;
1156 u32 hb_count;
1157
1158 hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
1159 if (ioc->hb_count == hb_count) {
1160 ioc->hb_fail++;
1161 } else {
1162 ioc->hb_count = hb_count;
1163 ioc->hb_fail = 0;
1164 }
1165
1166 if (ioc->hb_fail >= BFA_IOC_HB_FAIL_MAX) {
1167 bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, hb_count);
1168 ioc->hb_fail = 0;
1169 bfa_ioc_recover(ioc);
1170 return;
1171 }
1172
1173 bfa_ioc_mbox_poll(ioc);
1174 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
1175 BFA_IOC_HB_TOV);
1176}
1177
1178static void
1179bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
1180{
1181 ioc->hb_fail = 0;
1182 ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
1183 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
1184 BFA_IOC_HB_TOV);
1185}
1186
1187static void
1188bfa_ioc_hb_stop(struct bfa_ioc_s *ioc)
1189{
1190 bfa_timer_stop(&ioc->ioc_timer);
1191}
1192
1193/**
1194 * Host to LPU mailbox message addresses
1195 */
1196static struct {
1197 u32 hfn_mbox, lpu_mbox, hfn_pgn;
1198} iocreg_fnreg[] = {
1199 {
1200 HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0}, {
1201 HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1}, {
1202 HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2}, {
1203 HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3}
1204};
1205
1206/**
1207 * Host <-> LPU mailbox command/status registers - port 0
1208 */
1209static struct {
1210 u32 hfn, lpu;
1211} iocreg_mbcmd_p0[] = {
1212 {
1213 HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT}, {
1214 HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT}, {
1215 HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT}, {
1216 HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT}
1217};
1218
1219/**
1220 * Host <-> LPU mailbox command/status registers - port 1
1221 */
1222static struct {
1223 u32 hfn, lpu;
1224} iocreg_mbcmd_p1[] = {
1225 {
1226 HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT}, {
1227 HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT}, {
1228 HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT}, {
1229 HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT}
1230};
1231
1232/**
1233 * Shared IRQ handling in INTX mode
1234 */
1235static struct {
1236 u32 isr, msk;
1237} iocreg_shirq_next[] = {
1238 {
1239 HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK}, {
1240 HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK}, {
1241 HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK}, {
1242HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},};
1243
1244static void
1245bfa_ioc_reg_init(struct bfa_ioc_s *ioc)
1246{
1247 bfa_os_addr_t rb;
1248 int pcifn = bfa_ioc_pcifn(ioc);
1249
1250 rb = bfa_ioc_bar0(ioc);
1251
1252 ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
1253 ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
1254 ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
1255
1256 if (ioc->port_id == 0) {
1257 ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
1258 ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
1259 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
1260 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
1261 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
1262 } else {
1263 ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
1264 ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
1265 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
1266 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
1267 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
1268 }
1269
1270 /**
1271 * Shared IRQ handling in INTX mode
1272 */
1273 ioc->ioc_regs.shirq_isr_next = rb + iocreg_shirq_next[pcifn].isr;
1274 ioc->ioc_regs.shirq_msk_next = rb + iocreg_shirq_next[pcifn].msk;
1275
1276 /*
1277 * PSS control registers
1278 */
1279 ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
1280 ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
1281 ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
1282
1283 /*
1284 * IOC semaphore registers and serialization
1285 */
1286 ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
1287 ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
1288 ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
1289
1290 /**
1291 * sram memory access
1292 */
1293 ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
1294 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
1295 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT)
1296 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
1297}
1298
1299/**
1300 * Initiate a full firmware download.
1301 */
1302static void
1303bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1304 u32 boot_param)
1305{
1306 u32 *fwimg;
1307 u32 pgnum, pgoff;
1308 u32 loff = 0;
1309 u32 chunkno = 0;
1310 u32 i;
1311
1312 /**
1313 * Initialize LMEM first before code download
1314 */
1315 bfa_ioc_lmem_init(ioc);
1316
1317 /**
1318 * Flash based firmware boot
1319 */
1320 bfa_trc(ioc, bfa_ioc_fwimg_get_size(ioc));
1321 if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
1322 boot_type = BFI_BOOT_TYPE_FLASH;
1323 fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno);
1324 fwimg[BFI_BOOT_TYPE_OFF / sizeof(u32)] = bfa_os_swap32(boot_type);
1325 fwimg[BFI_BOOT_PARAM_OFF / sizeof(u32)] =
1326 bfa_os_swap32(boot_param);
1327
1328 pgnum = bfa_ioc_smem_pgnum(ioc, loff);
1329 pgoff = bfa_ioc_smem_pgoff(ioc, loff);
1330
1331 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
1332
1333 for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) {
1334
1335 if (BFA_FLASH_CHUNK_NO(i) != chunkno) {
1336 chunkno = BFA_FLASH_CHUNK_NO(i);
1337 fwimg = bfa_ioc_fwimg_get_chunk(ioc,
1338 BFA_FLASH_CHUNK_ADDR(chunkno));
1339 }
1340
1341 /**
1342 * write smem
1343 */
1344 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
1345 fwimg[BFA_FLASH_OFFSET_IN_CHUNK(i)]);
1346
1347 loff += sizeof(u32);
1348
1349 /**
1350 * handle page offset wrap around
1351 */
1352 loff = PSS_SMEM_PGOFF(loff);
1353 if (loff == 0) {
1354 pgnum++;
1355 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
1356 }
1357 }
1358
1359 bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
1360 bfa_ioc_smem_pgnum(ioc, 0));
1361}
1362
1363static void
1364bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force)
1365{
1366 bfa_ioc_hwinit(ioc, force);
1367}
1368
1369/**
1370 * Update BFA configuration from firmware configuration.
1371 */
1372static void
1373bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc)
1374{
1375 struct bfi_ioc_attr_s *attr = ioc->attr;
1376
1377 attr->adapter_prop = bfa_os_ntohl(attr->adapter_prop);
1378 attr->maxfrsize = bfa_os_ntohs(attr->maxfrsize);
1379
1380 bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
1381}
1382
1383/**
1384 * Attach time initialization of mbox logic.
1385 */
1386static void
1387bfa_ioc_mbox_attach(struct bfa_ioc_s *ioc)
1388{
1389 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1390 int mc;
1391
1392 INIT_LIST_HEAD(&mod->cmd_q);
1393 for (mc = 0; mc < BFI_MC_MAX; mc++) {
1394 mod->mbhdlr[mc].cbfn = NULL;
1395 mod->mbhdlr[mc].cbarg = ioc->bfa;
1396 }
1397}
1398
1399/**
1400 * Mbox poll timer -- restarts any pending mailbox requests.
1401 */
1402static void
1403bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc)
1404{
1405 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1406 struct bfa_mbox_cmd_s *cmd;
1407 u32 stat;
1408
1409 /**
1410 * If no command pending, do nothing
1411 */
1412 if (list_empty(&mod->cmd_q))
1413 return;
1414
1415 /**
1416 * If previous command is not yet fetched by firmware, do nothing
1417 */
1418 stat = bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
1419 if (stat)
1420 return;
1421
1422 /**
1423 * Enqueue command to firmware.
1424 */
1425 bfa_q_deq(&mod->cmd_q, &cmd);
1426 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
1427}
1428
1429/**
1430 * Cleanup any pending requests.
1431 */
1432static void
1433bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc)
1434{
1435 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1436 struct bfa_mbox_cmd_s *cmd;
1437
1438 while (!list_empty(&mod->cmd_q))
1439 bfa_q_deq(&mod->cmd_q, &cmd);
1440}
1441
1442/**
1443 * Initialize IOC to port mapping.
1444 */
1445
1446#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
1447static void
1448bfa_ioc_map_port(struct bfa_ioc_s *ioc)
1449{
1450 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1451 u32 r32;
1452
1453 /**
1454 * For crossbow, port id is same as pci function.
1455 */
1456 if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT) {
1457 ioc->port_id = bfa_ioc_pcifn(ioc);
1458 return;
1459 }
1460
1461 /**
1462 * For catapult, base port id on personality register and IOC type
1463 */
1464 r32 = bfa_reg_read(rb + FNC_PERS_REG);
1465 r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
1466 ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
1467
1468 bfa_trc(ioc, bfa_ioc_pcifn(ioc));
1469 bfa_trc(ioc, ioc->port_id);
1470}
1471
1472
1473
1474/**
1475 * bfa_ioc_public
1476 */
1477
1478/**
1479* Set interrupt mode for a function: INTX or MSIX
1480 */
1481void
1482bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
1483{
1484 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1485 u32 r32, mode;
1486
1487 r32 = bfa_reg_read(rb + FNC_PERS_REG);
1488 bfa_trc(ioc, r32);
1489
1490 mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
1491 __F0_INTX_STATUS;
1492
1493 /**
1494 * If already in desired mode, do not change anything
1495 */
1496 if (!msix && mode)
1497 return;
1498
1499 if (msix)
1500 mode = __F0_INTX_STATUS_MSIX;
1501 else
1502 mode = __F0_INTX_STATUS_INTA;
1503
1504 r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
1505 r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
1506 bfa_trc(ioc, r32);
1507
1508 bfa_reg_write(rb + FNC_PERS_REG, r32);
1509}
1510
1511bfa_status_t
1512bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
1513{
1514 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1515 u32 pll_sclk, pll_fclk, r32;
1516
1517 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
1518 pll_sclk =
1519 __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
1520 __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) |
1521 __APP_PLL_312_JITLMT0_1(3U) |
1522 __APP_PLL_312_CNTLMT0_1(1U);
1523 pll_fclk =
1524 __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
1525 __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) |
1526 __APP_PLL_425_JITLMT0_1(3U) |
1527 __APP_PLL_425_CNTLMT0_1(1U);
1528
1529 /**
1530 * For catapult, choose operational mode FC/FCoE
1531 */
1532 if (ioc->fcmode) {
1533 bfa_reg_write((rb + OP_MODE), 0);
1534 bfa_reg_write((rb + ETH_MAC_SER_REG),
1535 __APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2
1536 | __APP_EMS_CHANNEL_SEL);
1537 } else {
1538 ioc->pllinit = BFA_TRUE;
1539 bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
1540 bfa_reg_write((rb + ETH_MAC_SER_REG),
1541 __APP_EMS_REFCKBUFEN1);
1542 }
1543 } else {
1544 pll_sclk =
1545 __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
1546 __APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) |
1547 __APP_PLL_312_CNTLMT0_1(3U);
1548 pll_fclk =
1549 __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
1550 __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
1551 __APP_PLL_425_JITLMT0_1(3U) |
1552 __APP_PLL_425_CNTLMT0_1(3U);
1553 }
1554
1555 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
1556 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
1557
1558 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
1559 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
1560 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
1561 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
1562 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
1563 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
1564
1565 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1566 __APP_PLL_312_LOGIC_SOFT_RESET);
1567 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1568 __APP_PLL_312_BYPASS | __APP_PLL_312_LOGIC_SOFT_RESET);
1569 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1570 __APP_PLL_425_LOGIC_SOFT_RESET);
1571 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1572 __APP_PLL_425_BYPASS | __APP_PLL_425_LOGIC_SOFT_RESET);
1573 bfa_os_udelay(2);
1574 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1575 __APP_PLL_312_LOGIC_SOFT_RESET);
1576 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1577 __APP_PLL_425_LOGIC_SOFT_RESET);
1578
1579 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1580 pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET);
1581 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1582 pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET);
1583
1584 /**
1585 * Wait for PLLs to lock.
1586 */
1587 bfa_os_udelay(2000);
1588 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
1589 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
1590
1591 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
1592 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
1593
1594 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
1595 bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
1596 bfa_os_udelay(1000);
1597 r32 = bfa_reg_read((rb + MBIST_STAT_REG));
1598 bfa_trc(ioc, r32);
1599 }
1600
1601 return BFA_STATUS_OK;
1602}
1603
1604/**
1605 * Interface used by diag module to do firmware boot with memory test
1606 * as the entry vector.
1607 */
1608void
1609bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param)
1610{
1611 bfa_os_addr_t rb;
1612
1613 bfa_ioc_stats(ioc, ioc_boots);
1614
1615 if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
1616 return;
1617
1618 /**
1619 * Initialize IOC state of all functions on a chip reset.
1620 */
1621 rb = ioc->pcidev.pci_bar_kva;
1622 if (boot_param == BFI_BOOT_TYPE_MEMTEST) {
1623 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_MEMTEST);
1624 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_MEMTEST);
1625 } else {
1626 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_INITING);
1627 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_INITING);
1628 }
1629
1630 bfa_ioc_download_fw(ioc, boot_type, boot_param);
1631
1632 /**
1633 * Enable interrupts just before starting LPU
1634 */
1635 ioc->cbfn->reset_cbfn(ioc->bfa);
1636 bfa_ioc_lpu_start(ioc);
1637}
1638
1639/**
1640 * Enable/disable IOC failure auto recovery.
1641 */
1642void
1643bfa_ioc_auto_recover(bfa_boolean_t auto_recover)
1644{
1645 bfa_auto_recover = BFA_FALSE;
1646}
1647
1648
1649bfa_boolean_t
1650bfa_ioc_is_operational(struct bfa_ioc_s *ioc)
1651{
1652 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op);
1653}
1654
1655void
1656bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg)
1657{
1658 u32 *msgp = mbmsg;
1659 u32 r32;
1660 int i;
1661
1662 /**
1663 * read the MBOX msg
1664 */
1665 for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32));
1666 i++) {
1667 r32 = bfa_reg_read(ioc->ioc_regs.lpu_mbox +
1668 i * sizeof(u32));
1669 msgp[i] = bfa_os_htonl(r32);
1670 }
1671
1672 /**
1673 * turn off mailbox interrupt by clearing mailbox status
1674 */
1675 bfa_reg_write(ioc->ioc_regs.lpu_mbox_cmd, 1);
1676 bfa_reg_read(ioc->ioc_regs.lpu_mbox_cmd);
1677}
1678
1679void
1680bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
1681{
1682 union bfi_ioc_i2h_msg_u *msg;
1683
1684 msg = (union bfi_ioc_i2h_msg_u *)m;
1685
1686 bfa_ioc_stats(ioc, ioc_isrs);
1687
1688 switch (msg->mh.msg_id) {
1689 case BFI_IOC_I2H_HBEAT:
1690 break;
1691
1692 case BFI_IOC_I2H_READY_EVENT:
1693 bfa_fsm_send_event(ioc, IOC_E_FWREADY);
1694 break;
1695
1696 case BFI_IOC_I2H_ENABLE_REPLY:
1697 bfa_fsm_send_event(ioc, IOC_E_FWRSP_ENABLE);
1698 break;
1699
1700 case BFI_IOC_I2H_DISABLE_REPLY:
1701 bfa_fsm_send_event(ioc, IOC_E_FWRSP_DISABLE);
1702 break;
1703
1704 case BFI_IOC_I2H_GETATTR_REPLY:
1705 bfa_ioc_getattr_reply(ioc);
1706 break;
1707
1708 default:
1709 bfa_trc(ioc, msg->mh.msg_id);
1710 bfa_assert(0);
1711 }
1712}
1713
1714/**
1715 * IOC attach time initialization and setup.
1716 *
1717 * @param[in] ioc memory for IOC
1718 * @param[in] bfa driver instance structure
1719 * @param[in] trcmod kernel trace module
1720 * @param[in] aen kernel aen event module
1721 * @param[in] logm kernel logging module
1722 */
1723void
1724bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn,
1725 struct bfa_timer_mod_s *timer_mod, struct bfa_trc_mod_s *trcmod,
1726 struct bfa_aen_s *aen, struct bfa_log_mod_s *logm)
1727{
1728 ioc->bfa = bfa;
1729 ioc->cbfn = cbfn;
1730 ioc->timer_mod = timer_mod;
1731 ioc->trcmod = trcmod;
1732 ioc->aen = aen;
1733 ioc->logm = logm;
1734 ioc->fcmode = BFA_FALSE;
1735 ioc->pllinit = BFA_FALSE;
1736 ioc->dbg_fwsave_once = BFA_TRUE;
1737
1738 bfa_ioc_mbox_attach(ioc);
1739 INIT_LIST_HEAD(&ioc->hb_notify_q);
1740
1741 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
1742}
1743
1744/**
1745 * Driver detach time IOC cleanup.
1746 */
1747void
1748bfa_ioc_detach(struct bfa_ioc_s *ioc)
1749{
1750 bfa_fsm_send_event(ioc, IOC_E_DETACH);
1751}
1752
1753/**
1754 * Setup IOC PCI properties.
1755 *
1756 * @param[in] pcidev PCI device information for this IOC
1757 */
1758void
1759bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
1760 enum bfi_mclass mc)
1761{
1762 ioc->ioc_mc = mc;
1763 ioc->pcidev = *pcidev;
1764 ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT);
1765 ioc->cna = ioc->ctdev && !ioc->fcmode;
1766
1767 bfa_ioc_map_port(ioc);
1768 bfa_ioc_reg_init(ioc);
1769}
1770
1771/**
1772 * Initialize IOC dma memory
1773 *
1774 * @param[in] dm_kva kernel virtual address of IOC dma memory
1775 * @param[in] dm_pa physical address of IOC dma memory
1776 */
1777void
1778bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa)
1779{
1780 /**
1781 * dma memory for firmware attribute
1782 */
1783 ioc->attr_dma.kva = dm_kva;
1784 ioc->attr_dma.pa = dm_pa;
1785 ioc->attr = (struct bfi_ioc_attr_s *)dm_kva;
1786}
1787
1788/**
1789 * Return size of dma memory required.
1790 */
1791u32
1792bfa_ioc_meminfo(void)
1793{
1794 return BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
1795}
1796
1797void
1798bfa_ioc_enable(struct bfa_ioc_s *ioc)
1799{
1800 bfa_ioc_stats(ioc, ioc_enables);
1801 ioc->dbg_fwsave_once = BFA_TRUE;
1802
1803 bfa_fsm_send_event(ioc, IOC_E_ENABLE);
1804}
1805
1806void
1807bfa_ioc_disable(struct bfa_ioc_s *ioc)
1808{
1809 bfa_ioc_stats(ioc, ioc_disables);
1810 bfa_fsm_send_event(ioc, IOC_E_DISABLE);
1811}
1812
1813/**
1814 * Returns memory required for saving firmware trace in case of crash.
1815 * Driver must call this interface to allocate memory required for
1816 * automatic saving of firmware trace. Driver should call
1817 * bfa_ioc_debug_memclaim() right after bfa_ioc_attach() to setup this
1818 * trace memory.
1819 */
1820int
1821bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover)
1822{
1823return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
1824}
1825
1826/**
1827 * Initialize memory for saving firmware trace. Driver must initialize
1828 * trace memory before call bfa_ioc_enable().
1829 */
1830void
1831bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
1832{
1833 bfa_assert(ioc->auto_recover);
1834 ioc->dbg_fwsave = dbg_fwsave;
1835 ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover);
1836}
1837
1838u32
1839bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr)
1840{
1841 return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr);
1842}
1843
1844u32
1845bfa_ioc_smem_pgoff(struct bfa_ioc_s *ioc, u32 fmaddr)
1846{
1847 return PSS_SMEM_PGOFF(fmaddr);
1848}
1849
1850/**
1851 * Register mailbox message handler functions
1852 *
1853 * @param[in] ioc IOC instance
1854 * @param[in] mcfuncs message class handler functions
1855 */
1856void
1857bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs)
1858{
1859 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1860 int mc;
1861
1862 for (mc = 0; mc < BFI_MC_MAX; mc++)
1863 mod->mbhdlr[mc].cbfn = mcfuncs[mc];
1864}
1865
1866/**
1867 * Register mailbox message handler function, to be called by common modules
1868 */
1869void
1870bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
1871 bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg)
1872{
1873 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1874
1875 mod->mbhdlr[mc].cbfn = cbfn;
1876 mod->mbhdlr[mc].cbarg = cbarg;
1877}
1878
1879/**
1880 * Queue a mailbox command request to firmware. Waits if mailbox is busy.
1881 * Responsibility of caller to serialize
1882 *
1883 * @param[in] ioc IOC instance
1884 * @param[i] cmd Mailbox command
1885 */
1886void
1887bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd)
1888{
1889 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1890 u32 stat;
1891
1892 /**
1893 * If a previous command is pending, queue new command
1894 */
1895 if (!list_empty(&mod->cmd_q)) {
1896 list_add_tail(&cmd->qe, &mod->cmd_q);
1897 return;
1898 }
1899
1900 /**
1901 * If mailbox is busy, queue command for poll timer
1902 */
1903 stat = bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
1904 if (stat) {
1905 list_add_tail(&cmd->qe, &mod->cmd_q);
1906 return;
1907 }
1908
1909 /**
1910 * mailbox is free -- queue command to firmware
1911 */
1912 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
1913}
1914
1915/**
1916 * Handle mailbox interrupts
1917 */
1918void
1919bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc)
1920{
1921 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1922 struct bfi_mbmsg_s m;
1923 int mc;
1924
1925 bfa_ioc_msgget(ioc, &m);
1926
1927 /**
1928 * Treat IOC message class as special.
1929 */
1930 mc = m.mh.msg_class;
1931 if (mc == BFI_MC_IOC) {
1932 bfa_ioc_isr(ioc, &m);
1933 return;
1934 }
1935
1936 if ((mc > BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
1937 return;
1938
1939 mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
1940}
1941
1942void
1943bfa_ioc_error_isr(struct bfa_ioc_s *ioc)
1944{
1945 bfa_fsm_send_event(ioc, IOC_E_HWERROR);
1946}
1947
1948#ifndef BFA_BIOS_BUILD
1949
1950/**
1951 * return true if IOC is disabled
1952 */
1953bfa_boolean_t
1954bfa_ioc_is_disabled(struct bfa_ioc_s *ioc)
1955{
1956 return (bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling)
1957 || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled));
1958}
1959
1960/**
1961 * return true if IOC firmware is different.
1962 */
1963bfa_boolean_t
1964bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
1965{
1966 return (bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset)
1967 || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_fwcheck)
1968 || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_mismatch));
1969}
1970
1971#define bfa_ioc_state_disabled(__sm) \
1972 (((__sm) == BFI_IOC_UNINIT) || \
1973 ((__sm) == BFI_IOC_INITING) || \
1974 ((__sm) == BFI_IOC_HWINIT) || \
1975 ((__sm) == BFI_IOC_DISABLED) || \
1976 ((__sm) == BFI_IOC_HBFAIL) || \
1977 ((__sm) == BFI_IOC_CFG_DISABLED))
1978
1979/**
1980 * Check if adapter is disabled -- both IOCs should be in a disabled
1981 * state.
1982 */
1983bfa_boolean_t
1984bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc)
1985{
1986 u32 ioc_state;
1987 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1988
1989 if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled))
1990 return BFA_FALSE;
1991
1992 ioc_state = bfa_reg_read(rb + BFA_IOC0_STATE_REG);
1993 if (!bfa_ioc_state_disabled(ioc_state))
1994 return BFA_FALSE;
1995
1996 ioc_state = bfa_reg_read(rb + BFA_IOC1_STATE_REG);
1997 if (!bfa_ioc_state_disabled(ioc_state))
1998 return BFA_FALSE;
1999
2000 return BFA_TRUE;
2001}
2002
2003/**
2004 * Add to IOC heartbeat failure notification queue. To be used by common
2005 * modules such as
2006 */
2007void
2008bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
2009 struct bfa_ioc_hbfail_notify_s *notify)
2010{
2011 list_add_tail(&notify->qe, &ioc->hb_notify_q);
2012}
2013
2014#define BFA_MFG_NAME "Brocade"
2015void
2016bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
2017 struct bfa_adapter_attr_s *ad_attr)
2018{
2019 struct bfi_ioc_attr_s *ioc_attr;
2020 char model[BFA_ADAPTER_MODEL_NAME_LEN];
2021
2022 ioc_attr = ioc->attr;
2023 bfa_os_memcpy((void *)&ad_attr->serial_num,
2024 (void *)ioc_attr->brcd_serialnum,
2025 BFA_ADAPTER_SERIAL_NUM_LEN);
2026
2027 bfa_os_memcpy(&ad_attr->fw_ver, ioc_attr->fw_version, BFA_VERSION_LEN);
2028 bfa_os_memcpy(&ad_attr->optrom_ver, ioc_attr->optrom_version,
2029 BFA_VERSION_LEN);
2030 bfa_os_memcpy(&ad_attr->manufacturer, BFA_MFG_NAME,
2031 BFA_ADAPTER_MFG_NAME_LEN);
2032 bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd,
2033 sizeof(struct bfa_mfg_vpd_s));
2034
2035 ad_attr->nports = BFI_ADAPTER_GETP(NPORTS, ioc_attr->adapter_prop);
2036 ad_attr->max_speed = BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
2037
2038 /**
2039 * model name
2040 */
2041 if (BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop) == 10) {
2042 strcpy(model, "BR-10?0");
2043 model[5] = '0' + ad_attr->nports;
2044 } else {
2045 strcpy(model, "Brocade-??5");
2046 model[8] =
2047 '0' + BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
2048 model[9] = '0' + ad_attr->nports;
2049 }
2050
2051 if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
2052 ad_attr->prototype = 1;
2053 else
2054 ad_attr->prototype = 0;
2055
2056 bfa_os_memcpy(&ad_attr->model, model, BFA_ADAPTER_MODEL_NAME_LEN);
2057 bfa_os_memcpy(&ad_attr->model_descr, &ad_attr->model,
2058 BFA_ADAPTER_MODEL_NAME_LEN);
2059
2060 ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
2061 ad_attr->mac = bfa_ioc_get_mac(ioc);
2062
2063 ad_attr->pcie_gen = ioc_attr->pcie_gen;
2064 ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
2065 ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
2066 ad_attr->asic_rev = ioc_attr->asic_rev;
2067 ad_attr->hw_ver[0] = 'R';
2068 ad_attr->hw_ver[1] = 'e';
2069 ad_attr->hw_ver[2] = 'v';
2070 ad_attr->hw_ver[3] = '-';
2071 ad_attr->hw_ver[4] = ioc_attr->asic_rev;
2072 ad_attr->hw_ver[5] = '\0';
2073
2074 ad_attr->cna_capable = ioc->cna;
2075}
2076
2077void
2078bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
2079{
2080 bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
2081
2082 ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm);
2083 ioc_attr->port_id = ioc->port_id;
2084
2085 if (!ioc->ctdev)
2086 ioc_attr->ioc_type = BFA_IOC_TYPE_FC;
2087 else if (ioc->ioc_mc == BFI_MC_IOCFC)
2088 ioc_attr->ioc_type = BFA_IOC_TYPE_FCoE;
2089 else if (ioc->ioc_mc == BFI_MC_LL)
2090 ioc_attr->ioc_type = BFA_IOC_TYPE_LL;
2091
2092 bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
2093
2094 ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
2095 ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
2096 ioc_attr->pci_attr.chip_rev[0] = 'R';
2097 ioc_attr->pci_attr.chip_rev[1] = 'e';
2098 ioc_attr->pci_attr.chip_rev[2] = 'v';
2099 ioc_attr->pci_attr.chip_rev[3] = '-';
2100 ioc_attr->pci_attr.chip_rev[4] = ioc_attr->adapter_attr.asic_rev;
2101 ioc_attr->pci_attr.chip_rev[5] = '\0';
2102}
2103
2104/**
2105 * hal_wwn_public
2106 */
2107wwn_t
2108bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc)
2109{
2110 union {
2111 wwn_t wwn;
2112 u8 byte[sizeof(wwn_t)];
2113 }
2114 w;
2115
2116 w.wwn = ioc->attr->mfg_wwn;
2117
2118 if (bfa_ioc_portid(ioc) == 1)
2119 w.byte[7]++;
2120
2121 return w.wwn;
2122}
2123
2124wwn_t
2125bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc)
2126{
2127 union {
2128 wwn_t wwn;
2129 u8 byte[sizeof(wwn_t)];
2130 }
2131 w;
2132
2133 w.wwn = ioc->attr->mfg_wwn;
2134
2135 if (bfa_ioc_portid(ioc) == 1)
2136 w.byte[7]++;
2137
2138 w.byte[0] = 0x20;
2139
2140 return w.wwn;
2141}
2142
2143wwn_t
2144bfa_ioc_get_wwn_naa5(struct bfa_ioc_s *ioc, u16 inst)
2145{
2146 union {
2147 wwn_t wwn;
2148 u8 byte[sizeof(wwn_t)];
2149 }
2150 w , w5;
2151
2152 bfa_trc(ioc, inst);
2153
2154 w.wwn = ioc->attr->mfg_wwn;
2155 w5.byte[0] = 0x50 | w.byte[2] >> 4;
2156 w5.byte[1] = w.byte[2] << 4 | w.byte[3] >> 4;
2157 w5.byte[2] = w.byte[3] << 4 | w.byte[4] >> 4;
2158 w5.byte[3] = w.byte[4] << 4 | w.byte[5] >> 4;
2159 w5.byte[4] = w.byte[5] << 4 | w.byte[6] >> 4;
2160 w5.byte[5] = w.byte[6] << 4 | w.byte[7] >> 4;
2161 w5.byte[6] = w.byte[7] << 4 | (inst & 0x0f00) >> 8;
2162 w5.byte[7] = (inst & 0xff);
2163
2164 return w5.wwn;
2165}
2166
2167u64
2168bfa_ioc_get_adid(struct bfa_ioc_s *ioc)
2169{
2170 return ioc->attr->mfg_wwn;
2171}
2172
2173mac_t
2174bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
2175{
2176 mac_t mac;
2177
2178 mac = ioc->attr->mfg_mac;
2179 mac.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc);
2180
2181 return mac;
2182}
2183
2184void
2185bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc)
2186{
2187 ioc->fcmode = BFA_TRUE;
2188 ioc->port_id = bfa_ioc_pcifn(ioc);
2189}
2190
2191bfa_boolean_t
2192bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc)
2193{
2194 return ioc->fcmode || (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT);
2195}
2196
2197/**
2198 * Return true if interrupt should be claimed.
2199 */
2200bfa_boolean_t
2201bfa_ioc_intx_claim(struct bfa_ioc_s *ioc)
2202{
2203 u32 isr, msk;
2204
2205 /**
2206 * Always claim if not catapult.
2207 */
2208 if (!ioc->ctdev)
2209 return BFA_TRUE;
2210
2211 /**
2212 * FALSE if next device is claiming interrupt.
2213 * TRUE if next device is not interrupting or not present.
2214 */
2215 msk = bfa_reg_read(ioc->ioc_regs.shirq_msk_next);
2216 isr = bfa_reg_read(ioc->ioc_regs.shirq_isr_next);
2217 return !(isr & ~msk);
2218}
2219
2220/**
2221 * Send AEN notification
2222 */
2223static void
2224bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
2225{
2226 union bfa_aen_data_u aen_data;
2227 struct bfa_log_mod_s *logmod = ioc->logm;
2228 s32 inst_num = 0;
2229 struct bfa_ioc_attr_s ioc_attr;
2230
2231 switch (event) {
2232 case BFA_IOC_AEN_HBGOOD:
2233 bfa_log(logmod, BFA_AEN_IOC_HBGOOD, inst_num);
2234 break;
2235 case BFA_IOC_AEN_HBFAIL:
2236 bfa_log(logmod, BFA_AEN_IOC_HBFAIL, inst_num);
2237 break;
2238 case BFA_IOC_AEN_ENABLE:
2239 bfa_log(logmod, BFA_AEN_IOC_ENABLE, inst_num);
2240 break;
2241 case BFA_IOC_AEN_DISABLE:
2242 bfa_log(logmod, BFA_AEN_IOC_DISABLE, inst_num);
2243 break;
2244 case BFA_IOC_AEN_FWMISMATCH:
2245 bfa_log(logmod, BFA_AEN_IOC_FWMISMATCH, inst_num);
2246 break;
2247 default:
2248 break;
2249 }
2250
2251 memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn));
2252 memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac));
2253 bfa_ioc_get_attr(ioc, &ioc_attr);
2254 switch (ioc_attr.ioc_type) {
2255 case BFA_IOC_TYPE_FC:
2256 aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc);
2257 break;
2258 case BFA_IOC_TYPE_FCoE:
2259 aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc);
2260 aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2261 break;
2262 case BFA_IOC_TYPE_LL:
2263 aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2264 break;
2265 default:
2266 bfa_assert(ioc_attr.ioc_type == BFA_IOC_TYPE_FC);
2267 break;
2268 }
2269 aen_data.ioc.ioc_type = ioc_attr.ioc_type;
2270}
2271
2272/**
2273 * Retrieve saved firmware trace from a prior IOC failure.
2274 */
2275bfa_status_t
2276bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2277{
2278 int tlen;
2279
2280 if (ioc->dbg_fwsave_len == 0)
2281 return BFA_STATUS_ENOFSAVE;
2282
2283 tlen = *trclen;
2284 if (tlen > ioc->dbg_fwsave_len)
2285 tlen = ioc->dbg_fwsave_len;
2286
2287 bfa_os_memcpy(trcdata, ioc->dbg_fwsave, tlen);
2288 *trclen = tlen;
2289 return BFA_STATUS_OK;
2290}
2291
2292/**
2293 * Retrieve saved firmware trace from a prior IOC failure.
2294 */
2295bfa_status_t
2296bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2297{
2298 u32 pgnum;
2299 u32 loff = BFA_DBG_FWTRC_OFF(bfa_ioc_portid(ioc));
2300 int i, tlen;
2301 u32 *tbuf = trcdata, r32;
2302
2303 bfa_trc(ioc, *trclen);
2304
2305 pgnum = bfa_ioc_smem_pgnum(ioc, loff);
2306 loff = bfa_ioc_smem_pgoff(ioc, loff);
2307 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
2308
2309 tlen = *trclen;
2310 if (tlen > BFA_DBG_FWTRC_LEN)
2311 tlen = BFA_DBG_FWTRC_LEN;
2312 tlen /= sizeof(u32);
2313
2314 bfa_trc(ioc, tlen);
2315
2316 for (i = 0; i < tlen; i++) {
2317 r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
2318 tbuf[i] = bfa_os_ntohl(r32);
2319 loff += sizeof(u32);
2320
2321 /**
2322 * handle page offset wrap around
2323 */
2324 loff = PSS_SMEM_PGOFF(loff);
2325 if (loff == 0) {
2326 pgnum++;
2327 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
2328 }
2329 }
2330 bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
2331 bfa_ioc_smem_pgnum(ioc, 0));
2332 bfa_trc(ioc, pgnum);
2333
2334 *trclen = tlen * sizeof(u32);
2335 return BFA_STATUS_OK;
2336}
2337
2338/**
2339 * Save firmware trace if configured.
2340 */
2341static void
2342bfa_ioc_debug_save(struct bfa_ioc_s *ioc)
2343{
2344 int tlen;
2345
2346 if (ioc->dbg_fwsave_len) {
2347 tlen = ioc->dbg_fwsave_len;
2348 bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen);
2349 }
2350}
2351
2352/**
2353 * Firmware failure detected. Start recovery actions.
2354 */
2355static void
2356bfa_ioc_recover(struct bfa_ioc_s *ioc)
2357{
2358 if (ioc->dbg_fwsave_once) {
2359 ioc->dbg_fwsave_once = BFA_FALSE;
2360 bfa_ioc_debug_save(ioc);
2361 }
2362
2363 bfa_ioc_stats(ioc, ioc_hbfails);
2364 bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
2365}
2366
2367#else
2368
2369static void
2370bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
2371{
2372}
2373
2374static void
2375bfa_ioc_recover(struct bfa_ioc_s *ioc)
2376{
2377 bfa_assert(0);
2378}
2379
2380#endif
2381
2382
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
new file mode 100644
index 000000000000..58efd4b13143
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -0,0 +1,259 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_IOC_H__
19#define __BFA_IOC_H__
20
21#include <cs/bfa_sm.h>
22#include <bfi/bfi.h>
23#include <bfi/bfi_ioc.h>
24#include <bfi/bfi_boot.h>
25#include <bfa_timer.h>
26
27/**
28 * PCI device information required by IOC
29 */
30struct bfa_pcidev_s {
31 int pci_slot;
32 u8 pci_func;
33 u16 device_id;
34 bfa_os_addr_t pci_bar_kva;
35};
36
37/**
38 * Structure used to remember the DMA-able memory block's KVA and Physical
39 * Address
40 */
41struct bfa_dma_s {
42 void *kva; /*! Kernel virtual address */
43 u64 pa; /*! Physical address */
44};
45
46#define BFA_DMA_ALIGN_SZ 256
47#define BFA_ROUNDUP(_l, _s) (((_l) + ((_s) - 1)) & ~((_s) - 1))
48
49
50
51#define bfa_dma_addr_set(dma_addr, pa) \
52 __bfa_dma_addr_set(&dma_addr, (u64)pa)
53
54static inline void
55__bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa)
56{
57 dma_addr->a32.addr_lo = (u32) pa;
58 dma_addr->a32.addr_hi = (u32) (bfa_os_u32(pa));
59}
60
61
62#define bfa_dma_be_addr_set(dma_addr, pa) \
63 __bfa_dma_be_addr_set(&dma_addr, (u64)pa)
64static inline void
65__bfa_dma_be_addr_set(union bfi_addr_u *dma_addr, u64 pa)
66{
67 dma_addr->a32.addr_lo = (u32) bfa_os_htonl(pa);
68 dma_addr->a32.addr_hi = (u32) bfa_os_htonl(bfa_os_u32(pa));
69}
70
71struct bfa_ioc_regs_s {
72 bfa_os_addr_t hfn_mbox_cmd;
73 bfa_os_addr_t hfn_mbox;
74 bfa_os_addr_t lpu_mbox_cmd;
75 bfa_os_addr_t lpu_mbox;
76 bfa_os_addr_t pss_ctl_reg;
77 bfa_os_addr_t app_pll_fast_ctl_reg;
78 bfa_os_addr_t app_pll_slow_ctl_reg;
79 bfa_os_addr_t ioc_sem_reg;
80 bfa_os_addr_t ioc_usage_sem_reg;
81 bfa_os_addr_t ioc_usage_reg;
82 bfa_os_addr_t host_page_num_fn;
83 bfa_os_addr_t heartbeat;
84 bfa_os_addr_t ioc_fwstate;
85 bfa_os_addr_t ll_halt;
86 bfa_os_addr_t shirq_isr_next;
87 bfa_os_addr_t shirq_msk_next;
88 bfa_os_addr_t smem_page_start;
89 u32 smem_pg0;
90};
91
92#define bfa_reg_read(_raddr) bfa_os_reg_read(_raddr)
93#define bfa_reg_write(_raddr, _val) bfa_os_reg_write(_raddr, _val)
94#define bfa_mem_read(_raddr, _off) bfa_os_mem_read(_raddr, _off)
95#define bfa_mem_write(_raddr, _off, _val) \
96 bfa_os_mem_write(_raddr, _off, _val)
97/**
98 * IOC Mailbox structures
99 */
100struct bfa_mbox_cmd_s {
101 struct list_head qe;
102 u32 msg[BFI_IOC_MSGSZ];
103};
104
105/**
106 * IOC mailbox module
107 */
108typedef void (*bfa_ioc_mbox_mcfunc_t)(void *cbarg, struct bfi_mbmsg_s *m);
109struct bfa_ioc_mbox_mod_s {
110 struct list_head cmd_q; /* pending mbox queue */
111 int nmclass; /* number of handlers */
112 struct {
113 bfa_ioc_mbox_mcfunc_t cbfn; /* message handlers */
114 void *cbarg;
115 } mbhdlr[BFI_MC_MAX];
116};
117
118/**
119 * IOC callback function interfaces
120 */
121typedef void (*bfa_ioc_enable_cbfn_t)(void *bfa, enum bfa_status status);
122typedef void (*bfa_ioc_disable_cbfn_t)(void *bfa);
123typedef void (*bfa_ioc_hbfail_cbfn_t)(void *bfa);
124typedef void (*bfa_ioc_reset_cbfn_t)(void *bfa);
125struct bfa_ioc_cbfn_s {
126 bfa_ioc_enable_cbfn_t enable_cbfn;
127 bfa_ioc_disable_cbfn_t disable_cbfn;
128 bfa_ioc_hbfail_cbfn_t hbfail_cbfn;
129 bfa_ioc_reset_cbfn_t reset_cbfn;
130};
131
132/**
133 * Heartbeat failure notification queue element.
134 */
135struct bfa_ioc_hbfail_notify_s {
136 struct list_head qe;
137 bfa_ioc_hbfail_cbfn_t cbfn;
138 void *cbarg;
139};
140
141/**
142 * Initialize a heartbeat failure notification structure
143 */
144#define bfa_ioc_hbfail_init(__notify, __cbfn, __cbarg) do { \
145 (__notify)->cbfn = (__cbfn); \
146 (__notify)->cbarg = (__cbarg); \
147} while (0)
148
149struct bfa_ioc_s {
150 bfa_fsm_t fsm;
151 struct bfa_s *bfa;
152 struct bfa_pcidev_s pcidev;
153 struct bfa_timer_mod_s *timer_mod;
154 struct bfa_timer_s ioc_timer;
155 struct bfa_timer_s sem_timer;
156 u32 hb_count;
157 u32 hb_fail;
158 u32 retry_count;
159 struct list_head hb_notify_q;
160 void *dbg_fwsave;
161 int dbg_fwsave_len;
162 bfa_boolean_t dbg_fwsave_once;
163 enum bfi_mclass ioc_mc;
164 struct bfa_ioc_regs_s ioc_regs;
165 struct bfa_trc_mod_s *trcmod;
166 struct bfa_aen_s *aen;
167 struct bfa_log_mod_s *logm;
168 struct bfa_ioc_drv_stats_s stats;
169 bfa_boolean_t auto_recover;
170 bfa_boolean_t fcmode;
171 bfa_boolean_t ctdev;
172 bfa_boolean_t cna;
173 bfa_boolean_t pllinit;
174 u8 port_id;
175
176 struct bfa_dma_s attr_dma;
177 struct bfi_ioc_attr_s *attr;
178 struct bfa_ioc_cbfn_s *cbfn;
179 struct bfa_ioc_mbox_mod_s mbox_mod;
180};
181
182#define bfa_ioc_pcifn(__ioc) (__ioc)->pcidev.pci_func
183#define bfa_ioc_devid(__ioc) (__ioc)->pcidev.device_id
184#define bfa_ioc_bar0(__ioc) (__ioc)->pcidev.pci_bar_kva
185#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
186#define bfa_ioc_fetch_stats(__ioc, __stats) \
187 ((__stats)->drv_stats) = (__ioc)->stats
188#define bfa_ioc_clr_stats(__ioc) \
189 bfa_os_memset(&(__ioc)->stats, 0, sizeof((__ioc)->stats))
190#define bfa_ioc_maxfrsize(__ioc) (__ioc)->attr->maxfrsize
191#define bfa_ioc_rx_bbcredit(__ioc) (__ioc)->attr->rx_bbcredit
192#define bfa_ioc_speed_sup(__ioc) \
193 BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
194
195/**
196 * IOC mailbox interface
197 */
198void bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd);
199void bfa_ioc_mbox_register(struct bfa_ioc_s *ioc,
200 bfa_ioc_mbox_mcfunc_t *mcfuncs);
201void bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc);
202void bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len);
203void bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg);
204void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
205 bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg);
206
207/**
208 * IOC interfaces
209 */
210void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa,
211 struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod,
212 struct bfa_trc_mod_s *trcmod,
213 struct bfa_aen_s *aen, struct bfa_log_mod_s *logm);
214void bfa_ioc_detach(struct bfa_ioc_s *ioc);
215void bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
216 enum bfi_mclass mc);
217u32 bfa_ioc_meminfo(void);
218void bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa);
219void bfa_ioc_enable(struct bfa_ioc_s *ioc);
220void bfa_ioc_disable(struct bfa_ioc_s *ioc);
221bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc);
222
223void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param);
224void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg);
225void bfa_ioc_error_isr(struct bfa_ioc_s *ioc);
226void bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t intx);
227bfa_status_t bfa_ioc_pll_init(struct bfa_ioc_s *ioc);
228bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc);
229bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc);
230bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc);
231bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc);
232void bfa_ioc_cfg_complete(struct bfa_ioc_s *ioc);
233void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr);
234void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
235 struct bfa_adapter_attr_s *ad_attr);
236int bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover);
237void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave);
238bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata,
239 int *trclen);
240bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata,
241 int *trclen);
242u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr);
243u32 bfa_ioc_smem_pgoff(struct bfa_ioc_s *ioc, u32 fmaddr);
244void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc);
245bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc);
246void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
247 struct bfa_ioc_hbfail_notify_s *notify);
248
249/*
250 * bfa mfg wwn API functions
251 */
252wwn_t bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc);
253wwn_t bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc);
254wwn_t bfa_ioc_get_wwn_naa5(struct bfa_ioc_s *ioc, u16 inst);
255mac_t bfa_ioc_get_mac(struct bfa_ioc_s *ioc);
256u64 bfa_ioc_get_adid(struct bfa_ioc_s *ioc);
257
258#endif /* __BFA_IOC_H__ */
259
diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c
new file mode 100644
index 000000000000..12350b022d63
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_iocfc.c
@@ -0,0 +1,872 @@
1/*
2 * Copyright (c) 2005-2009 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 <cs/bfa_debug.h>
19#include <bfa_priv.h>
20#include <log/bfa_log_hal.h>
21#include <bfi/bfi_boot.h>
22#include <bfi/bfi_cbreg.h>
23#include <aen/bfa_aen_ioc.h>
24#include <defs/bfa_defs_iocfc.h>
25#include <defs/bfa_defs_pci.h>
26#include "bfa_callback_priv.h"
27#include "bfad_drv.h"
28
29BFA_TRC_FILE(HAL, IOCFC);
30
31/**
32 * IOC local definitions
33 */
34#define BFA_IOCFC_TOV 5000 /* msecs */
35
36enum {
37 BFA_IOCFC_ACT_NONE = 0,
38 BFA_IOCFC_ACT_INIT = 1,
39 BFA_IOCFC_ACT_STOP = 2,
40 BFA_IOCFC_ACT_DISABLE = 3,
41};
42
43/*
44 * forward declarations
45 */
46static void bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status);
47static void bfa_iocfc_disable_cbfn(void *bfa_arg);
48static void bfa_iocfc_hbfail_cbfn(void *bfa_arg);
49static void bfa_iocfc_reset_cbfn(void *bfa_arg);
50static void bfa_iocfc_stats_clear(void *bfa_arg);
51static void bfa_iocfc_stats_swap(struct bfa_fw_stats_s *d,
52 struct bfa_fw_stats_s *s);
53static void bfa_iocfc_stats_clr_cb(void *bfa_arg, bfa_boolean_t complete);
54static void bfa_iocfc_stats_clr_timeout(void *bfa_arg);
55static void bfa_iocfc_stats_cb(void *bfa_arg, bfa_boolean_t complete);
56static void bfa_iocfc_stats_timeout(void *bfa_arg);
57
58static struct bfa_ioc_cbfn_s bfa_iocfc_cbfn;
59
60/**
61 * bfa_ioc_pvt BFA IOC private functions
62 */
63
64static void
65bfa_iocfc_cqs_sz(struct bfa_iocfc_cfg_s *cfg, u32 *dm_len)
66{
67 int i, per_reqq_sz, per_rspq_sz;
68
69 per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ),
70 BFA_DMA_ALIGN_SZ);
71 per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ),
72 BFA_DMA_ALIGN_SZ);
73
74 /*
75 * Calculate CQ size
76 */
77 for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
78 *dm_len = *dm_len + per_reqq_sz;
79 *dm_len = *dm_len + per_rspq_sz;
80 }
81
82 /*
83 * Calculate Shadow CI/PI size
84 */
85 for (i = 0; i < cfg->fwcfg.num_cqs; i++)
86 *dm_len += (2 * BFA_CACHELINE_SZ);
87}
88
89static void
90bfa_iocfc_fw_cfg_sz(struct bfa_iocfc_cfg_s *cfg, u32 *dm_len)
91{
92 *dm_len +=
93 BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
94 *dm_len +=
95 BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
96 BFA_CACHELINE_SZ);
97 *dm_len += BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s), BFA_CACHELINE_SZ);
98}
99
100/**
101 * Use the Mailbox interface to send BFI_IOCFC_H2I_CFG_REQ
102 */
103static void
104bfa_iocfc_send_cfg(void *bfa_arg)
105{
106 struct bfa_s *bfa = bfa_arg;
107 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
108 struct bfi_iocfc_cfg_req_s cfg_req;
109 struct bfi_iocfc_cfg_s *cfg_info = iocfc->cfginfo;
110 struct bfa_iocfc_cfg_s *cfg = &iocfc->cfg;
111 int i;
112
113 bfa_assert(cfg->fwcfg.num_cqs <= BFI_IOC_MAX_CQS);
114 bfa_trc(bfa, cfg->fwcfg.num_cqs);
115
116 iocfc->cfgdone = BFA_FALSE;
117 bfa_iocfc_reset_queues(bfa);
118
119 /**
120 * initialize IOC configuration info
121 */
122 cfg_info->endian_sig = BFI_IOC_ENDIAN_SIG;
123 cfg_info->num_cqs = cfg->fwcfg.num_cqs;
124
125 bfa_dma_be_addr_set(cfg_info->cfgrsp_addr, iocfc->cfgrsp_dma.pa);
126 bfa_dma_be_addr_set(cfg_info->stats_addr, iocfc->stats_pa);
127
128 /**
129 * dma map REQ and RSP circular queues and shadow pointers
130 */
131 for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
132 bfa_dma_be_addr_set(cfg_info->req_cq_ba[i],
133 iocfc->req_cq_ba[i].pa);
134 bfa_dma_be_addr_set(cfg_info->req_shadow_ci[i],
135 iocfc->req_cq_shadow_ci[i].pa);
136 cfg_info->req_cq_elems[i] =
137 bfa_os_htons(cfg->drvcfg.num_reqq_elems);
138
139 bfa_dma_be_addr_set(cfg_info->rsp_cq_ba[i],
140 iocfc->rsp_cq_ba[i].pa);
141 bfa_dma_be_addr_set(cfg_info->rsp_shadow_pi[i],
142 iocfc->rsp_cq_shadow_pi[i].pa);
143 cfg_info->rsp_cq_elems[i] =
144 bfa_os_htons(cfg->drvcfg.num_rspq_elems);
145 }
146
147 /**
148 * dma map IOC configuration itself
149 */
150 bfi_h2i_set(cfg_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_CFG_REQ,
151 bfa_lpuid(bfa));
152 bfa_dma_be_addr_set(cfg_req.ioc_cfg_dma_addr, iocfc->cfg_info.pa);
153
154 bfa_ioc_mbox_send(&bfa->ioc, &cfg_req,
155 sizeof(struct bfi_iocfc_cfg_req_s));
156}
157
158static void
159bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
160 struct bfa_pcidev_s *pcidev)
161{
162 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
163
164 bfa->bfad = bfad;
165 iocfc->bfa = bfa;
166 iocfc->action = BFA_IOCFC_ACT_NONE;
167
168 bfa_os_assign(iocfc->cfg, *cfg);
169
170 /**
171 * Initialize chip specific handlers.
172 */
173 if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) {
174 iocfc->hwif.hw_reginit = bfa_hwct_reginit;
175 iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
176 iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;
177 iocfc->hwif.hw_msix_install = bfa_hwct_msix_install;
178 iocfc->hwif.hw_msix_uninstall = bfa_hwct_msix_uninstall;
179 iocfc->hwif.hw_isr_mode_set = bfa_hwct_isr_mode_set;
180 iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
181 } else {
182 iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
183 iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
184 iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
185 iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install;
186 iocfc->hwif.hw_msix_uninstall = bfa_hwcb_msix_uninstall;
187 iocfc->hwif.hw_isr_mode_set = bfa_hwcb_isr_mode_set;
188 iocfc->hwif.hw_msix_getvecs = bfa_hwcb_msix_getvecs;
189 }
190
191 iocfc->hwif.hw_reginit(bfa);
192 bfa->msix.nvecs = 0;
193}
194
195static void
196bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg,
197 struct bfa_meminfo_s *meminfo)
198{
199 u8 *dm_kva;
200 u64 dm_pa;
201 int i, per_reqq_sz, per_rspq_sz;
202 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
203 int dbgsz;
204
205 dm_kva = bfa_meminfo_dma_virt(meminfo);
206 dm_pa = bfa_meminfo_dma_phys(meminfo);
207
208 /*
209 * First allocate dma memory for IOC.
210 */
211 bfa_ioc_mem_claim(&bfa->ioc, dm_kva, dm_pa);
212 dm_kva += bfa_ioc_meminfo();
213 dm_pa += bfa_ioc_meminfo();
214
215 /*
216 * Claim DMA-able memory for the request/response queues and for shadow
217 * ci/pi registers
218 */
219 per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ),
220 BFA_DMA_ALIGN_SZ);
221 per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ),
222 BFA_DMA_ALIGN_SZ);
223
224 for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
225 iocfc->req_cq_ba[i].kva = dm_kva;
226 iocfc->req_cq_ba[i].pa = dm_pa;
227 bfa_os_memset(dm_kva, 0, per_reqq_sz);
228 dm_kva += per_reqq_sz;
229 dm_pa += per_reqq_sz;
230
231 iocfc->rsp_cq_ba[i].kva = dm_kva;
232 iocfc->rsp_cq_ba[i].pa = dm_pa;
233 bfa_os_memset(dm_kva, 0, per_rspq_sz);
234 dm_kva += per_rspq_sz;
235 dm_pa += per_rspq_sz;
236 }
237
238 for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
239 iocfc->req_cq_shadow_ci[i].kva = dm_kva;
240 iocfc->req_cq_shadow_ci[i].pa = dm_pa;
241 dm_kva += BFA_CACHELINE_SZ;
242 dm_pa += BFA_CACHELINE_SZ;
243
244 iocfc->rsp_cq_shadow_pi[i].kva = dm_kva;
245 iocfc->rsp_cq_shadow_pi[i].pa = dm_pa;
246 dm_kva += BFA_CACHELINE_SZ;
247 dm_pa += BFA_CACHELINE_SZ;
248 }
249
250 /*
251 * Claim DMA-able memory for the config info page
252 */
253 bfa->iocfc.cfg_info.kva = dm_kva;
254 bfa->iocfc.cfg_info.pa = dm_pa;
255 bfa->iocfc.cfginfo = (struct bfi_iocfc_cfg_s *) dm_kva;
256 dm_kva += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
257 dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
258
259 /*
260 * Claim DMA-able memory for the config response
261 */
262 bfa->iocfc.cfgrsp_dma.kva = dm_kva;
263 bfa->iocfc.cfgrsp_dma.pa = dm_pa;
264 bfa->iocfc.cfgrsp = (struct bfi_iocfc_cfgrsp_s *) dm_kva;
265
266 dm_kva +=
267 BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
268 BFA_CACHELINE_SZ);
269 dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
270 BFA_CACHELINE_SZ);
271
272 /*
273 * Claim DMA-able memory for iocfc stats
274 */
275 bfa->iocfc.stats_kva = dm_kva;
276 bfa->iocfc.stats_pa = dm_pa;
277 bfa->iocfc.fw_stats = (struct bfa_fw_stats_s *) dm_kva;
278 dm_kva += BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s), BFA_CACHELINE_SZ);
279 dm_pa += BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s), BFA_CACHELINE_SZ);
280
281 bfa_meminfo_dma_virt(meminfo) = dm_kva;
282 bfa_meminfo_dma_phys(meminfo) = dm_pa;
283
284 dbgsz = bfa_ioc_debug_trcsz(bfa_auto_recover);
285 if (dbgsz > 0) {
286 bfa_ioc_debug_memclaim(&bfa->ioc, bfa_meminfo_kva(meminfo));
287 bfa_meminfo_kva(meminfo) += dbgsz;
288 }
289}
290
291/**
292 * BFA submodules initialization completion notification.
293 */
294static void
295bfa_iocfc_initdone_submod(struct bfa_s *bfa)
296{
297 int i;
298
299 for (i = 0; hal_mods[i]; i++)
300 hal_mods[i]->initdone(bfa);
301}
302
303/**
304 * Start BFA submodules.
305 */
306static void
307bfa_iocfc_start_submod(struct bfa_s *bfa)
308{
309 int i;
310
311 bfa->rme_process = BFA_TRUE;
312
313 for (i = 0; hal_mods[i]; i++)
314 hal_mods[i]->start(bfa);
315}
316
317/**
318 * Disable BFA submodules.
319 */
320static void
321bfa_iocfc_disable_submod(struct bfa_s *bfa)
322{
323 int i;
324
325 for (i = 0; hal_mods[i]; i++)
326 hal_mods[i]->iocdisable(bfa);
327}
328
329static void
330bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)
331{
332 struct bfa_s *bfa = bfa_arg;
333
334 if (complete) {
335 if (bfa->iocfc.cfgdone)
336 bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
337 else
338 bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
339 } else
340 bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
341}
342
343static void
344bfa_iocfc_stop_cb(void *bfa_arg, bfa_boolean_t compl)
345{
346 struct bfa_s *bfa = bfa_arg;
347 struct bfad_s *bfad = bfa->bfad;
348
349 if (compl)
350 complete(&bfad->comp);
351
352 else
353 bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
354}
355
356static void
357bfa_iocfc_disable_cb(void *bfa_arg, bfa_boolean_t compl)
358{
359 struct bfa_s *bfa = bfa_arg;
360 struct bfad_s *bfad = bfa->bfad;
361
362 if (compl)
363 complete(&bfad->disable_comp);
364}
365
366/**
367 * Update BFA configuration from firmware configuration.
368 */
369static void
370bfa_iocfc_cfgrsp(struct bfa_s *bfa)
371{
372 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
373 struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
374 struct bfa_iocfc_fwcfg_s *fwcfg = &cfgrsp->fwcfg;
375 struct bfi_iocfc_cfg_s *cfginfo = iocfc->cfginfo;
376
377 fwcfg->num_cqs = fwcfg->num_cqs;
378 fwcfg->num_ioim_reqs = bfa_os_ntohs(fwcfg->num_ioim_reqs);
379 fwcfg->num_tskim_reqs = bfa_os_ntohs(fwcfg->num_tskim_reqs);
380 fwcfg->num_fcxp_reqs = bfa_os_ntohs(fwcfg->num_fcxp_reqs);
381 fwcfg->num_uf_bufs = bfa_os_ntohs(fwcfg->num_uf_bufs);
382 fwcfg->num_rports = bfa_os_ntohs(fwcfg->num_rports);
383
384 cfginfo->intr_attr.coalesce = cfgrsp->intr_attr.coalesce;
385 cfginfo->intr_attr.delay = bfa_os_ntohs(cfgrsp->intr_attr.delay);
386 cfginfo->intr_attr.latency = bfa_os_ntohs(cfgrsp->intr_attr.latency);
387
388 iocfc->cfgdone = BFA_TRUE;
389
390 /**
391 * Configuration is complete - initialize/start submodules
392 */
393 if (iocfc->action == BFA_IOCFC_ACT_INIT)
394 bfa_cb_queue(bfa, &iocfc->init_hcb_qe, bfa_iocfc_init_cb, bfa);
395 else
396 bfa_iocfc_start_submod(bfa);
397}
398
399static void
400bfa_iocfc_stats_clear(void *bfa_arg)
401{
402 struct bfa_s *bfa = bfa_arg;
403 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
404 struct bfi_iocfc_stats_req_s stats_req;
405
406 bfa_timer_start(bfa, &iocfc->stats_timer,
407 bfa_iocfc_stats_clr_timeout, bfa,
408 BFA_IOCFC_TOV);
409
410 bfi_h2i_set(stats_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_CLEAR_STATS_REQ,
411 bfa_lpuid(bfa));
412 bfa_ioc_mbox_send(&bfa->ioc, &stats_req,
413 sizeof(struct bfi_iocfc_stats_req_s));
414}
415
416static void
417bfa_iocfc_stats_swap(struct bfa_fw_stats_s *d, struct bfa_fw_stats_s *s)
418{
419 u32 *dip = (u32 *) d;
420 u32 *sip = (u32 *) s;
421 int i;
422
423 for (i = 0; i < (sizeof(struct bfa_fw_stats_s) / sizeof(u32)); i++)
424 dip[i] = bfa_os_ntohl(sip[i]);
425}
426
427static void
428bfa_iocfc_stats_clr_cb(void *bfa_arg, bfa_boolean_t complete)
429{
430 struct bfa_s *bfa = bfa_arg;
431 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
432
433 if (complete) {
434 bfa_ioc_clr_stats(&bfa->ioc);
435 iocfc->stats_cbfn(iocfc->stats_cbarg, iocfc->stats_status);
436 } else {
437 iocfc->stats_busy = BFA_FALSE;
438 iocfc->stats_status = BFA_STATUS_OK;
439 }
440}
441
442static void
443bfa_iocfc_stats_clr_timeout(void *bfa_arg)
444{
445 struct bfa_s *bfa = bfa_arg;
446 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
447
448 bfa_trc(bfa, 0);
449
450 iocfc->stats_status = BFA_STATUS_ETIMER;
451 bfa_cb_queue(bfa, &iocfc->stats_hcb_qe, bfa_iocfc_stats_clr_cb, bfa);
452}
453
454static void
455bfa_iocfc_stats_cb(void *bfa_arg, bfa_boolean_t complete)
456{
457 struct bfa_s *bfa = bfa_arg;
458 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
459
460 if (complete) {
461 if (iocfc->stats_status == BFA_STATUS_OK) {
462 bfa_os_memset(iocfc->stats_ret, 0,
463 sizeof(*iocfc->stats_ret));
464 bfa_iocfc_stats_swap(&iocfc->stats_ret->fw_stats,
465 iocfc->fw_stats);
466 }
467 iocfc->stats_cbfn(iocfc->stats_cbarg, iocfc->stats_status);
468 } else {
469 iocfc->stats_busy = BFA_FALSE;
470 iocfc->stats_status = BFA_STATUS_OK;
471 }
472}
473
474static void
475bfa_iocfc_stats_timeout(void *bfa_arg)
476{
477 struct bfa_s *bfa = bfa_arg;
478 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
479
480 bfa_trc(bfa, 0);
481
482 iocfc->stats_status = BFA_STATUS_ETIMER;
483 bfa_cb_queue(bfa, &iocfc->stats_hcb_qe, bfa_iocfc_stats_cb, bfa);
484}
485
486static void
487bfa_iocfc_stats_query(struct bfa_s *bfa)
488{
489 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
490 struct bfi_iocfc_stats_req_s stats_req;
491
492 bfa_timer_start(bfa, &iocfc->stats_timer,
493 bfa_iocfc_stats_timeout, bfa, BFA_IOCFC_TOV);
494
495 bfi_h2i_set(stats_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_GET_STATS_REQ,
496 bfa_lpuid(bfa));
497 bfa_ioc_mbox_send(&bfa->ioc, &stats_req,
498 sizeof(struct bfi_iocfc_stats_req_s));
499}
500
501void
502bfa_iocfc_reset_queues(struct bfa_s *bfa)
503{
504 int q;
505
506 for (q = 0; q < BFI_IOC_MAX_CQS; q++) {
507 bfa_reqq_ci(bfa, q) = 0;
508 bfa_reqq_pi(bfa, q) = 0;
509 bfa_rspq_ci(bfa, q) = 0;
510 bfa_rspq_pi(bfa, q) = 0;
511 }
512}
513
514/**
515 * IOC enable request is complete
516 */
517static void
518bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)
519{
520 struct bfa_s *bfa = bfa_arg;
521
522 if (status != BFA_STATUS_OK) {
523 bfa_isr_disable(bfa);
524 if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT)
525 bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
526 bfa_iocfc_init_cb, bfa);
527 return;
528 }
529
530 bfa_iocfc_initdone_submod(bfa);
531 bfa_iocfc_send_cfg(bfa);
532}
533
534/**
535 * IOC disable request is complete
536 */
537static void
538bfa_iocfc_disable_cbfn(void *bfa_arg)
539{
540 struct bfa_s *bfa = bfa_arg;
541
542 bfa_isr_disable(bfa);
543 bfa_iocfc_disable_submod(bfa);
544
545 if (bfa->iocfc.action == BFA_IOCFC_ACT_STOP)
546 bfa_cb_queue(bfa, &bfa->iocfc.stop_hcb_qe, bfa_iocfc_stop_cb,
547 bfa);
548 else {
549 bfa_assert(bfa->iocfc.action == BFA_IOCFC_ACT_DISABLE);
550 bfa_cb_queue(bfa, &bfa->iocfc.dis_hcb_qe, bfa_iocfc_disable_cb,
551 bfa);
552 }
553}
554
555/**
556 * Notify sub-modules of hardware failure.
557 */
558static void
559bfa_iocfc_hbfail_cbfn(void *bfa_arg)
560{
561 struct bfa_s *bfa = bfa_arg;
562
563 bfa->rme_process = BFA_FALSE;
564
565 bfa_isr_disable(bfa);
566 bfa_iocfc_disable_submod(bfa);
567
568 if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT)
569 bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe, bfa_iocfc_init_cb,
570 bfa);
571}
572
573/**
574 * Actions on chip-reset completion.
575 */
576static void
577bfa_iocfc_reset_cbfn(void *bfa_arg)
578{
579 struct bfa_s *bfa = bfa_arg;
580
581 bfa_iocfc_reset_queues(bfa);
582 bfa_isr_enable(bfa);
583}
584
585
586
587/**
588 * bfa_ioc_public
589 */
590
591/**
592 * Query IOC memory requirement information.
593 */
594void
595bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
596 u32 *dm_len)
597{
598 /* dma memory for IOC */
599 *dm_len += bfa_ioc_meminfo();
600
601 bfa_iocfc_fw_cfg_sz(cfg, dm_len);
602 bfa_iocfc_cqs_sz(cfg, dm_len);
603 *km_len += bfa_ioc_debug_trcsz(bfa_auto_recover);
604}
605
606/**
607 * Query IOC memory requirement information.
608 */
609void
610bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
611 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
612{
613 int i;
614
615 bfa_iocfc_cbfn.enable_cbfn = bfa_iocfc_enable_cbfn;
616 bfa_iocfc_cbfn.disable_cbfn = bfa_iocfc_disable_cbfn;
617 bfa_iocfc_cbfn.hbfail_cbfn = bfa_iocfc_hbfail_cbfn;
618 bfa_iocfc_cbfn.reset_cbfn = bfa_iocfc_reset_cbfn;
619
620 bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod,
621 bfa->trcmod, bfa->aen, bfa->logm);
622 bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
623 bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
624
625 /**
626 * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode.
627 */
628 if (0)
629 bfa_ioc_set_fcmode(&bfa->ioc);
630
631 bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
632 bfa_iocfc_mem_claim(bfa, cfg, meminfo);
633 bfa_timer_init(&bfa->timer_mod);
634
635 INIT_LIST_HEAD(&bfa->comp_q);
636 for (i = 0; i < BFI_IOC_MAX_CQS; i++)
637 INIT_LIST_HEAD(&bfa->reqq_waitq[i]);
638}
639
640/**
641 * Query IOC memory requirement information.
642 */
643void
644bfa_iocfc_detach(struct bfa_s *bfa)
645{
646 bfa_ioc_detach(&bfa->ioc);
647}
648
649/**
650 * Query IOC memory requirement information.
651 */
652void
653bfa_iocfc_init(struct bfa_s *bfa)
654{
655 bfa->iocfc.action = BFA_IOCFC_ACT_INIT;
656 bfa_ioc_enable(&bfa->ioc);
657 bfa_msix_install(bfa);
658}
659
660/**
661 * IOC start called from bfa_start(). Called to start IOC operations
662 * at driver instantiation for this instance.
663 */
664void
665bfa_iocfc_start(struct bfa_s *bfa)
666{
667 if (bfa->iocfc.cfgdone)
668 bfa_iocfc_start_submod(bfa);
669}
670
671/**
672 * IOC stop called from bfa_stop(). Called only when driver is unloaded
673 * for this instance.
674 */
675void
676bfa_iocfc_stop(struct bfa_s *bfa)
677{
678 bfa->iocfc.action = BFA_IOCFC_ACT_STOP;
679
680 bfa->rme_process = BFA_FALSE;
681 bfa_ioc_disable(&bfa->ioc);
682}
683
684void
685bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m)
686{
687 struct bfa_s *bfa = bfaarg;
688 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
689 union bfi_iocfc_i2h_msg_u *msg;
690
691 msg = (union bfi_iocfc_i2h_msg_u *) m;
692 bfa_trc(bfa, msg->mh.msg_id);
693
694 switch (msg->mh.msg_id) {
695 case BFI_IOCFC_I2H_CFG_REPLY:
696 iocfc->cfg_reply = &msg->cfg_reply;
697 bfa_iocfc_cfgrsp(bfa);
698 break;
699
700 case BFI_IOCFC_I2H_GET_STATS_RSP:
701 if (iocfc->stats_busy == BFA_FALSE
702 || iocfc->stats_status == BFA_STATUS_ETIMER)
703 break;
704
705 bfa_timer_stop(&iocfc->stats_timer);
706 iocfc->stats_status = BFA_STATUS_OK;
707 bfa_cb_queue(bfa, &iocfc->stats_hcb_qe, bfa_iocfc_stats_cb,
708 bfa);
709 break;
710 case BFI_IOCFC_I2H_CLEAR_STATS_RSP:
711 /*
712 * check for timer pop before processing the rsp
713 */
714 if (iocfc->stats_busy == BFA_FALSE
715 || iocfc->stats_status == BFA_STATUS_ETIMER)
716 break;
717
718 bfa_timer_stop(&iocfc->stats_timer);
719 iocfc->stats_status = BFA_STATUS_OK;
720 bfa_cb_queue(bfa, &iocfc->stats_hcb_qe,
721 bfa_iocfc_stats_clr_cb, bfa);
722 break;
723 case BFI_IOCFC_I2H_UPDATEQ_RSP:
724 iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK);
725 break;
726 default:
727 bfa_assert(0);
728 }
729}
730
731#ifndef BFA_BIOS_BUILD
732void
733bfa_adapter_get_attr(struct bfa_s *bfa, struct bfa_adapter_attr_s *ad_attr)
734{
735 bfa_ioc_get_adapter_attr(&bfa->ioc, ad_attr);
736}
737
738u64
739bfa_adapter_get_id(struct bfa_s *bfa)
740{
741 return bfa_ioc_get_adid(&bfa->ioc);
742}
743
744void
745bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr)
746{
747 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
748
749 attr->intr_attr = iocfc->cfginfo->intr_attr;
750 attr->config = iocfc->cfg;
751}
752
753bfa_status_t
754bfa_iocfc_israttr_set(struct bfa_s *bfa, struct bfa_iocfc_intr_attr_s *attr)
755{
756 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
757 struct bfi_iocfc_set_intr_req_s *m;
758
759 iocfc->cfginfo->intr_attr = *attr;
760 if (!bfa_iocfc_is_operational(bfa))
761 return BFA_STATUS_OK;
762
763 m = bfa_reqq_next(bfa, BFA_REQQ_IOC);
764 if (!m)
765 return BFA_STATUS_DEVBUSY;
766
767 bfi_h2i_set(m->mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_SET_INTR_REQ,
768 bfa_lpuid(bfa));
769 m->coalesce = attr->coalesce;
770 m->delay = bfa_os_htons(attr->delay);
771 m->latency = bfa_os_htons(attr->latency);
772
773 bfa_trc(bfa, attr->delay);
774 bfa_trc(bfa, attr->latency);
775
776 bfa_reqq_produce(bfa, BFA_REQQ_IOC);
777 return BFA_STATUS_OK;
778}
779
780void
781bfa_iocfc_set_snsbase(struct bfa_s *bfa, u64 snsbase_pa)
782{
783 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
784
785 iocfc->cfginfo->sense_buf_len = (BFI_IOIM_SNSLEN - 1);
786 bfa_dma_be_addr_set(iocfc->cfginfo->ioim_snsbase, snsbase_pa);
787}
788
789bfa_status_t
790bfa_iocfc_get_stats(struct bfa_s *bfa, struct bfa_iocfc_stats_s *stats,
791 bfa_cb_ioc_t cbfn, void *cbarg)
792{
793 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
794
795 if (iocfc->stats_busy) {
796 bfa_trc(bfa, iocfc->stats_busy);
797 return (BFA_STATUS_DEVBUSY);
798 }
799
800 iocfc->stats_busy = BFA_TRUE;
801 iocfc->stats_ret = stats;
802 iocfc->stats_cbfn = cbfn;
803 iocfc->stats_cbarg = cbarg;
804
805 bfa_iocfc_stats_query(bfa);
806
807 return (BFA_STATUS_OK);
808}
809
810bfa_status_t
811bfa_iocfc_clear_stats(struct bfa_s *bfa, bfa_cb_ioc_t cbfn, void *cbarg)
812{
813 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
814
815 if (iocfc->stats_busy) {
816 bfa_trc(bfa, iocfc->stats_busy);
817 return (BFA_STATUS_DEVBUSY);
818 }
819
820 iocfc->stats_busy = BFA_TRUE;
821 iocfc->stats_cbfn = cbfn;
822 iocfc->stats_cbarg = cbarg;
823
824 bfa_iocfc_stats_clear(bfa);
825 return (BFA_STATUS_OK);
826}
827
828/**
829 * Enable IOC after it is disabled.
830 */
831void
832bfa_iocfc_enable(struct bfa_s *bfa)
833{
834 bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,
835 "IOC Enable");
836 bfa_ioc_enable(&bfa->ioc);
837}
838
839void
840bfa_iocfc_disable(struct bfa_s *bfa)
841{
842 bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,
843 "IOC Disable");
844 bfa->iocfc.action = BFA_IOCFC_ACT_DISABLE;
845
846 bfa->rme_process = BFA_FALSE;
847 bfa_ioc_disable(&bfa->ioc);
848}
849
850
851bfa_boolean_t
852bfa_iocfc_is_operational(struct bfa_s *bfa)
853{
854 return bfa_ioc_is_operational(&bfa->ioc) && bfa->iocfc.cfgdone;
855}
856
857/**
858 * Return boot target port wwns -- read from boot information in flash.
859 */
860void
861bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns)
862{
863 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
864 struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
865
866 *nwwns = cfgrsp->bootwwns.nwwns;
867 *wwns = cfgrsp->bootwwns.wwn;
868}
869
870#endif
871
872
diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h
new file mode 100644
index 000000000000..7ad177ed4cfc
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_iocfc.h
@@ -0,0 +1,168 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_IOCFC_H__
19#define __BFA_IOCFC_H__
20
21#include <bfa_ioc.h>
22#include <bfa.h>
23#include <bfi/bfi_iocfc.h>
24#include <bfa_callback_priv.h>
25
26#define BFA_REQQ_NELEMS_MIN (4)
27#define BFA_RSPQ_NELEMS_MIN (4)
28
29struct bfa_iocfc_regs_s {
30 bfa_os_addr_t intr_status;
31 bfa_os_addr_t intr_mask;
32 bfa_os_addr_t cpe_q_pi[BFI_IOC_MAX_CQS];
33 bfa_os_addr_t cpe_q_ci[BFI_IOC_MAX_CQS];
34 bfa_os_addr_t cpe_q_depth[BFI_IOC_MAX_CQS];
35 bfa_os_addr_t cpe_q_ctrl[BFI_IOC_MAX_CQS];
36 bfa_os_addr_t rme_q_ci[BFI_IOC_MAX_CQS];
37 bfa_os_addr_t rme_q_pi[BFI_IOC_MAX_CQS];
38 bfa_os_addr_t rme_q_depth[BFI_IOC_MAX_CQS];
39 bfa_os_addr_t rme_q_ctrl[BFI_IOC_MAX_CQS];
40};
41
42/**
43 * MSIX vector handlers
44 */
45#define BFA_MSIX_MAX_VECTORS 22
46typedef void (*bfa_msix_handler_t)(struct bfa_s *bfa, int vec);
47struct bfa_msix_s {
48 int nvecs;
49 bfa_msix_handler_t handler[BFA_MSIX_MAX_VECTORS];
50};
51
52/**
53 * Chip specific interfaces
54 */
55struct bfa_hwif_s {
56 void (*hw_reginit)(struct bfa_s *bfa);
57 void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq);
58 void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
59 void (*hw_msix_install)(struct bfa_s *bfa);
60 void (*hw_msix_uninstall)(struct bfa_s *bfa);
61 void (*hw_isr_mode_set)(struct bfa_s *bfa, bfa_boolean_t msix);
62 void (*hw_msix_getvecs)(struct bfa_s *bfa, u32 *vecmap,
63 u32 *nvecs, u32 *maxvec);
64};
65typedef void (*bfa_cb_iocfc_t) (void *cbarg, enum bfa_status status);
66
67struct bfa_iocfc_s {
68 struct bfa_s *bfa;
69 struct bfa_iocfc_cfg_s cfg;
70 int action;
71
72 u32 req_cq_pi[BFI_IOC_MAX_CQS];
73 u32 rsp_cq_ci[BFI_IOC_MAX_CQS];
74
75 struct bfa_cb_qe_s init_hcb_qe;
76 struct bfa_cb_qe_s stop_hcb_qe;
77 struct bfa_cb_qe_s dis_hcb_qe;
78 struct bfa_cb_qe_s stats_hcb_qe;
79 bfa_boolean_t cfgdone;
80
81 struct bfa_dma_s cfg_info;
82 struct bfi_iocfc_cfg_s *cfginfo;
83 struct bfa_dma_s cfgrsp_dma;
84 struct bfi_iocfc_cfgrsp_s *cfgrsp;
85 struct bfi_iocfc_cfg_reply_s *cfg_reply;
86
87 u8 *stats_kva;
88 u64 stats_pa;
89 struct bfa_fw_stats_s *fw_stats;
90 struct bfa_timer_s stats_timer; /* timer */
91 struct bfa_iocfc_stats_s *stats_ret; /* driver stats location */
92 bfa_status_t stats_status; /* stats/statsclr status */
93 bfa_boolean_t stats_busy; /* outstanding stats */
94 bfa_cb_ioc_t stats_cbfn; /* driver callback function */
95 void *stats_cbarg; /* user callback arg */
96
97 struct bfa_dma_s req_cq_ba[BFI_IOC_MAX_CQS];
98 struct bfa_dma_s req_cq_shadow_ci[BFI_IOC_MAX_CQS];
99 struct bfa_dma_s rsp_cq_ba[BFI_IOC_MAX_CQS];
100 struct bfa_dma_s rsp_cq_shadow_pi[BFI_IOC_MAX_CQS];
101 struct bfa_iocfc_regs_s bfa_regs; /* BFA device registers */
102 struct bfa_hwif_s hwif;
103
104 bfa_cb_iocfc_t updateq_cbfn; /* bios callback function */
105 void *updateq_cbarg; /* bios callback arg */
106};
107
108#define bfa_lpuid(__bfa) bfa_ioc_portid(&(__bfa)->ioc)
109#define bfa_msix_init(__bfa, __nvecs) \
110 (__bfa)->iocfc.hwif.hw_msix_init(__bfa, __nvecs)
111#define bfa_msix_install(__bfa) \
112 (__bfa)->iocfc.hwif.hw_msix_install(__bfa)
113#define bfa_msix_uninstall(__bfa) \
114 (__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa)
115#define bfa_isr_mode_set(__bfa, __msix) \
116 (__bfa)->iocfc.hwif.hw_isr_mode_set(__bfa, __msix)
117#define bfa_msix_getvecs(__bfa, __vecmap, __nvecs, __maxvec) \
118 (__bfa)->iocfc.hwif.hw_msix_getvecs(__bfa, __vecmap, __nvecs, __maxvec)
119
120/*
121 * FC specific IOC functions.
122 */
123void bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
124 u32 *dm_len);
125void bfa_iocfc_attach(struct bfa_s *bfa, void *bfad,
126 struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
127 struct bfa_pcidev_s *pcidev);
128void bfa_iocfc_detach(struct bfa_s *bfa);
129void bfa_iocfc_init(struct bfa_s *bfa);
130void bfa_iocfc_start(struct bfa_s *bfa);
131void bfa_iocfc_stop(struct bfa_s *bfa);
132void bfa_iocfc_isr(void *bfa, struct bfi_mbmsg_s *msg);
133void bfa_iocfc_set_snsbase(struct bfa_s *bfa, u64 snsbase_pa);
134bfa_boolean_t bfa_iocfc_is_operational(struct bfa_s *bfa);
135void bfa_iocfc_reset_queues(struct bfa_s *bfa);
136void bfa_iocfc_updateq(struct bfa_s *bfa, u32 reqq_ba, u32 rspq_ba,
137 u32 reqq_sci, u32 rspq_spi,
138 bfa_cb_iocfc_t cbfn, void *cbarg);
139
140void bfa_msix_all(struct bfa_s *bfa, int vec);
141void bfa_msix_reqq(struct bfa_s *bfa, int vec);
142void bfa_msix_rspq(struct bfa_s *bfa, int vec);
143void bfa_msix_lpu_err(struct bfa_s *bfa, int vec);
144
145void bfa_hwcb_reginit(struct bfa_s *bfa);
146void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq);
147void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
148void bfa_hwcb_msix_install(struct bfa_s *bfa);
149void bfa_hwcb_msix_uninstall(struct bfa_s *bfa);
150void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
151void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap,
152 u32 *nvecs, u32 *maxvec);
153void bfa_hwct_reginit(struct bfa_s *bfa);
154void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq);
155void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
156void bfa_hwct_msix_install(struct bfa_s *bfa);
157void bfa_hwct_msix_uninstall(struct bfa_s *bfa);
158void bfa_hwct_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
159void bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *vecmap,
160 u32 *nvecs, u32 *maxvec);
161
162void bfa_com_meminfo(bfa_boolean_t mincfg, u32 *dm_len);
163void bfa_com_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi,
164 bfa_boolean_t mincfg);
165void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns);
166
167#endif /* __BFA_IOCFC_H__ */
168
diff --git a/drivers/scsi/bfa/bfa_iocfc_q.c b/drivers/scsi/bfa/bfa_iocfc_q.c
new file mode 100644
index 000000000000..500a17df40b2
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_iocfc_q.c
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19#include "bfa_intr_priv.h"
20
21BFA_TRC_FILE(HAL, IOCFC_Q);
22
23void
24bfa_iocfc_updateq(struct bfa_s *bfa, u32 reqq_ba, u32 rspq_ba,
25 u32 reqq_sci, u32 rspq_spi, bfa_cb_iocfc_t cbfn,
26 void *cbarg)
27{
28 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
29 struct bfi_iocfc_updateq_req_s updateq_req;
30
31 iocfc->updateq_cbfn = cbfn;
32 iocfc->updateq_cbarg = cbarg;
33
34 bfi_h2i_set(updateq_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_UPDATEQ_REQ,
35 bfa_lpuid(bfa));
36
37 updateq_req.reqq_ba = bfa_os_htonl(reqq_ba);
38 updateq_req.rspq_ba = bfa_os_htonl(rspq_ba);
39 updateq_req.reqq_sci = bfa_os_htonl(reqq_sci);
40 updateq_req.rspq_spi = bfa_os_htonl(rspq_spi);
41
42 bfa_ioc_mbox_send(&bfa->ioc, &updateq_req,
43 sizeof(struct bfi_iocfc_updateq_req_s));
44}
diff --git a/drivers/scsi/bfa/bfa_ioim.c b/drivers/scsi/bfa/bfa_ioim.c
new file mode 100644
index 000000000000..7ae2552e1e14
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_ioim.c
@@ -0,0 +1,1311 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19#include <cs/bfa_debug.h>
20#include <bfa_cb_ioim_macros.h>
21
22BFA_TRC_FILE(HAL, IOIM);
23
24/*
25 * forward declarations.
26 */
27static bfa_boolean_t bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim);
28static bfa_boolean_t bfa_ioim_sge_setup(struct bfa_ioim_s *ioim);
29static void bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim);
30static bfa_boolean_t bfa_ioim_send_abort(struct bfa_ioim_s *ioim);
31static void bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim);
32static void __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete);
33static void __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete);
34static void __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete);
35static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete);
36static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete);
37
38/**
39 * bfa_ioim_sm
40 */
41
42/**
43 * IO state machine events
44 */
45enum bfa_ioim_event {
46 BFA_IOIM_SM_START = 1, /* io start request from host */
47 BFA_IOIM_SM_COMP_GOOD = 2, /* io good comp, resource free */
48 BFA_IOIM_SM_COMP = 3, /* io comp, resource is free */
49 BFA_IOIM_SM_COMP_UTAG = 4, /* io comp, resource is free */
50 BFA_IOIM_SM_DONE = 5, /* io comp, resource not free */
51 BFA_IOIM_SM_FREE = 6, /* io resource is freed */
52 BFA_IOIM_SM_ABORT = 7, /* abort request from scsi stack */
53 BFA_IOIM_SM_ABORT_COMP = 8, /* abort from f/w */
54 BFA_IOIM_SM_ABORT_DONE = 9, /* abort completion from f/w */
55 BFA_IOIM_SM_QRESUME = 10, /* CQ space available to queue IO */
56 BFA_IOIM_SM_SGALLOCED = 11, /* SG page allocation successful */
57 BFA_IOIM_SM_SQRETRY = 12, /* sequence recovery retry */
58 BFA_IOIM_SM_HCB = 13, /* bfa callback complete */
59 BFA_IOIM_SM_CLEANUP = 14, /* IO cleanup from itnim */
60 BFA_IOIM_SM_TMSTART = 15, /* IO cleanup from tskim */
61 BFA_IOIM_SM_TMDONE = 16, /* IO cleanup from tskim */
62 BFA_IOIM_SM_HWFAIL = 17, /* IOC h/w failure event */
63 BFA_IOIM_SM_IOTOV = 18, /* ITN offline TOV */
64};
65
66/*
67 * forward declaration of IO state machine
68 */
69static void bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim,
70 enum bfa_ioim_event event);
71static void bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim,
72 enum bfa_ioim_event event);
73static void bfa_ioim_sm_active(struct bfa_ioim_s *ioim,
74 enum bfa_ioim_event event);
75static void bfa_ioim_sm_abort(struct bfa_ioim_s *ioim,
76 enum bfa_ioim_event event);
77static void bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim,
78 enum bfa_ioim_event event);
79static void bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim,
80 enum bfa_ioim_event event);
81static void bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim,
82 enum bfa_ioim_event event);
83static void bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim,
84 enum bfa_ioim_event event);
85static void bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim,
86 enum bfa_ioim_event event);
87static void bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim,
88 enum bfa_ioim_event event);
89static void bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim,
90 enum bfa_ioim_event event);
91
92/**
93 * IO is not started (unallocated).
94 */
95static void
96bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
97{
98 bfa_trc_fp(ioim->bfa, ioim->iotag);
99 bfa_trc_fp(ioim->bfa, event);
100
101 switch (event) {
102 case BFA_IOIM_SM_START:
103 if (!bfa_itnim_is_online(ioim->itnim)) {
104 if (!bfa_itnim_hold_io(ioim->itnim)) {
105 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
106 list_del(&ioim->qe);
107 list_add_tail(&ioim->qe,
108 &ioim->fcpim->ioim_comp_q);
109 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
110 __bfa_cb_ioim_pathtov, ioim);
111 } else {
112 list_del(&ioim->qe);
113 list_add_tail(&ioim->qe,
114 &ioim->itnim->pending_q);
115 }
116 break;
117 }
118
119 if (ioim->nsges > BFI_SGE_INLINE) {
120 if (!bfa_ioim_sge_setup(ioim)) {
121 bfa_sm_set_state(ioim, bfa_ioim_sm_sgalloc);
122 return;
123 }
124 }
125
126 if (!bfa_ioim_send_ioreq(ioim)) {
127 bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
128 break;
129 }
130
131 bfa_sm_set_state(ioim, bfa_ioim_sm_active);
132 break;
133
134 case BFA_IOIM_SM_IOTOV:
135 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
136 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
137 __bfa_cb_ioim_pathtov, ioim);
138 break;
139
140 case BFA_IOIM_SM_ABORT:
141 /**
142 * IO in pending queue can get abort requests. Complete abort
143 * requests immediately.
144 */
145 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
146 bfa_assert(bfa_q_is_on_q(&ioim->itnim->pending_q, ioim));
147 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
148 ioim);
149 break;
150
151 default:
152 bfa_assert(0);
153 }
154}
155
156/**
157 * IO is waiting for SG pages.
158 */
159static void
160bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
161{
162 bfa_trc(ioim->bfa, ioim->iotag);
163 bfa_trc(ioim->bfa, event);
164
165 switch (event) {
166 case BFA_IOIM_SM_SGALLOCED:
167 if (!bfa_ioim_send_ioreq(ioim)) {
168 bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
169 break;
170 }
171 bfa_sm_set_state(ioim, bfa_ioim_sm_active);
172 break;
173
174 case BFA_IOIM_SM_CLEANUP:
175 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
176 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
177 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
178 ioim);
179 bfa_ioim_notify_cleanup(ioim);
180 break;
181
182 case BFA_IOIM_SM_ABORT:
183 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
184 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
185 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
186 ioim);
187 break;
188
189 case BFA_IOIM_SM_HWFAIL:
190 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
191 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
192 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
193 ioim);
194 break;
195
196 default:
197 bfa_assert(0);
198 }
199}
200
201/**
202 * IO is active.
203 */
204static void
205bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
206{
207 bfa_trc_fp(ioim->bfa, ioim->iotag);
208 bfa_trc_fp(ioim->bfa, event);
209
210 switch (event) {
211 case BFA_IOIM_SM_COMP_GOOD:
212 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
213 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
214 __bfa_cb_ioim_good_comp, ioim);
215 break;
216
217 case BFA_IOIM_SM_COMP:
218 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
219 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
220 ioim);
221 break;
222
223 case BFA_IOIM_SM_DONE:
224 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
225 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
226 ioim);
227 break;
228
229 case BFA_IOIM_SM_ABORT:
230 ioim->iosp->abort_explicit = BFA_TRUE;
231 ioim->io_cbfn = __bfa_cb_ioim_abort;
232
233 if (bfa_ioim_send_abort(ioim))
234 bfa_sm_set_state(ioim, bfa_ioim_sm_abort);
235 else {
236 bfa_sm_set_state(ioim, bfa_ioim_sm_abort_qfull);
237 bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq,
238 &ioim->iosp->reqq_wait);
239 }
240 break;
241
242 case BFA_IOIM_SM_CLEANUP:
243 ioim->iosp->abort_explicit = BFA_FALSE;
244 ioim->io_cbfn = __bfa_cb_ioim_failed;
245
246 if (bfa_ioim_send_abort(ioim))
247 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
248 else {
249 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
250 bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq,
251 &ioim->iosp->reqq_wait);
252 }
253 break;
254
255 case BFA_IOIM_SM_HWFAIL:
256 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
257 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
258 ioim);
259 break;
260
261 default:
262 bfa_assert(0);
263 }
264}
265
266/**
267 * IO is being aborted, waiting for completion from firmware.
268 */
269static void
270bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
271{
272 bfa_trc(ioim->bfa, ioim->iotag);
273 bfa_trc(ioim->bfa, event);
274
275 switch (event) {
276 case BFA_IOIM_SM_COMP_GOOD:
277 case BFA_IOIM_SM_COMP:
278 case BFA_IOIM_SM_DONE:
279 case BFA_IOIM_SM_FREE:
280 break;
281
282 case BFA_IOIM_SM_ABORT_DONE:
283 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
284 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
285 ioim);
286 break;
287
288 case BFA_IOIM_SM_ABORT_COMP:
289 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
290 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
291 ioim);
292 break;
293
294 case BFA_IOIM_SM_COMP_UTAG:
295 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
296 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
297 ioim);
298 break;
299
300 case BFA_IOIM_SM_CLEANUP:
301 bfa_assert(ioim->iosp->abort_explicit == BFA_TRUE);
302 ioim->iosp->abort_explicit = BFA_FALSE;
303
304 if (bfa_ioim_send_abort(ioim))
305 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
306 else {
307 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
308 bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq,
309 &ioim->iosp->reqq_wait);
310 }
311 break;
312
313 case BFA_IOIM_SM_HWFAIL:
314 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
315 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
316 ioim);
317 break;
318
319 default:
320 bfa_assert(0);
321 }
322}
323
324/**
325 * IO is being cleaned up (implicit abort), waiting for completion from
326 * firmware.
327 */
328static void
329bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
330{
331 bfa_trc(ioim->bfa, ioim->iotag);
332 bfa_trc(ioim->bfa, event);
333
334 switch (event) {
335 case BFA_IOIM_SM_COMP_GOOD:
336 case BFA_IOIM_SM_COMP:
337 case BFA_IOIM_SM_DONE:
338 case BFA_IOIM_SM_FREE:
339 break;
340
341 case BFA_IOIM_SM_ABORT:
342 /**
343 * IO is already being aborted implicitly
344 */
345 ioim->io_cbfn = __bfa_cb_ioim_abort;
346 break;
347
348 case BFA_IOIM_SM_ABORT_DONE:
349 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
350 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
351 bfa_ioim_notify_cleanup(ioim);
352 break;
353
354 case BFA_IOIM_SM_ABORT_COMP:
355 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
356 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
357 bfa_ioim_notify_cleanup(ioim);
358 break;
359
360 case BFA_IOIM_SM_COMP_UTAG:
361 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
362 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
363 bfa_ioim_notify_cleanup(ioim);
364 break;
365
366 case BFA_IOIM_SM_HWFAIL:
367 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
368 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
369 ioim);
370 break;
371
372 case BFA_IOIM_SM_CLEANUP:
373 /**
374 * IO can be in cleanup state already due to TM command. 2nd cleanup
375 * request comes from ITN offline event.
376 */
377 break;
378
379 default:
380 bfa_assert(0);
381 }
382}
383
384/**
385 * IO is waiting for room in request CQ
386 */
387static void
388bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
389{
390 bfa_trc(ioim->bfa, ioim->iotag);
391 bfa_trc(ioim->bfa, event);
392
393 switch (event) {
394 case BFA_IOIM_SM_QRESUME:
395 bfa_sm_set_state(ioim, bfa_ioim_sm_active);
396 bfa_ioim_send_ioreq(ioim);
397 break;
398
399 case BFA_IOIM_SM_ABORT:
400 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
401 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
402 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
403 ioim);
404 break;
405
406 case BFA_IOIM_SM_CLEANUP:
407 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
408 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
409 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
410 ioim);
411 bfa_ioim_notify_cleanup(ioim);
412 break;
413
414 case BFA_IOIM_SM_HWFAIL:
415 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
416 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
417 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
418 ioim);
419 break;
420
421 default:
422 bfa_assert(0);
423 }
424}
425
426/**
427 * Active IO is being aborted, waiting for room in request CQ.
428 */
429static void
430bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
431{
432 bfa_trc(ioim->bfa, ioim->iotag);
433 bfa_trc(ioim->bfa, event);
434
435 switch (event) {
436 case BFA_IOIM_SM_QRESUME:
437 bfa_sm_set_state(ioim, bfa_ioim_sm_abort);
438 bfa_ioim_send_abort(ioim);
439 break;
440
441 case BFA_IOIM_SM_CLEANUP:
442 bfa_assert(ioim->iosp->abort_explicit == BFA_TRUE);
443 ioim->iosp->abort_explicit = BFA_FALSE;
444 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
445 break;
446
447 case BFA_IOIM_SM_COMP_GOOD:
448 case BFA_IOIM_SM_COMP:
449 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
450 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
451 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
452 ioim);
453 break;
454
455 case BFA_IOIM_SM_DONE:
456 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
457 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
458 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
459 ioim);
460 break;
461
462 case BFA_IOIM_SM_HWFAIL:
463 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
464 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
465 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
466 ioim);
467 break;
468
469 default:
470 bfa_assert(0);
471 }
472}
473
474/**
475 * Active IO is being cleaned up, waiting for room in request CQ.
476 */
477static void
478bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
479{
480 bfa_trc(ioim->bfa, ioim->iotag);
481 bfa_trc(ioim->bfa, event);
482
483 switch (event) {
484 case BFA_IOIM_SM_QRESUME:
485 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
486 bfa_ioim_send_abort(ioim);
487 break;
488
489 case BFA_IOIM_SM_ABORT:
490 /**
491 * IO is alraedy being cleaned up implicitly
492 */
493 ioim->io_cbfn = __bfa_cb_ioim_abort;
494 break;
495
496 case BFA_IOIM_SM_COMP_GOOD:
497 case BFA_IOIM_SM_COMP:
498 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
499 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
500 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
501 bfa_ioim_notify_cleanup(ioim);
502 break;
503
504 case BFA_IOIM_SM_DONE:
505 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
506 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
507 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
508 bfa_ioim_notify_cleanup(ioim);
509 break;
510
511 case BFA_IOIM_SM_HWFAIL:
512 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
513 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
514 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
515 ioim);
516 break;
517
518 default:
519 bfa_assert(0);
520 }
521}
522
523/**
524 * IO bfa callback is pending.
525 */
526static void
527bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
528{
529 bfa_trc_fp(ioim->bfa, ioim->iotag);
530 bfa_trc_fp(ioim->bfa, event);
531
532 switch (event) {
533 case BFA_IOIM_SM_HCB:
534 bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
535 bfa_ioim_free(ioim);
536 bfa_cb_ioim_resfree(ioim->bfa->bfad);
537 break;
538
539 case BFA_IOIM_SM_CLEANUP:
540 bfa_ioim_notify_cleanup(ioim);
541 break;
542
543 case BFA_IOIM_SM_HWFAIL:
544 break;
545
546 default:
547 bfa_assert(0);
548 }
549}
550
551/**
552 * IO bfa callback is pending. IO resource cannot be freed.
553 */
554static void
555bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
556{
557 bfa_trc(ioim->bfa, ioim->iotag);
558 bfa_trc(ioim->bfa, event);
559
560 switch (event) {
561 case BFA_IOIM_SM_HCB:
562 bfa_sm_set_state(ioim, bfa_ioim_sm_resfree);
563 list_del(&ioim->qe);
564 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_resfree_q);
565 break;
566
567 case BFA_IOIM_SM_FREE:
568 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
569 break;
570
571 case BFA_IOIM_SM_CLEANUP:
572 bfa_ioim_notify_cleanup(ioim);
573 break;
574
575 case BFA_IOIM_SM_HWFAIL:
576 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
577 break;
578
579 default:
580 bfa_assert(0);
581 }
582}
583
584/**
585 * IO is completed, waiting resource free from firmware.
586 */
587static void
588bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
589{
590 bfa_trc(ioim->bfa, ioim->iotag);
591 bfa_trc(ioim->bfa, event);
592
593 switch (event) {
594 case BFA_IOIM_SM_FREE:
595 bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
596 bfa_ioim_free(ioim);
597 bfa_cb_ioim_resfree(ioim->bfa->bfad);
598 break;
599
600 case BFA_IOIM_SM_CLEANUP:
601 bfa_ioim_notify_cleanup(ioim);
602 break;
603
604 case BFA_IOIM_SM_HWFAIL:
605 break;
606
607 default:
608 bfa_assert(0);
609 }
610}
611
612
613
614/**
615 * bfa_ioim_private
616 */
617
618static void
619__bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete)
620{
621 struct bfa_ioim_s *ioim = cbarg;
622
623 if (!complete) {
624 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
625 return;
626 }
627
628 bfa_cb_ioim_good_comp(ioim->bfa->bfad, ioim->dio);
629}
630
631static void
632__bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete)
633{
634 struct bfa_ioim_s *ioim = cbarg;
635 struct bfi_ioim_rsp_s *m;
636 u8 *snsinfo = NULL;
637 u8 sns_len = 0;
638 s32 residue = 0;
639
640 if (!complete) {
641 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
642 return;
643 }
644
645 m = (struct bfi_ioim_rsp_s *) &ioim->iosp->comp_rspmsg;
646 if (m->io_status == BFI_IOIM_STS_OK) {
647 /**
648 * setup sense information, if present
649 */
650 if (m->scsi_status == SCSI_STATUS_CHECK_CONDITION
651 && m->sns_len) {
652 sns_len = m->sns_len;
653 snsinfo = ioim->iosp->snsinfo;
654 }
655
656 /**
657 * setup residue value correctly for normal completions
658 */
659 if (m->resid_flags == FCP_RESID_UNDER)
660 residue = bfa_os_ntohl(m->residue);
661 if (m->resid_flags == FCP_RESID_OVER) {
662 residue = bfa_os_ntohl(m->residue);
663 residue = -residue;
664 }
665 }
666
667 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, m->io_status,
668 m->scsi_status, sns_len, snsinfo, residue);
669}
670
671static void
672__bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete)
673{
674 struct bfa_ioim_s *ioim = cbarg;
675
676 if (!complete) {
677 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
678 return;
679 }
680
681 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED,
682 0, 0, NULL, 0);
683}
684
685static void
686__bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete)
687{
688 struct bfa_ioim_s *ioim = cbarg;
689
690 if (!complete) {
691 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
692 return;
693 }
694
695 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV,
696 0, 0, NULL, 0);
697}
698
699static void
700__bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete)
701{
702 struct bfa_ioim_s *ioim = cbarg;
703
704 if (!complete) {
705 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
706 return;
707 }
708
709 bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio);
710}
711
712static void
713bfa_ioim_sgpg_alloced(void *cbarg)
714{
715 struct bfa_ioim_s *ioim = cbarg;
716
717 ioim->nsgpgs = BFA_SGPG_NPAGE(ioim->nsges);
718 list_splice_tail_init(&ioim->iosp->sgpg_wqe.sgpg_q, &ioim->sgpg_q);
719 bfa_ioim_sgpg_setup(ioim);
720 bfa_sm_send_event(ioim, BFA_IOIM_SM_SGALLOCED);
721}
722
723/**
724 * Send I/O request to firmware.
725 */
726static bfa_boolean_t
727bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
728{
729 struct bfa_itnim_s *itnim = ioim->itnim;
730 struct bfi_ioim_req_s *m;
731 static struct fcp_cmnd_s cmnd_z0 = { 0 };
732 struct bfi_sge_s *sge;
733 u32 pgdlen = 0;
734
735 /**
736 * check for room in queue to send request now
737 */
738 m = bfa_reqq_next(ioim->bfa, itnim->reqq);
739 if (!m) {
740 bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq,
741 &ioim->iosp->reqq_wait);
742 return BFA_FALSE;
743 }
744
745 /**
746 * build i/o request message next
747 */
748 m->io_tag = bfa_os_htons(ioim->iotag);
749 m->rport_hdl = ioim->itnim->rport->fw_handle;
750 m->io_timeout = bfa_cb_ioim_get_timeout(ioim->dio);
751
752 /**
753 * build inline IO SG element here
754 */
755 sge = &m->sges[0];
756 if (ioim->nsges) {
757 sge->sga = bfa_cb_ioim_get_sgaddr(ioim->dio, 0);
758 pgdlen = bfa_cb_ioim_get_sglen(ioim->dio, 0);
759 sge->sg_len = pgdlen;
760 sge->flags = (ioim->nsges > BFI_SGE_INLINE) ?
761 BFI_SGE_DATA_CPL : BFI_SGE_DATA_LAST;
762 bfa_sge_to_be(sge);
763 sge++;
764 }
765
766 if (ioim->nsges > BFI_SGE_INLINE) {
767 sge->sga = ioim->sgpg->sgpg_pa;
768 } else {
769 sge->sga.a32.addr_lo = 0;
770 sge->sga.a32.addr_hi = 0;
771 }
772 sge->sg_len = pgdlen;
773 sge->flags = BFI_SGE_PGDLEN;
774 bfa_sge_to_be(sge);
775
776 /**
777 * set up I/O command parameters
778 */
779 bfa_os_assign(m->cmnd, cmnd_z0);
780 m->cmnd.lun = bfa_cb_ioim_get_lun(ioim->dio);
781 m->cmnd.iodir = bfa_cb_ioim_get_iodir(ioim->dio);
782 bfa_os_assign(m->cmnd.cdb,
783 *(struct scsi_cdb_s *)bfa_cb_ioim_get_cdb(ioim->dio));
784 m->cmnd.fcp_dl = bfa_os_htonl(bfa_cb_ioim_get_size(ioim->dio));
785
786 /**
787 * set up I/O message header
788 */
789 switch (m->cmnd.iodir) {
790 case FCP_IODIR_READ:
791 bfi_h2i_set(m->mh, BFI_MC_IOIM_READ, 0, bfa_lpuid(ioim->bfa));
792 bfa_stats(itnim, input_reqs);
793 break;
794 case FCP_IODIR_WRITE:
795 bfi_h2i_set(m->mh, BFI_MC_IOIM_WRITE, 0, bfa_lpuid(ioim->bfa));
796 bfa_stats(itnim, output_reqs);
797 break;
798 case FCP_IODIR_RW:
799 bfa_stats(itnim, input_reqs);
800 bfa_stats(itnim, output_reqs);
801 default:
802 bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa));
803 }
804 if (itnim->seq_rec ||
805 (bfa_cb_ioim_get_size(ioim->dio) & (sizeof(u32) - 1)))
806 bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa));
807
808#ifdef IOIM_ADVANCED
809 m->cmnd.crn = bfa_cb_ioim_get_crn(ioim->dio);
810 m->cmnd.priority = bfa_cb_ioim_get_priority(ioim->dio);
811 m->cmnd.taskattr = bfa_cb_ioim_get_taskattr(ioim->dio);
812
813 /**
814 * Handle large CDB (>16 bytes).
815 */
816 m->cmnd.addl_cdb_len = (bfa_cb_ioim_get_cdblen(ioim->dio) -
817 FCP_CMND_CDB_LEN) / sizeof(u32);
818 if (m->cmnd.addl_cdb_len) {
819 bfa_os_memcpy(&m->cmnd.cdb + 1, (struct scsi_cdb_s *)
820 bfa_cb_ioim_get_cdb(ioim->dio) + 1,
821 m->cmnd.addl_cdb_len * sizeof(u32));
822 fcp_cmnd_fcpdl(&m->cmnd) =
823 bfa_os_htonl(bfa_cb_ioim_get_size(ioim->dio));
824 }
825#endif
826
827 /**
828 * queue I/O message to firmware
829 */
830 bfa_reqq_produce(ioim->bfa, itnim->reqq);
831 return BFA_TRUE;
832}
833
834/**
835 * Setup any additional SG pages needed.Inline SG element is setup
836 * at queuing time.
837 */
838static bfa_boolean_t
839bfa_ioim_sge_setup(struct bfa_ioim_s *ioim)
840{
841 u16 nsgpgs;
842
843 bfa_assert(ioim->nsges > BFI_SGE_INLINE);
844
845 /**
846 * allocate SG pages needed
847 */
848 nsgpgs = BFA_SGPG_NPAGE(ioim->nsges);
849 if (!nsgpgs)
850 return BFA_TRUE;
851
852 if (bfa_sgpg_malloc(ioim->bfa, &ioim->sgpg_q, nsgpgs)
853 != BFA_STATUS_OK) {
854 bfa_sgpg_wait(ioim->bfa, &ioim->iosp->sgpg_wqe, nsgpgs);
855 return BFA_FALSE;
856 }
857
858 ioim->nsgpgs = nsgpgs;
859 bfa_ioim_sgpg_setup(ioim);
860
861 return BFA_TRUE;
862}
863
864static void
865bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
866{
867 int sgeid, nsges, i;
868 struct bfi_sge_s *sge;
869 struct bfa_sgpg_s *sgpg;
870 u32 pgcumsz;
871
872 sgeid = BFI_SGE_INLINE;
873 ioim->sgpg = sgpg = bfa_q_first(&ioim->sgpg_q);
874
875 do {
876 sge = sgpg->sgpg->sges;
877 nsges = ioim->nsges - sgeid;
878 if (nsges > BFI_SGPG_DATA_SGES)
879 nsges = BFI_SGPG_DATA_SGES;
880
881 pgcumsz = 0;
882 for (i = 0; i < nsges; i++, sge++, sgeid++) {
883 sge->sga = bfa_cb_ioim_get_sgaddr(ioim->dio, sgeid);
884 sge->sg_len = bfa_cb_ioim_get_sglen(ioim->dio, sgeid);
885 pgcumsz += sge->sg_len;
886
887 /**
888 * set flags
889 */
890 if (i < (nsges - 1))
891 sge->flags = BFI_SGE_DATA;
892 else if (sgeid < (ioim->nsges - 1))
893 sge->flags = BFI_SGE_DATA_CPL;
894 else
895 sge->flags = BFI_SGE_DATA_LAST;
896 }
897
898 sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg);
899
900 /**
901 * set the link element of each page
902 */
903 if (sgeid == ioim->nsges) {
904 sge->flags = BFI_SGE_PGDLEN;
905 sge->sga.a32.addr_lo = 0;
906 sge->sga.a32.addr_hi = 0;
907 } else {
908 sge->flags = BFI_SGE_LINK;
909 sge->sga = sgpg->sgpg_pa;
910 }
911 sge->sg_len = pgcumsz;
912 } while (sgeid < ioim->nsges);
913}
914
915/**
916 * Send I/O abort request to firmware.
917 */
918static bfa_boolean_t
919bfa_ioim_send_abort(struct bfa_ioim_s *ioim)
920{
921 struct bfa_itnim_s *itnim = ioim->itnim;
922 struct bfi_ioim_abort_req_s *m;
923 enum bfi_ioim_h2i msgop;
924
925 /**
926 * check for room in queue to send request now
927 */
928 m = bfa_reqq_next(ioim->bfa, itnim->reqq);
929 if (!m)
930 return BFA_FALSE;
931
932 /**
933 * build i/o request message next
934 */
935 if (ioim->iosp->abort_explicit)
936 msgop = BFI_IOIM_H2I_IOABORT_REQ;
937 else
938 msgop = BFI_IOIM_H2I_IOCLEANUP_REQ;
939
940 bfi_h2i_set(m->mh, BFI_MC_IOIM, msgop, bfa_lpuid(ioim->bfa));
941 m->io_tag = bfa_os_htons(ioim->iotag);
942 m->abort_tag = ++ioim->abort_tag;
943
944 /**
945 * queue I/O message to firmware
946 */
947 bfa_reqq_produce(ioim->bfa, itnim->reqq);
948 return BFA_TRUE;
949}
950
951/**
952 * Call to resume any I/O requests waiting for room in request queue.
953 */
954static void
955bfa_ioim_qresume(void *cbarg)
956{
957 struct bfa_ioim_s *ioim = cbarg;
958
959 bfa_fcpim_stats(ioim->fcpim, qresumes);
960 bfa_sm_send_event(ioim, BFA_IOIM_SM_QRESUME);
961}
962
963
964static void
965bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim)
966{
967 /**
968 * Move IO from itnim queue to fcpim global queue since itnim will be
969 * freed.
970 */
971 list_del(&ioim->qe);
972 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
973
974 if (!ioim->iosp->tskim) {
975 if (ioim->fcpim->delay_comp && ioim->itnim->iotov_active) {
976 bfa_cb_dequeue(&ioim->hcb_qe);
977 list_del(&ioim->qe);
978 list_add_tail(&ioim->qe, &ioim->itnim->delay_comp_q);
979 }
980 bfa_itnim_iodone(ioim->itnim);
981 } else
982 bfa_tskim_iodone(ioim->iosp->tskim);
983}
984
985/**
986 * or after the link comes back.
987 */
988void
989bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov)
990{
991 /**
992 * If path tov timer expired, failback with PATHTOV status - these
993 * IO requests are not normally retried by IO stack.
994 *
995 * Otherwise device cameback online and fail it with normal failed
996 * status so that IO stack retries these failed IO requests.
997 */
998 if (iotov)
999 ioim->io_cbfn = __bfa_cb_ioim_pathtov;
1000 else
1001 ioim->io_cbfn = __bfa_cb_ioim_failed;
1002
1003 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1004
1005 /**
1006 * Move IO to fcpim global queue since itnim will be
1007 * freed.
1008 */
1009 list_del(&ioim->qe);
1010 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
1011}
1012
1013
1014
1015/**
1016 * bfa_ioim_friend
1017 */
1018
1019/**
1020 * Memory allocation and initialization.
1021 */
1022void
1023bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
1024{
1025 struct bfa_ioim_s *ioim;
1026 struct bfa_ioim_sp_s *iosp;
1027 u16 i;
1028 u8 *snsinfo;
1029 u32 snsbufsz;
1030
1031 /**
1032 * claim memory first
1033 */
1034 ioim = (struct bfa_ioim_s *) bfa_meminfo_kva(minfo);
1035 fcpim->ioim_arr = ioim;
1036 bfa_meminfo_kva(minfo) = (u8 *) (ioim + fcpim->num_ioim_reqs);
1037
1038 iosp = (struct bfa_ioim_sp_s *) bfa_meminfo_kva(minfo);
1039 fcpim->ioim_sp_arr = iosp;
1040 bfa_meminfo_kva(minfo) = (u8 *) (iosp + fcpim->num_ioim_reqs);
1041
1042 /**
1043 * Claim DMA memory for per IO sense data.
1044 */
1045 snsbufsz = fcpim->num_ioim_reqs * BFI_IOIM_SNSLEN;
1046 fcpim->snsbase.pa = bfa_meminfo_dma_phys(minfo);
1047 bfa_meminfo_dma_phys(minfo) += snsbufsz;
1048
1049 fcpim->snsbase.kva = bfa_meminfo_dma_virt(minfo);
1050 bfa_meminfo_dma_virt(minfo) += snsbufsz;
1051 snsinfo = fcpim->snsbase.kva;
1052 bfa_iocfc_set_snsbase(fcpim->bfa, fcpim->snsbase.pa);
1053
1054 /**
1055 * Initialize ioim free queues
1056 */
1057 INIT_LIST_HEAD(&fcpim->ioim_free_q);
1058 INIT_LIST_HEAD(&fcpim->ioim_resfree_q);
1059 INIT_LIST_HEAD(&fcpim->ioim_comp_q);
1060
1061 for (i = 0; i < fcpim->num_ioim_reqs;
1062 i++, ioim++, iosp++, snsinfo += BFI_IOIM_SNSLEN) {
1063 /*
1064 * initialize IOIM
1065 */
1066 bfa_os_memset(ioim, 0, sizeof(struct bfa_ioim_s));
1067 ioim->iotag = i;
1068 ioim->bfa = fcpim->bfa;
1069 ioim->fcpim = fcpim;
1070 ioim->iosp = iosp;
1071 iosp->snsinfo = snsinfo;
1072 INIT_LIST_HEAD(&ioim->sgpg_q);
1073 bfa_reqq_winit(&ioim->iosp->reqq_wait,
1074 bfa_ioim_qresume, ioim);
1075 bfa_sgpg_winit(&ioim->iosp->sgpg_wqe,
1076 bfa_ioim_sgpg_alloced, ioim);
1077 bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
1078
1079 list_add_tail(&ioim->qe, &fcpim->ioim_free_q);
1080 }
1081}
1082
1083/**
1084 * Driver detach time call.
1085 */
1086void
1087bfa_ioim_detach(struct bfa_fcpim_mod_s *fcpim)
1088{
1089}
1090
1091void
1092bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
1093{
1094 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
1095 struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m;
1096 struct bfa_ioim_s *ioim;
1097 u16 iotag;
1098 enum bfa_ioim_event evt = BFA_IOIM_SM_COMP;
1099
1100 iotag = bfa_os_ntohs(rsp->io_tag);
1101
1102 ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
1103 bfa_assert(ioim->iotag == iotag);
1104
1105 bfa_trc(ioim->bfa, ioim->iotag);
1106 bfa_trc(ioim->bfa, rsp->io_status);
1107 bfa_trc(ioim->bfa, rsp->reuse_io_tag);
1108
1109 if (bfa_sm_cmp_state(ioim, bfa_ioim_sm_active))
1110 bfa_os_assign(ioim->iosp->comp_rspmsg, *m);
1111
1112 switch (rsp->io_status) {
1113 case BFI_IOIM_STS_OK:
1114 bfa_fcpim_stats(fcpim, iocomp_ok);
1115 if (rsp->reuse_io_tag == 0)
1116 evt = BFA_IOIM_SM_DONE;
1117 else
1118 evt = BFA_IOIM_SM_COMP;
1119 break;
1120
1121 case BFI_IOIM_STS_TIMEDOUT:
1122 case BFI_IOIM_STS_ABORTED:
1123 rsp->io_status = BFI_IOIM_STS_ABORTED;
1124 bfa_fcpim_stats(fcpim, iocomp_aborted);
1125 if (rsp->reuse_io_tag == 0)
1126 evt = BFA_IOIM_SM_DONE;
1127 else
1128 evt = BFA_IOIM_SM_COMP;
1129 break;
1130
1131 case BFI_IOIM_STS_PROTO_ERR:
1132 bfa_fcpim_stats(fcpim, iocom_proto_err);
1133 bfa_assert(rsp->reuse_io_tag);
1134 evt = BFA_IOIM_SM_COMP;
1135 break;
1136
1137 case BFI_IOIM_STS_SQER_NEEDED:
1138 bfa_fcpim_stats(fcpim, iocom_sqer_needed);
1139 bfa_assert(rsp->reuse_io_tag == 0);
1140 evt = BFA_IOIM_SM_SQRETRY;
1141 break;
1142
1143 case BFI_IOIM_STS_RES_FREE:
1144 bfa_fcpim_stats(fcpim, iocom_res_free);
1145 evt = BFA_IOIM_SM_FREE;
1146 break;
1147
1148 case BFI_IOIM_STS_HOST_ABORTED:
1149 bfa_fcpim_stats(fcpim, iocom_hostabrts);
1150 if (rsp->abort_tag != ioim->abort_tag) {
1151 bfa_trc(ioim->bfa, rsp->abort_tag);
1152 bfa_trc(ioim->bfa, ioim->abort_tag);
1153 return;
1154 }
1155
1156 if (rsp->reuse_io_tag)
1157 evt = BFA_IOIM_SM_ABORT_COMP;
1158 else
1159 evt = BFA_IOIM_SM_ABORT_DONE;
1160 break;
1161
1162 case BFI_IOIM_STS_UTAG:
1163 bfa_fcpim_stats(fcpim, iocom_utags);
1164 evt = BFA_IOIM_SM_COMP_UTAG;
1165 break;
1166
1167 default:
1168 bfa_assert(0);
1169 }
1170
1171 bfa_sm_send_event(ioim, evt);
1172}
1173
1174void
1175bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
1176{
1177 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
1178 struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m;
1179 struct bfa_ioim_s *ioim;
1180 u16 iotag;
1181
1182 iotag = bfa_os_ntohs(rsp->io_tag);
1183
1184 ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
1185 bfa_assert(ioim->iotag == iotag);
1186
1187 bfa_trc_fp(ioim->bfa, ioim->iotag);
1188 bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD);
1189}
1190
1191/**
1192 * Called by itnim to clean up IO while going offline.
1193 */
1194void
1195bfa_ioim_cleanup(struct bfa_ioim_s *ioim)
1196{
1197 bfa_trc(ioim->bfa, ioim->iotag);
1198 bfa_fcpim_stats(ioim->fcpim, io_cleanups);
1199
1200 ioim->iosp->tskim = NULL;
1201 bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP);
1202}
1203
1204void
1205bfa_ioim_cleanup_tm(struct bfa_ioim_s *ioim, struct bfa_tskim_s *tskim)
1206{
1207 bfa_trc(ioim->bfa, ioim->iotag);
1208 bfa_fcpim_stats(ioim->fcpim, io_tmaborts);
1209
1210 ioim->iosp->tskim = tskim;
1211 bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP);
1212}
1213
1214/**
1215 * IOC failure handling.
1216 */
1217void
1218bfa_ioim_iocdisable(struct bfa_ioim_s *ioim)
1219{
1220 bfa_sm_send_event(ioim, BFA_IOIM_SM_HWFAIL);
1221}
1222
1223/**
1224 * IO offline TOV popped. Fail the pending IO.
1225 */
1226void
1227bfa_ioim_tov(struct bfa_ioim_s *ioim)
1228{
1229 bfa_sm_send_event(ioim, BFA_IOIM_SM_IOTOV);
1230}
1231
1232
1233
1234/**
1235 * bfa_ioim_api
1236 */
1237
1238/**
1239 * Allocate IOIM resource for initiator mode I/O request.
1240 */
1241struct bfa_ioim_s *
1242bfa_ioim_alloc(struct bfa_s *bfa, struct bfad_ioim_s *dio,
1243 struct bfa_itnim_s *itnim, u16 nsges)
1244{
1245 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
1246 struct bfa_ioim_s *ioim;
1247
1248 /**
1249 * alocate IOIM resource
1250 */
1251 bfa_q_deq(&fcpim->ioim_free_q, &ioim);
1252 if (!ioim) {
1253 bfa_fcpim_stats(fcpim, no_iotags);
1254 return NULL;
1255 }
1256
1257 ioim->dio = dio;
1258 ioim->itnim = itnim;
1259 ioim->nsges = nsges;
1260 ioim->nsgpgs = 0;
1261
1262 bfa_stats(fcpim, total_ios);
1263 bfa_stats(itnim, ios);
1264 fcpim->ios_active++;
1265
1266 list_add_tail(&ioim->qe, &itnim->io_q);
1267 bfa_trc_fp(ioim->bfa, ioim->iotag);
1268
1269 return ioim;
1270}
1271
1272void
1273bfa_ioim_free(struct bfa_ioim_s *ioim)
1274{
1275 struct bfa_fcpim_mod_s *fcpim = ioim->fcpim;
1276
1277 bfa_trc_fp(ioim->bfa, ioim->iotag);
1278 bfa_assert_fp(bfa_sm_cmp_state(ioim, bfa_ioim_sm_uninit));
1279
1280 bfa_assert_fp(list_empty(&ioim->sgpg_q)
1281 || (ioim->nsges > BFI_SGE_INLINE));
1282
1283 if (ioim->nsgpgs > 0)
1284 bfa_sgpg_mfree(ioim->bfa, &ioim->sgpg_q, ioim->nsgpgs);
1285
1286 bfa_stats(ioim->itnim, io_comps);
1287 fcpim->ios_active--;
1288
1289 list_del(&ioim->qe);
1290 list_add_tail(&ioim->qe, &fcpim->ioim_free_q);
1291}
1292
1293void
1294bfa_ioim_start(struct bfa_ioim_s *ioim)
1295{
1296 bfa_trc_fp(ioim->bfa, ioim->iotag);
1297 bfa_sm_send_event(ioim, BFA_IOIM_SM_START);
1298}
1299
1300/**
1301 * Driver I/O abort request.
1302 */
1303void
1304bfa_ioim_abort(struct bfa_ioim_s *ioim)
1305{
1306 bfa_trc(ioim->bfa, ioim->iotag);
1307 bfa_fcpim_stats(ioim->fcpim, io_aborts);
1308 bfa_sm_send_event(ioim, BFA_IOIM_SM_ABORT);
1309}
1310
1311
diff --git a/drivers/scsi/bfa/bfa_itnim.c b/drivers/scsi/bfa/bfa_itnim.c
new file mode 100644
index 000000000000..4d5c61a4f85c
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_itnim.c
@@ -0,0 +1,1088 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19#include <bfa_fcpim.h>
20#include "bfa_fcpim_priv.h"
21
22BFA_TRC_FILE(HAL, ITNIM);
23
24#define BFA_ITNIM_FROM_TAG(_fcpim, _tag) \
25 ((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1)))
26
27#define bfa_fcpim_additn(__itnim) \
28 list_add_tail(&(__itnim)->qe, &(__itnim)->fcpim->itnim_q)
29#define bfa_fcpim_delitn(__itnim) do { \
30 bfa_assert(bfa_q_is_on_q(&(__itnim)->fcpim->itnim_q, __itnim)); \
31 list_del(&(__itnim)->qe); \
32 bfa_assert(list_empty(&(__itnim)->io_q)); \
33 bfa_assert(list_empty(&(__itnim)->io_cleanup_q)); \
34 bfa_assert(list_empty(&(__itnim)->pending_q)); \
35} while (0)
36
37#define bfa_itnim_online_cb(__itnim) do { \
38 if ((__itnim)->bfa->fcs) \
39 bfa_cb_itnim_online((__itnim)->ditn); \
40 else { \
41 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \
42 __bfa_cb_itnim_online, (__itnim)); \
43 } \
44} while (0)
45
46#define bfa_itnim_offline_cb(__itnim) do { \
47 if ((__itnim)->bfa->fcs) \
48 bfa_cb_itnim_offline((__itnim)->ditn); \
49 else { \
50 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \
51 __bfa_cb_itnim_offline, (__itnim)); \
52 } \
53} while (0)
54
55#define bfa_itnim_sler_cb(__itnim) do { \
56 if ((__itnim)->bfa->fcs) \
57 bfa_cb_itnim_sler((__itnim)->ditn); \
58 else { \
59 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \
60 __bfa_cb_itnim_sler, (__itnim)); \
61 } \
62} while (0)
63
64/*
65 * forward declarations
66 */
67static void bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim);
68static bfa_boolean_t bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim);
69static bfa_boolean_t bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim);
70static void bfa_itnim_cleanp_comp(void *itnim_cbarg);
71static void bfa_itnim_cleanup(struct bfa_itnim_s *itnim);
72static void __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete);
73static void __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete);
74static void __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete);
75static void bfa_itnim_iotov_online(struct bfa_itnim_s *itnim);
76static void bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim);
77static void bfa_itnim_iotov(void *itnim_arg);
78static void bfa_itnim_iotov_start(struct bfa_itnim_s *itnim);
79static void bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim);
80static void bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim);
81
82/**
83 * bfa_itnim_sm BFA itnim state machine
84 */
85
86
87enum bfa_itnim_event {
88 BFA_ITNIM_SM_CREATE = 1, /* itnim is created */
89 BFA_ITNIM_SM_ONLINE = 2, /* itnim is online */
90 BFA_ITNIM_SM_OFFLINE = 3, /* itnim is offline */
91 BFA_ITNIM_SM_FWRSP = 4, /* firmware response */
92 BFA_ITNIM_SM_DELETE = 5, /* deleting an existing itnim */
93 BFA_ITNIM_SM_CLEANUP = 6, /* IO cleanup completion */
94 BFA_ITNIM_SM_SLER = 7, /* second level error recovery */
95 BFA_ITNIM_SM_HWFAIL = 8, /* IOC h/w failure event */
96 BFA_ITNIM_SM_QRESUME = 9, /* queue space available */
97};
98
99static void bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim,
100 enum bfa_itnim_event event);
101static void bfa_itnim_sm_created(struct bfa_itnim_s *itnim,
102 enum bfa_itnim_event event);
103static void bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim,
104 enum bfa_itnim_event event);
105static void bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
106 enum bfa_itnim_event event);
107static void bfa_itnim_sm_online(struct bfa_itnim_s *itnim,
108 enum bfa_itnim_event event);
109static void bfa_itnim_sm_sler(struct bfa_itnim_s *itnim,
110 enum bfa_itnim_event event);
111static void bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
112 enum bfa_itnim_event event);
113static void bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
114 enum bfa_itnim_event event);
115static void bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim,
116 enum bfa_itnim_event event);
117static void bfa_itnim_sm_offline(struct bfa_itnim_s *itnim,
118 enum bfa_itnim_event event);
119static void bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
120 enum bfa_itnim_event event);
121static void bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim,
122 enum bfa_itnim_event event);
123static void bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
124 enum bfa_itnim_event event);
125static void bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
126 enum bfa_itnim_event event);
127static void bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
128 enum bfa_itnim_event event);
129
130/**
131 * Beginning/unallocated state - no events expected.
132 */
133static void
134bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
135{
136 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
137 bfa_trc(itnim->bfa, event);
138
139 switch (event) {
140 case BFA_ITNIM_SM_CREATE:
141 bfa_sm_set_state(itnim, bfa_itnim_sm_created);
142 itnim->is_online = BFA_FALSE;
143 bfa_fcpim_additn(itnim);
144 break;
145
146 default:
147 bfa_assert(0);
148 }
149}
150
151/**
152 * Beginning state, only online event expected.
153 */
154static void
155bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
156{
157 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
158 bfa_trc(itnim->bfa, event);
159
160 switch (event) {
161 case BFA_ITNIM_SM_ONLINE:
162 if (bfa_itnim_send_fwcreate(itnim))
163 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
164 else
165 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
166 break;
167
168 case BFA_ITNIM_SM_DELETE:
169 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
170 bfa_fcpim_delitn(itnim);
171 break;
172
173 case BFA_ITNIM_SM_HWFAIL:
174 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
175 break;
176
177 default:
178 bfa_assert(0);
179 }
180}
181
182/**
183 * Waiting for itnim create response from firmware.
184 */
185static void
186bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
187{
188 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
189 bfa_trc(itnim->bfa, event);
190
191 switch (event) {
192 case BFA_ITNIM_SM_FWRSP:
193 bfa_sm_set_state(itnim, bfa_itnim_sm_online);
194 itnim->is_online = BFA_TRUE;
195 bfa_itnim_iotov_online(itnim);
196 bfa_itnim_online_cb(itnim);
197 break;
198
199 case BFA_ITNIM_SM_DELETE:
200 bfa_sm_set_state(itnim, bfa_itnim_sm_delete_pending);
201 break;
202
203 case BFA_ITNIM_SM_OFFLINE:
204 if (bfa_itnim_send_fwdelete(itnim))
205 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
206 else
207 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull);
208 break;
209
210 case BFA_ITNIM_SM_HWFAIL:
211 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
212 break;
213
214 default:
215 bfa_assert(0);
216 }
217}
218
219static void
220bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
221 enum bfa_itnim_event event)
222{
223 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
224 bfa_trc(itnim->bfa, event);
225
226 switch (event) {
227 case BFA_ITNIM_SM_QRESUME:
228 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
229 bfa_itnim_send_fwcreate(itnim);
230 break;
231
232 case BFA_ITNIM_SM_DELETE:
233 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
234 bfa_reqq_wcancel(&itnim->reqq_wait);
235 bfa_fcpim_delitn(itnim);
236 break;
237
238 case BFA_ITNIM_SM_OFFLINE:
239 bfa_sm_set_state(itnim, bfa_itnim_sm_offline);
240 bfa_reqq_wcancel(&itnim->reqq_wait);
241 bfa_itnim_offline_cb(itnim);
242 break;
243
244 case BFA_ITNIM_SM_HWFAIL:
245 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
246 bfa_reqq_wcancel(&itnim->reqq_wait);
247 break;
248
249 default:
250 bfa_assert(0);
251 }
252}
253
254/**
255 * Waiting for itnim create response from firmware, a delete is pending.
256 */
257static void
258bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
259 enum bfa_itnim_event event)
260{
261 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
262 bfa_trc(itnim->bfa, event);
263
264 switch (event) {
265 case BFA_ITNIM_SM_FWRSP:
266 if (bfa_itnim_send_fwdelete(itnim))
267 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
268 else
269 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
270 break;
271
272 case BFA_ITNIM_SM_HWFAIL:
273 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
274 bfa_fcpim_delitn(itnim);
275 break;
276
277 default:
278 bfa_assert(0);
279 }
280}
281
282/**
283 * Online state - normal parking state.
284 */
285static void
286bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
287{
288 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
289 bfa_trc(itnim->bfa, event);
290
291 switch (event) {
292 case BFA_ITNIM_SM_OFFLINE:
293 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline);
294 itnim->is_online = BFA_FALSE;
295 bfa_itnim_iotov_start(itnim);
296 bfa_itnim_cleanup(itnim);
297 break;
298
299 case BFA_ITNIM_SM_DELETE:
300 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
301 itnim->is_online = BFA_FALSE;
302 bfa_itnim_cleanup(itnim);
303 break;
304
305 case BFA_ITNIM_SM_SLER:
306 bfa_sm_set_state(itnim, bfa_itnim_sm_sler);
307 itnim->is_online = BFA_FALSE;
308 bfa_itnim_iotov_start(itnim);
309 bfa_itnim_sler_cb(itnim);
310 break;
311
312 case BFA_ITNIM_SM_HWFAIL:
313 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
314 itnim->is_online = BFA_FALSE;
315 bfa_itnim_iotov_start(itnim);
316 bfa_itnim_iocdisable_cleanup(itnim);
317 break;
318
319 default:
320 bfa_assert(0);
321 }
322}
323
324/**
325 * Second level error recovery need.
326 */
327static void
328bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
329{
330 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
331 bfa_trc(itnim->bfa, event);
332
333 switch (event) {
334 case BFA_ITNIM_SM_OFFLINE:
335 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline);
336 bfa_itnim_cleanup(itnim);
337 break;
338
339 case BFA_ITNIM_SM_DELETE:
340 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
341 bfa_itnim_cleanup(itnim);
342 bfa_itnim_iotov_delete(itnim);
343 break;
344
345 case BFA_ITNIM_SM_HWFAIL:
346 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
347 bfa_itnim_iocdisable_cleanup(itnim);
348 break;
349
350 default:
351 bfa_assert(0);
352 }
353}
354
355/**
356 * Going offline. Waiting for active IO cleanup.
357 */
358static void
359bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
360 enum bfa_itnim_event event)
361{
362 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
363 bfa_trc(itnim->bfa, event);
364
365 switch (event) {
366 case BFA_ITNIM_SM_CLEANUP:
367 if (bfa_itnim_send_fwdelete(itnim))
368 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
369 else
370 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull);
371 break;
372
373 case BFA_ITNIM_SM_DELETE:
374 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
375 bfa_itnim_iotov_delete(itnim);
376 break;
377
378 case BFA_ITNIM_SM_HWFAIL:
379 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
380 bfa_itnim_iocdisable_cleanup(itnim);
381 bfa_itnim_offline_cb(itnim);
382 break;
383
384 case BFA_ITNIM_SM_SLER:
385 break;
386
387 default:
388 bfa_assert(0);
389 }
390}
391
392/**
393 * Deleting itnim. Waiting for active IO cleanup.
394 */
395static void
396bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
397 enum bfa_itnim_event event)
398{
399 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
400 bfa_trc(itnim->bfa, event);
401
402 switch (event) {
403 case BFA_ITNIM_SM_CLEANUP:
404 if (bfa_itnim_send_fwdelete(itnim))
405 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
406 else
407 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
408 break;
409
410 case BFA_ITNIM_SM_HWFAIL:
411 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
412 bfa_itnim_iocdisable_cleanup(itnim);
413 break;
414
415 default:
416 bfa_assert(0);
417 }
418}
419
420/**
421 * Rport offline. Fimrware itnim is being deleted - awaiting f/w response.
422 */
423static void
424bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
425{
426 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
427 bfa_trc(itnim->bfa, event);
428
429 switch (event) {
430 case BFA_ITNIM_SM_FWRSP:
431 bfa_sm_set_state(itnim, bfa_itnim_sm_offline);
432 bfa_itnim_offline_cb(itnim);
433 break;
434
435 case BFA_ITNIM_SM_DELETE:
436 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
437 break;
438
439 case BFA_ITNIM_SM_HWFAIL:
440 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
441 bfa_itnim_offline_cb(itnim);
442 break;
443
444 default:
445 bfa_assert(0);
446 }
447}
448
449static void
450bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
451 enum bfa_itnim_event event)
452{
453 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
454 bfa_trc(itnim->bfa, event);
455
456 switch (event) {
457 case BFA_ITNIM_SM_QRESUME:
458 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
459 bfa_itnim_send_fwdelete(itnim);
460 break;
461
462 case BFA_ITNIM_SM_DELETE:
463 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
464 break;
465
466 case BFA_ITNIM_SM_HWFAIL:
467 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
468 bfa_reqq_wcancel(&itnim->reqq_wait);
469 bfa_itnim_offline_cb(itnim);
470 break;
471
472 default:
473 bfa_assert(0);
474 }
475}
476
477/**
478 * Offline state.
479 */
480static void
481bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
482{
483 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
484 bfa_trc(itnim->bfa, event);
485
486 switch (event) {
487 case BFA_ITNIM_SM_DELETE:
488 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
489 bfa_itnim_iotov_delete(itnim);
490 bfa_fcpim_delitn(itnim);
491 break;
492
493 case BFA_ITNIM_SM_ONLINE:
494 if (bfa_itnim_send_fwcreate(itnim))
495 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
496 else
497 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
498 break;
499
500 case BFA_ITNIM_SM_HWFAIL:
501 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
502 break;
503
504 default:
505 bfa_assert(0);
506 }
507}
508
509/**
510 * IOC h/w failed state.
511 */
512static void
513bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
514 enum bfa_itnim_event event)
515{
516 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
517 bfa_trc(itnim->bfa, event);
518
519 switch (event) {
520 case BFA_ITNIM_SM_DELETE:
521 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
522 bfa_itnim_iotov_delete(itnim);
523 bfa_fcpim_delitn(itnim);
524 break;
525
526 case BFA_ITNIM_SM_OFFLINE:
527 bfa_itnim_offline_cb(itnim);
528 break;
529
530 case BFA_ITNIM_SM_ONLINE:
531 if (bfa_itnim_send_fwcreate(itnim))
532 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
533 else
534 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
535 break;
536
537 case BFA_ITNIM_SM_HWFAIL:
538 break;
539
540 default:
541 bfa_assert(0);
542 }
543}
544
545/**
546 * Itnim is deleted, waiting for firmware response to delete.
547 */
548static void
549bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
550{
551 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
552 bfa_trc(itnim->bfa, event);
553
554 switch (event) {
555 case BFA_ITNIM_SM_FWRSP:
556 case BFA_ITNIM_SM_HWFAIL:
557 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
558 bfa_fcpim_delitn(itnim);
559 break;
560
561 default:
562 bfa_assert(0);
563 }
564}
565
566static void
567bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
568 enum bfa_itnim_event event)
569{
570 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
571 bfa_trc(itnim->bfa, event);
572
573 switch (event) {
574 case BFA_ITNIM_SM_QRESUME:
575 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
576 bfa_itnim_send_fwdelete(itnim);
577 break;
578
579 case BFA_ITNIM_SM_HWFAIL:
580 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
581 bfa_reqq_wcancel(&itnim->reqq_wait);
582 bfa_fcpim_delitn(itnim);
583 break;
584
585 default:
586 bfa_assert(0);
587 }
588}
589
590
591
592/**
593 * bfa_itnim_private
594 */
595
596/**
597 * Initiate cleanup of all IOs on an IOC failure.
598 */
599static void
600bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim)
601{
602 struct bfa_tskim_s *tskim;
603 struct bfa_ioim_s *ioim;
604 struct list_head *qe, *qen;
605
606 list_for_each_safe(qe, qen, &itnim->tsk_q) {
607 tskim = (struct bfa_tskim_s *) qe;
608 bfa_tskim_iocdisable(tskim);
609 }
610
611 list_for_each_safe(qe, qen, &itnim->io_q) {
612 ioim = (struct bfa_ioim_s *) qe;
613 bfa_ioim_iocdisable(ioim);
614 }
615
616 /**
617 * For IO request in pending queue, we pretend an early timeout.
618 */
619 list_for_each_safe(qe, qen, &itnim->pending_q) {
620 ioim = (struct bfa_ioim_s *) qe;
621 bfa_ioim_tov(ioim);
622 }
623
624 list_for_each_safe(qe, qen, &itnim->io_cleanup_q) {
625 ioim = (struct bfa_ioim_s *) qe;
626 bfa_ioim_iocdisable(ioim);
627 }
628}
629
630/**
631 * IO cleanup completion
632 */
633static void
634bfa_itnim_cleanp_comp(void *itnim_cbarg)
635{
636 struct bfa_itnim_s *itnim = itnim_cbarg;
637
638 bfa_stats(itnim, cleanup_comps);
639 bfa_sm_send_event(itnim, BFA_ITNIM_SM_CLEANUP);
640}
641
642/**
643 * Initiate cleanup of all IOs.
644 */
645static void
646bfa_itnim_cleanup(struct bfa_itnim_s *itnim)
647{
648 struct bfa_ioim_s *ioim;
649 struct bfa_tskim_s *tskim;
650 struct list_head *qe, *qen;
651
652 bfa_wc_init(&itnim->wc, bfa_itnim_cleanp_comp, itnim);
653
654 list_for_each_safe(qe, qen, &itnim->io_q) {
655 ioim = (struct bfa_ioim_s *) qe;
656
657 /**
658 * Move IO to a cleanup queue from active queue so that a later
659 * TM will not pickup this IO.
660 */
661 list_del(&ioim->qe);
662 list_add_tail(&ioim->qe, &itnim->io_cleanup_q);
663
664 bfa_wc_up(&itnim->wc);
665 bfa_ioim_cleanup(ioim);
666 }
667
668 list_for_each_safe(qe, qen, &itnim->tsk_q) {
669 tskim = (struct bfa_tskim_s *) qe;
670 bfa_wc_up(&itnim->wc);
671 bfa_tskim_cleanup(tskim);
672 }
673
674 bfa_wc_wait(&itnim->wc);
675}
676
677static void
678__bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete)
679{
680 struct bfa_itnim_s *itnim = cbarg;
681
682 if (complete)
683 bfa_cb_itnim_online(itnim->ditn);
684}
685
686static void
687__bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete)
688{
689 struct bfa_itnim_s *itnim = cbarg;
690
691 if (complete)
692 bfa_cb_itnim_offline(itnim->ditn);
693}
694
695static void
696__bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete)
697{
698 struct bfa_itnim_s *itnim = cbarg;
699
700 if (complete)
701 bfa_cb_itnim_sler(itnim->ditn);
702}
703
704/**
705 * Call to resume any I/O requests waiting for room in request queue.
706 */
707static void
708bfa_itnim_qresume(void *cbarg)
709{
710 struct bfa_itnim_s *itnim = cbarg;
711
712 bfa_sm_send_event(itnim, BFA_ITNIM_SM_QRESUME);
713}
714
715
716
717
718/**
719 * bfa_itnim_public
720 */
721
722void
723bfa_itnim_iodone(struct bfa_itnim_s *itnim)
724{
725 bfa_wc_down(&itnim->wc);
726}
727
728void
729bfa_itnim_tskdone(struct bfa_itnim_s *itnim)
730{
731 bfa_wc_down(&itnim->wc);
732}
733
734void
735bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
736 u32 *dm_len)
737{
738 /**
739 * ITN memory
740 */
741 *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_itnim_s);
742}
743
744void
745bfa_itnim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
746{
747 struct bfa_s *bfa = fcpim->bfa;
748 struct bfa_itnim_s *itnim;
749 int i;
750
751 INIT_LIST_HEAD(&fcpim->itnim_q);
752
753 itnim = (struct bfa_itnim_s *) bfa_meminfo_kva(minfo);
754 fcpim->itnim_arr = itnim;
755
756 for (i = 0; i < fcpim->num_itnims; i++, itnim++) {
757 bfa_os_memset(itnim, 0, sizeof(struct bfa_itnim_s));
758 itnim->bfa = bfa;
759 itnim->fcpim = fcpim;
760 itnim->reqq = BFA_REQQ_QOS_LO;
761 itnim->rport = BFA_RPORT_FROM_TAG(bfa, i);
762 itnim->iotov_active = BFA_FALSE;
763 bfa_reqq_winit(&itnim->reqq_wait, bfa_itnim_qresume, itnim);
764
765 INIT_LIST_HEAD(&itnim->io_q);
766 INIT_LIST_HEAD(&itnim->io_cleanup_q);
767 INIT_LIST_HEAD(&itnim->pending_q);
768 INIT_LIST_HEAD(&itnim->tsk_q);
769 INIT_LIST_HEAD(&itnim->delay_comp_q);
770 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
771 }
772
773 bfa_meminfo_kva(minfo) = (u8 *) itnim;
774}
775
776void
777bfa_itnim_iocdisable(struct bfa_itnim_s *itnim)
778{
779 bfa_stats(itnim, ioc_disabled);
780 bfa_sm_send_event(itnim, BFA_ITNIM_SM_HWFAIL);
781}
782
783static bfa_boolean_t
784bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim)
785{
786 struct bfi_itnim_create_req_s *m;
787
788 itnim->msg_no++;
789
790 /**
791 * check for room in queue to send request now
792 */
793 m = bfa_reqq_next(itnim->bfa, itnim->reqq);
794 if (!m) {
795 bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait);
796 return BFA_FALSE;
797 }
798
799 bfi_h2i_set(m->mh, BFI_MC_ITNIM, BFI_ITNIM_H2I_CREATE_REQ,
800 bfa_lpuid(itnim->bfa));
801 m->fw_handle = itnim->rport->fw_handle;
802 m->class = FC_CLASS_3;
803 m->seq_rec = itnim->seq_rec;
804 m->msg_no = itnim->msg_no;
805
806 /**
807 * queue I/O message to firmware
808 */
809 bfa_reqq_produce(itnim->bfa, itnim->reqq);
810 return BFA_TRUE;
811}
812
813static bfa_boolean_t
814bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim)
815{
816 struct bfi_itnim_delete_req_s *m;
817
818 /**
819 * check for room in queue to send request now
820 */
821 m = bfa_reqq_next(itnim->bfa, itnim->reqq);
822 if (!m) {
823 bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait);
824 return BFA_FALSE;
825 }
826
827 bfi_h2i_set(m->mh, BFI_MC_ITNIM, BFI_ITNIM_H2I_DELETE_REQ,
828 bfa_lpuid(itnim->bfa));
829 m->fw_handle = itnim->rport->fw_handle;
830
831 /**
832 * queue I/O message to firmware
833 */
834 bfa_reqq_produce(itnim->bfa, itnim->reqq);
835 return BFA_TRUE;
836}
837
838/**
839 * Cleanup all pending failed inflight requests.
840 */
841static void
842bfa_itnim_delayed_comp(struct bfa_itnim_s *itnim, bfa_boolean_t iotov)
843{
844 struct bfa_ioim_s *ioim;
845 struct list_head *qe, *qen;
846
847 list_for_each_safe(qe, qen, &itnim->delay_comp_q) {
848 ioim = (struct bfa_ioim_s *)qe;
849 bfa_ioim_delayed_comp(ioim, iotov);
850 }
851}
852
853/**
854 * Start all pending IO requests.
855 */
856static void
857bfa_itnim_iotov_online(struct bfa_itnim_s *itnim)
858{
859 struct bfa_ioim_s *ioim;
860
861 bfa_itnim_iotov_stop(itnim);
862
863 /**
864 * Abort all inflight IO requests in the queue
865 */
866 bfa_itnim_delayed_comp(itnim, BFA_FALSE);
867
868 /**
869 * Start all pending IO requests.
870 */
871 while (!list_empty(&itnim->pending_q)) {
872 bfa_q_deq(&itnim->pending_q, &ioim);
873 list_add_tail(&ioim->qe, &itnim->io_q);
874 bfa_ioim_start(ioim);
875 }
876}
877
878/**
879 * Fail all pending IO requests
880 */
881static void
882bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim)
883{
884 struct bfa_ioim_s *ioim;
885
886 /**
887 * Fail all inflight IO requests in the queue
888 */
889 bfa_itnim_delayed_comp(itnim, BFA_TRUE);
890
891 /**
892 * Fail any pending IO requests.
893 */
894 while (!list_empty(&itnim->pending_q)) {
895 bfa_q_deq(&itnim->pending_q, &ioim);
896 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
897 bfa_ioim_tov(ioim);
898 }
899}
900
901/**
902 * IO TOV timer callback. Fail any pending IO requests.
903 */
904static void
905bfa_itnim_iotov(void *itnim_arg)
906{
907 struct bfa_itnim_s *itnim = itnim_arg;
908
909 itnim->iotov_active = BFA_FALSE;
910
911 bfa_cb_itnim_tov_begin(itnim->ditn);
912 bfa_itnim_iotov_cleanup(itnim);
913 bfa_cb_itnim_tov(itnim->ditn);
914}
915
916/**
917 * Start IO TOV timer for failing back pending IO requests in offline state.
918 */
919static void
920bfa_itnim_iotov_start(struct bfa_itnim_s *itnim)
921{
922 if (itnim->fcpim->path_tov > 0) {
923
924 itnim->iotov_active = BFA_TRUE;
925 bfa_assert(bfa_itnim_hold_io(itnim));
926 bfa_timer_start(itnim->bfa, &itnim->timer,
927 bfa_itnim_iotov, itnim, itnim->fcpim->path_tov);
928 }
929}
930
931/**
932 * Stop IO TOV timer.
933 */
934static void
935bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim)
936{
937 if (itnim->iotov_active) {
938 itnim->iotov_active = BFA_FALSE;
939 bfa_timer_stop(&itnim->timer);
940 }
941}
942
943/**
944 * Stop IO TOV timer.
945 */
946static void
947bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim)
948{
949 bfa_boolean_t pathtov_active = BFA_FALSE;
950
951 if (itnim->iotov_active)
952 pathtov_active = BFA_TRUE;
953
954 bfa_itnim_iotov_stop(itnim);
955 if (pathtov_active)
956 bfa_cb_itnim_tov_begin(itnim->ditn);
957 bfa_itnim_iotov_cleanup(itnim);
958 if (pathtov_active)
959 bfa_cb_itnim_tov(itnim->ditn);
960}
961
962
963
964/**
965 * bfa_itnim_public
966 */
967
968/**
969 * Itnim interrupt processing.
970 */
971void
972bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
973{
974 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
975 union bfi_itnim_i2h_msg_u msg;
976 struct bfa_itnim_s *itnim;
977
978 bfa_trc(bfa, m->mhdr.msg_id);
979
980 msg.msg = m;
981
982 switch (m->mhdr.msg_id) {
983 case BFI_ITNIM_I2H_CREATE_RSP:
984 itnim = BFA_ITNIM_FROM_TAG(fcpim,
985 msg.create_rsp->bfa_handle);
986 bfa_assert(msg.create_rsp->status == BFA_STATUS_OK);
987 bfa_stats(itnim, create_comps);
988 bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
989 break;
990
991 case BFI_ITNIM_I2H_DELETE_RSP:
992 itnim = BFA_ITNIM_FROM_TAG(fcpim,
993 msg.delete_rsp->bfa_handle);
994 bfa_assert(msg.delete_rsp->status == BFA_STATUS_OK);
995 bfa_stats(itnim, delete_comps);
996 bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
997 break;
998
999 case BFI_ITNIM_I2H_SLER_EVENT:
1000 itnim = BFA_ITNIM_FROM_TAG(fcpim,
1001 msg.sler_event->bfa_handle);
1002 bfa_stats(itnim, sler_events);
1003 bfa_sm_send_event(itnim, BFA_ITNIM_SM_SLER);
1004 break;
1005
1006 default:
1007 bfa_trc(bfa, m->mhdr.msg_id);
1008 bfa_assert(0);
1009 }
1010}
1011
1012
1013
1014/**
1015 * bfa_itnim_api
1016 */
1017
1018struct bfa_itnim_s *
1019bfa_itnim_create(struct bfa_s *bfa, struct bfa_rport_s *rport, void *ditn)
1020{
1021 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
1022 struct bfa_itnim_s *itnim;
1023
1024 itnim = BFA_ITNIM_FROM_TAG(fcpim, rport->rport_tag);
1025 bfa_assert(itnim->rport == rport);
1026
1027 itnim->ditn = ditn;
1028
1029 bfa_stats(itnim, creates);
1030 bfa_sm_send_event(itnim, BFA_ITNIM_SM_CREATE);
1031
1032 return (itnim);
1033}
1034
1035void
1036bfa_itnim_delete(struct bfa_itnim_s *itnim)
1037{
1038 bfa_stats(itnim, deletes);
1039 bfa_sm_send_event(itnim, BFA_ITNIM_SM_DELETE);
1040}
1041
1042void
1043bfa_itnim_online(struct bfa_itnim_s *itnim, bfa_boolean_t seq_rec)
1044{
1045 itnim->seq_rec = seq_rec;
1046 bfa_stats(itnim, onlines);
1047 bfa_sm_send_event(itnim, BFA_ITNIM_SM_ONLINE);
1048}
1049
1050void
1051bfa_itnim_offline(struct bfa_itnim_s *itnim)
1052{
1053 bfa_stats(itnim, offlines);
1054 bfa_sm_send_event(itnim, BFA_ITNIM_SM_OFFLINE);
1055}
1056
1057/**
1058 * Return true if itnim is considered offline for holding off IO request.
1059 * IO is not held if itnim is being deleted.
1060 */
1061bfa_boolean_t
1062bfa_itnim_hold_io(struct bfa_itnim_s *itnim)
1063{
1064 return (
1065 itnim->fcpim->path_tov && itnim->iotov_active &&
1066 (bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwcreate) ||
1067 bfa_sm_cmp_state(itnim, bfa_itnim_sm_sler) ||
1068 bfa_sm_cmp_state(itnim, bfa_itnim_sm_cleanup_offline) ||
1069 bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwdelete) ||
1070 bfa_sm_cmp_state(itnim, bfa_itnim_sm_offline) ||
1071 bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable))
1072);
1073}
1074
1075void
1076bfa_itnim_get_stats(struct bfa_itnim_s *itnim,
1077 struct bfa_itnim_hal_stats_s *stats)
1078{
1079 *stats = itnim->stats;
1080}
1081
1082void
1083bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
1084{
1085 bfa_os_memset(&itnim->stats, 0, sizeof(itnim->stats));
1086}
1087
1088
diff --git a/drivers/scsi/bfa/bfa_log.c b/drivers/scsi/bfa/bfa_log.c
new file mode 100644
index 000000000000..c2735e55cf03
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_log.c
@@ -0,0 +1,346 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_log.c BFA log library
20 */
21
22#include <bfa_os_inc.h>
23#include <cs/bfa_log.h>
24
25/*
26 * global log info structure
27 */
28struct bfa_log_info_s {
29 u32 start_idx; /* start index for a module */
30 u32 total_count; /* total count for a module */
31 enum bfa_log_severity level; /* global log level */
32 bfa_log_cb_t cbfn; /* callback function */
33};
34
35static struct bfa_log_info_s bfa_log_info[BFA_LOG_MODULE_ID_MAX + 1];
36static u32 bfa_log_msg_total_count;
37static int bfa_log_initialized;
38
39static char *bfa_log_severity[] =
40 { "[none]", "[critical]", "[error]", "[warn]", "[info]", "" };
41
42/**
43 * BFA log library initialization
44 *
45 * The log library initialization includes the following,
46 * - set log instance name and callback function
47 * - read the message array generated from xml files
48 * - calculate start index for each module
49 * - calculate message count for each module
50 * - perform error checking
51 *
52 * @param[in] log_mod - log module info
53 * @param[in] instance_name - instance name
54 * @param[in] cbfn - callback function
55 *
56 * It return 0 on success, or -1 on failure
57 */
58int
59bfa_log_init(struct bfa_log_mod_s *log_mod, char *instance_name,
60 bfa_log_cb_t cbfn)
61{
62 struct bfa_log_msgdef_s *msg;
63 u32 pre_mod_id = 0;
64 u32 cur_mod_id = 0;
65 u32 i, pre_idx, idx, msg_id;
66
67 /*
68 * set instance name
69 */
70 if (log_mod) {
71 strncpy(log_mod->instance_info, instance_name,
72 sizeof(log_mod->instance_info));
73 log_mod->cbfn = cbfn;
74 for (i = 0; i <= BFA_LOG_MODULE_ID_MAX; i++)
75 log_mod->log_level[i] = BFA_LOG_WARNING;
76 }
77
78 if (bfa_log_initialized)
79 return 0;
80
81 for (i = 0; i <= BFA_LOG_MODULE_ID_MAX; i++) {
82 bfa_log_info[i].start_idx = 0;
83 bfa_log_info[i].total_count = 0;
84 bfa_log_info[i].level = BFA_LOG_WARNING;
85 bfa_log_info[i].cbfn = cbfn;
86 }
87
88 pre_idx = 0;
89 idx = 0;
90 msg = bfa_log_msg_array;
91 msg_id = BFA_LOG_GET_MSG_ID(msg);
92 pre_mod_id = BFA_LOG_GET_MOD_ID(msg_id);
93 while (msg_id != 0) {
94 cur_mod_id = BFA_LOG_GET_MOD_ID(msg_id);
95
96 if (cur_mod_id > BFA_LOG_MODULE_ID_MAX) {
97 cbfn(log_mod, msg_id,
98 "%s%s log: module id %u out of range\n",
99 BFA_LOG_CAT_NAME,
100 bfa_log_severity[BFA_LOG_ERROR],
101 cur_mod_id);
102 return -1;
103 }
104
105 if (pre_mod_id > BFA_LOG_MODULE_ID_MAX) {
106 cbfn(log_mod, msg_id,
107 "%s%s log: module id %u out of range\n",
108 BFA_LOG_CAT_NAME,
109 bfa_log_severity[BFA_LOG_ERROR],
110 pre_mod_id);
111 return -1;
112 }
113
114 if (cur_mod_id != pre_mod_id) {
115 bfa_log_info[pre_mod_id].start_idx = pre_idx;
116 bfa_log_info[pre_mod_id].total_count = idx - pre_idx;
117 pre_mod_id = cur_mod_id;
118 pre_idx = idx;
119 }
120
121 idx++;
122 msg++;
123 msg_id = BFA_LOG_GET_MSG_ID(msg);
124 }
125
126 bfa_log_info[cur_mod_id].start_idx = pre_idx;
127 bfa_log_info[cur_mod_id].total_count = idx - pre_idx;
128 bfa_log_msg_total_count = idx;
129
130 cbfn(log_mod, msg_id, "%s%s log: init OK, msg total count %u\n",
131 BFA_LOG_CAT_NAME,
132 bfa_log_severity[BFA_LOG_INFO], bfa_log_msg_total_count);
133
134 bfa_log_initialized = 1;
135
136 return 0;
137}
138
139/**
140 * BFA log set log level for a module
141 *
142 * @param[in] log_mod - log module info
143 * @param[in] mod_id - module id
144 * @param[in] log_level - log severity level
145 *
146 * It return BFA_STATUS_OK on success, or > 0 on failure
147 */
148bfa_status_t
149bfa_log_set_level(struct bfa_log_mod_s *log_mod, int mod_id,
150 enum bfa_log_severity log_level)
151{
152 if (mod_id <= BFA_LOG_UNUSED_ID || mod_id > BFA_LOG_MODULE_ID_MAX)
153 return BFA_STATUS_EINVAL;
154
155 if (log_level <= BFA_LOG_INVALID || log_level > BFA_LOG_LEVEL_MAX)
156 return BFA_STATUS_EINVAL;
157
158 if (log_mod)
159 log_mod->log_level[mod_id] = log_level;
160 else
161 bfa_log_info[mod_id].level = log_level;
162
163 return BFA_STATUS_OK;
164}
165
166/**
167 * BFA log set log level for all modules
168 *
169 * @param[in] log_mod - log module info
170 * @param[in] log_level - log severity level
171 *
172 * It return BFA_STATUS_OK on success, or > 0 on failure
173 */
174bfa_status_t
175bfa_log_set_level_all(struct bfa_log_mod_s *log_mod,
176 enum bfa_log_severity log_level)
177{
178 int mod_id = BFA_LOG_UNUSED_ID + 1;
179
180 if (log_level <= BFA_LOG_INVALID || log_level > BFA_LOG_LEVEL_MAX)
181 return BFA_STATUS_EINVAL;
182
183 if (log_mod) {
184 for (; mod_id <= BFA_LOG_MODULE_ID_MAX; mod_id++)
185 log_mod->log_level[mod_id] = log_level;
186 } else {
187 for (; mod_id <= BFA_LOG_MODULE_ID_MAX; mod_id++)
188 bfa_log_info[mod_id].level = log_level;
189 }
190
191 return BFA_STATUS_OK;
192}
193
194/**
195 * BFA log set log level for all aen sub-modules
196 *
197 * @param[in] log_mod - log module info
198 * @param[in] log_level - log severity level
199 *
200 * It return BFA_STATUS_OK on success, or > 0 on failure
201 */
202bfa_status_t
203bfa_log_set_level_aen(struct bfa_log_mod_s *log_mod,
204 enum bfa_log_severity log_level)
205{
206 int mod_id = BFA_LOG_AEN_MIN + 1;
207
208 if (log_mod) {
209 for (; mod_id <= BFA_LOG_AEN_MAX; mod_id++)
210 log_mod->log_level[mod_id] = log_level;
211 } else {
212 for (; mod_id <= BFA_LOG_AEN_MAX; mod_id++)
213 bfa_log_info[mod_id].level = log_level;
214 }
215
216 return BFA_STATUS_OK;
217}
218
219/**
220 * BFA log get log level for a module
221 *
222 * @param[in] log_mod - log module info
223 * @param[in] mod_id - module id
224 *
225 * It returns log level or -1 on error
226 */
227enum bfa_log_severity
228bfa_log_get_level(struct bfa_log_mod_s *log_mod, int mod_id)
229{
230 if (mod_id <= BFA_LOG_UNUSED_ID || mod_id > BFA_LOG_MODULE_ID_MAX)
231 return BFA_LOG_INVALID;
232
233 if (log_mod)
234 return (log_mod->log_level[mod_id]);
235 else
236 return (bfa_log_info[mod_id].level);
237}
238
239enum bfa_log_severity
240bfa_log_get_msg_level(struct bfa_log_mod_s *log_mod, u32 msg_id)
241{
242 struct bfa_log_msgdef_s *msg;
243 u32 mod = BFA_LOG_GET_MOD_ID(msg_id);
244 u32 idx = BFA_LOG_GET_MSG_IDX(msg_id) - 1;
245
246 if (!bfa_log_initialized)
247 return BFA_LOG_INVALID;
248
249 if (mod > BFA_LOG_MODULE_ID_MAX)
250 return BFA_LOG_INVALID;
251
252 if (idx >= bfa_log_info[mod].total_count) {
253 bfa_log_info[mod].cbfn(log_mod, msg_id,
254 "%s%s log: inconsistent idx %u vs. total count %u\n",
255 BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR], idx,
256 bfa_log_info[mod].total_count);
257 return BFA_LOG_INVALID;
258 }
259
260 msg = bfa_log_msg_array + bfa_log_info[mod].start_idx + idx;
261 if (msg_id != BFA_LOG_GET_MSG_ID(msg)) {
262 bfa_log_info[mod].cbfn(log_mod, msg_id,
263 "%s%s log: inconsistent msg id %u array msg id %u\n",
264 BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR],
265 msg_id, BFA_LOG_GET_MSG_ID(msg));
266 return BFA_LOG_INVALID;
267 }
268
269 return BFA_LOG_GET_SEVERITY(msg);
270}
271
272/**
273 * BFA log message handling
274 *
275 * BFA log message handling finds the message based on message id and prints
276 * out the message based on its format and arguments. It also does prefix
277 * the severity etc.
278 *
279 * @param[in] log_mod - log module info
280 * @param[in] msg_id - message id
281 * @param[in] ... - message arguments
282 *
283 * It return 0 on success, or -1 on errors
284 */
285int
286bfa_log(struct bfa_log_mod_s *log_mod, u32 msg_id, ...)
287{
288 va_list ap;
289 char buf[256];
290 struct bfa_log_msgdef_s *msg;
291 int log_level;
292 u32 mod = BFA_LOG_GET_MOD_ID(msg_id);
293 u32 idx = BFA_LOG_GET_MSG_IDX(msg_id) - 1;
294
295 if (!bfa_log_initialized)
296 return -1;
297
298 if (mod > BFA_LOG_MODULE_ID_MAX)
299 return -1;
300
301 if (idx >= bfa_log_info[mod].total_count) {
302 bfa_log_info[mod].
303 cbfn
304 (log_mod, msg_id,
305 "%s%s log: inconsistent idx %u vs. total count %u\n",
306 BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR], idx,
307 bfa_log_info[mod].total_count);
308 return -1;
309 }
310
311 msg = bfa_log_msg_array + bfa_log_info[mod].start_idx + idx;
312 if (msg_id != BFA_LOG_GET_MSG_ID(msg)) {
313 bfa_log_info[mod].
314 cbfn
315 (log_mod, msg_id,
316 "%s%s log: inconsistent msg id %u array msg id %u\n",
317 BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR],
318 msg_id, BFA_LOG_GET_MSG_ID(msg));
319 return -1;
320 }
321
322 log_level = log_mod ? log_mod->log_level[mod] : bfa_log_info[mod].level;
323 if ((BFA_LOG_GET_SEVERITY(msg) > log_level) &&
324 (msg->attributes != BFA_LOG_ATTR_NONE))
325 return 0;
326
327 va_start(ap, msg_id);
328 bfa_os_vsprintf(buf, BFA_LOG_GET_MSG_FMT_STRING(msg), ap);
329 va_end(ap);
330
331 if (log_mod)
332 log_mod->cbfn(log_mod, msg_id, "%s[%s]%s%s %s: %s\n",
333 BFA_LOG_CAT_NAME, log_mod->instance_info,
334 bfa_log_severity[BFA_LOG_GET_SEVERITY(msg)],
335 (msg->attributes & BFA_LOG_ATTR_AUDIT)
336 ? " (audit) " : "", msg->msg_value, buf);
337 else
338 bfa_log_info[mod].cbfn(log_mod, msg_id, "%s%s%s %s: %s\n",
339 BFA_LOG_CAT_NAME,
340 bfa_log_severity[BFA_LOG_GET_SEVERITY(msg)],
341 (msg->attributes & BFA_LOG_ATTR_AUDIT) ?
342 " (audit) " : "", msg->msg_value, buf);
343
344 return 0;
345}
346
diff --git a/drivers/scsi/bfa/bfa_log_module.c b/drivers/scsi/bfa/bfa_log_module.c
new file mode 100644
index 000000000000..5c154d341d69
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_log_module.c
@@ -0,0 +1,451 @@
1/*
2 * Copyright (c) 2005-2009 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 <cs/bfa_log.h>
19#include <aen/bfa_aen_adapter.h>
20#include <aen/bfa_aen_audit.h>
21#include <aen/bfa_aen_ethport.h>
22#include <aen/bfa_aen_ioc.h>
23#include <aen/bfa_aen_itnim.h>
24#include <aen/bfa_aen_lport.h>
25#include <aen/bfa_aen_port.h>
26#include <aen/bfa_aen_rport.h>
27#include <log/bfa_log_fcs.h>
28#include <log/bfa_log_hal.h>
29#include <log/bfa_log_linux.h>
30#include <log/bfa_log_wdrv.h>
31
32struct bfa_log_msgdef_s bfa_log_msg_array[] = {
33
34
35/* messages define for BFA_AEN_CAT_ADAPTER Module */
36{BFA_AEN_ADAPTER_ADD, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
37 "BFA_AEN_ADAPTER_ADD",
38 "New adapter found: SN = %s, base port WWN = %s.",
39 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
40
41{BFA_AEN_ADAPTER_REMOVE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
42 BFA_LOG_WARNING, "BFA_AEN_ADAPTER_REMOVE",
43 "Adapter removed: SN = %s.",
44 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
45
46
47
48
49/* messages define for BFA_AEN_CAT_AUDIT Module */
50{BFA_AEN_AUDIT_AUTH_ENABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
51 BFA_LOG_INFO, "BFA_AEN_AUDIT_AUTH_ENABLE",
52 "Authentication enabled for base port: WWN = %s.",
53 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
54
55{BFA_AEN_AUDIT_AUTH_DISABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
56 BFA_LOG_INFO, "BFA_AEN_AUDIT_AUTH_DISABLE",
57 "Authentication disabled for base port: WWN = %s.",
58 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
59
60
61
62
63/* messages define for BFA_AEN_CAT_ETHPORT Module */
64{BFA_AEN_ETHPORT_LINKUP, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
65 "BFA_AEN_ETHPORT_LINKUP",
66 "Base port ethernet linkup: mac = %s.",
67 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
68
69{BFA_AEN_ETHPORT_LINKDOWN, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
70 "BFA_AEN_ETHPORT_LINKDOWN",
71 "Base port ethernet linkdown: mac = %s.",
72 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
73
74{BFA_AEN_ETHPORT_ENABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
75 "BFA_AEN_ETHPORT_ENABLE",
76 "Base port ethernet interface enabled: mac = %s.",
77 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
78
79{BFA_AEN_ETHPORT_DISABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
80 "BFA_AEN_ETHPORT_DISABLE",
81 "Base port ethernet interface disabled: mac = %s.",
82 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
83
84
85
86
87/* messages define for BFA_AEN_CAT_IOC Module */
88{BFA_AEN_IOC_HBGOOD, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
89 "BFA_AEN_IOC_HBGOOD",
90 "Heart Beat of IOC %d is good.",
91 ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1},
92
93{BFA_AEN_IOC_HBFAIL, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_CRITICAL,
94 "BFA_AEN_IOC_HBFAIL",
95 "Heart Beat of IOC %d has failed.",
96 ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1},
97
98{BFA_AEN_IOC_ENABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
99 "BFA_AEN_IOC_ENABLE",
100 "IOC %d is enabled.",
101 ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1},
102
103{BFA_AEN_IOC_DISABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
104 "BFA_AEN_IOC_DISABLE",
105 "IOC %d is disabled.",
106 ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1},
107
108{BFA_AEN_IOC_FWMISMATCH, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
109 BFA_LOG_CRITICAL, "BFA_AEN_IOC_FWMISMATCH",
110 "Running firmware version is incompatible with the driver version.",
111 (0), 0},
112
113
114
115
116/* messages define for BFA_AEN_CAT_ITNIM Module */
117{BFA_AEN_ITNIM_ONLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
118 "BFA_AEN_ITNIM_ONLINE",
119 "Target (WWN = %s) is online for initiator (WWN = %s).",
120 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
121
122{BFA_AEN_ITNIM_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
123 "BFA_AEN_ITNIM_OFFLINE",
124 "Target (WWN = %s) offlined by initiator (WWN = %s).",
125 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
126
127{BFA_AEN_ITNIM_DISCONNECT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
128 BFA_LOG_ERROR, "BFA_AEN_ITNIM_DISCONNECT",
129 "Target (WWN = %s) connectivity lost for initiator (WWN = %s).",
130 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
131
132
133
134
135/* messages define for BFA_AEN_CAT_LPORT Module */
136{BFA_AEN_LPORT_NEW, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
137 "BFA_AEN_LPORT_NEW",
138 "New logical port created: WWN = %s, Role = %s.",
139 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
140
141{BFA_AEN_LPORT_DELETE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
142 "BFA_AEN_LPORT_DELETE",
143 "Logical port deleted: WWN = %s, Role = %s.",
144 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
145
146{BFA_AEN_LPORT_ONLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
147 "BFA_AEN_LPORT_ONLINE",
148 "Logical port online: WWN = %s, Role = %s.",
149 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
150
151{BFA_AEN_LPORT_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
152 "BFA_AEN_LPORT_OFFLINE",
153 "Logical port taken offline: WWN = %s, Role = %s.",
154 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
155
156{BFA_AEN_LPORT_DISCONNECT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
157 BFA_LOG_ERROR, "BFA_AEN_LPORT_DISCONNECT",
158 "Logical port lost fabric connectivity: WWN = %s, Role = %s.",
159 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
160
161{BFA_AEN_LPORT_NEW_PROP, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
162 "BFA_AEN_LPORT_NEW_PROP",
163 "New virtual port created using proprietary interface: WWN = %s, Role = %s.",
164 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
165
166{BFA_AEN_LPORT_DELETE_PROP, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
167 BFA_LOG_INFO, "BFA_AEN_LPORT_DELETE_PROP",
168 "Virtual port deleted using proprietary interface: WWN = %s, Role = %s.",
169 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
170
171{BFA_AEN_LPORT_NEW_STANDARD, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
172 BFA_LOG_INFO, "BFA_AEN_LPORT_NEW_STANDARD",
173 "New virtual port created using standard interface: WWN = %s, Role = %s.",
174 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
175
176{BFA_AEN_LPORT_DELETE_STANDARD, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
177 BFA_LOG_INFO, "BFA_AEN_LPORT_DELETE_STANDARD",
178 "Virtual port deleted using standard interface: WWN = %s, Role = %s.",
179 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
180
181{BFA_AEN_LPORT_NPIV_DUP_WWN, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
182 BFA_LOG_WARNING, "BFA_AEN_LPORT_NPIV_DUP_WWN",
183 "Virtual port login failed. Duplicate WWN = %s reported by fabric.",
184 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
185
186{BFA_AEN_LPORT_NPIV_FABRIC_MAX, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
187 BFA_LOG_WARNING, "BFA_AEN_LPORT_NPIV_FABRIC_MAX",
188 "Virtual port (WWN = %s) login failed. Max NPIV ports already exist in"
189 " fabric/fport.",
190 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
191
192{BFA_AEN_LPORT_NPIV_UNKNOWN, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
193 BFA_LOG_WARNING, "BFA_AEN_LPORT_NPIV_UNKNOWN",
194 "Virtual port (WWN = %s) login failed.",
195 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
196
197
198
199
200/* messages define for BFA_AEN_CAT_PORT Module */
201{BFA_AEN_PORT_ONLINE, BFA_LOG_ATTR_NONE, BFA_LOG_INFO, "BFA_AEN_PORT_ONLINE",
202 "Base port online: WWN = %s.",
203 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
204
205{BFA_AEN_PORT_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_WARNING,
206 "BFA_AEN_PORT_OFFLINE",
207 "Base port offline: WWN = %s.",
208 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
209
210{BFA_AEN_PORT_RLIR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
211 "BFA_AEN_PORT_RLIR",
212 "RLIR event not supported.",
213 (0), 0},
214
215{BFA_AEN_PORT_SFP_INSERT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
216 "BFA_AEN_PORT_SFP_INSERT",
217 "New SFP found: WWN/MAC = %s.",
218 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
219
220{BFA_AEN_PORT_SFP_REMOVE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
221 BFA_LOG_WARNING, "BFA_AEN_PORT_SFP_REMOVE",
222 "SFP removed: WWN/MAC = %s.",
223 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
224
225{BFA_AEN_PORT_SFP_POM, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_WARNING,
226 "BFA_AEN_PORT_SFP_POM",
227 "SFP POM level to %s: WWN/MAC = %s.",
228 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
229
230{BFA_AEN_PORT_ENABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
231 "BFA_AEN_PORT_ENABLE",
232 "Base port enabled: WWN = %s.",
233 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
234
235{BFA_AEN_PORT_DISABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
236 "BFA_AEN_PORT_DISABLE",
237 "Base port disabled: WWN = %s.",
238 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
239
240{BFA_AEN_PORT_AUTH_ON, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
241 "BFA_AEN_PORT_AUTH_ON",
242 "Authentication successful for base port: WWN = %s.",
243 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
244
245{BFA_AEN_PORT_AUTH_OFF, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_ERROR,
246 "BFA_AEN_PORT_AUTH_OFF",
247 "Authentication unsuccessful for base port: WWN = %s.",
248 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
249
250{BFA_AEN_PORT_DISCONNECT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_ERROR,
251 "BFA_AEN_PORT_DISCONNECT",
252 "Base port (WWN = %s) lost fabric connectivity.",
253 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
254
255{BFA_AEN_PORT_QOS_NEG, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_WARNING,
256 "BFA_AEN_PORT_QOS_NEG",
257 "QOS negotiation failed for base port: WWN = %s.",
258 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
259
260{BFA_AEN_PORT_FABRIC_NAME_CHANGE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
261 BFA_LOG_WARNING, "BFA_AEN_PORT_FABRIC_NAME_CHANGE",
262 "Base port WWN = %s, Fabric WWN = %s.",
263 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
264
265{BFA_AEN_PORT_SFP_ACCESS_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
266 BFA_LOG_WARNING, "BFA_AEN_PORT_SFP_ACCESS_ERROR",
267 "SFP access error: WWN/MAC = %s.",
268 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
269
270{BFA_AEN_PORT_SFP_UNSUPPORT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
271 BFA_LOG_WARNING, "BFA_AEN_PORT_SFP_UNSUPPORT",
272 "Unsupported SFP found: WWN/MAC = %s.",
273 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
274
275
276
277
278/* messages define for BFA_AEN_CAT_RPORT Module */
279{BFA_AEN_RPORT_ONLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
280 "BFA_AEN_RPORT_ONLINE",
281 "Remote port (WWN = %s) online for logical port (WWN = %s).",
282 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
283
284{BFA_AEN_RPORT_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
285 "BFA_AEN_RPORT_OFFLINE",
286 "Remote port (WWN = %s) offlined by logical port (WWN = %s).",
287 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
288
289{BFA_AEN_RPORT_DISCONNECT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
290 BFA_LOG_ERROR, "BFA_AEN_RPORT_DISCONNECT",
291 "Remote port (WWN = %s) connectivity lost for logical port (WWN = %s).",
292 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
293
294{BFA_AEN_RPORT_QOS_PRIO, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
295 "BFA_AEN_RPORT_QOS_PRIO",
296 "QOS priority changed to %s: RPWWN = %s and LPWWN = %s.",
297 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) |
298 (BFA_LOG_S << BFA_LOG_ARG2) | 0), 3},
299
300{BFA_AEN_RPORT_QOS_FLOWID, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
301 "BFA_AEN_RPORT_QOS_FLOWID",
302 "QOS flow ID changed to %d: RPWWN = %s and LPWWN = %s.",
303 ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) |
304 (BFA_LOG_S << BFA_LOG_ARG2) | 0), 3},
305
306
307
308
309/* messages define for FCS Module */
310{BFA_LOG_FCS_FABRIC_NOSWITCH, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
311 BFA_LOG_INFO, "FCS_FABRIC_NOSWITCH",
312 "No switched fabric presence is detected.",
313 (0), 0},
314
315{BFA_LOG_FCS_FABRIC_ISOLATED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
316 BFA_LOG_INFO, "FCS_FABRIC_ISOLATED",
317 "Port is isolated due to VF_ID mismatch. PWWN: %s, Port VF_ID: %04x and"
318 " switch port VF_ID: %04x.",
319 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_X << BFA_LOG_ARG1) |
320 (BFA_LOG_X << BFA_LOG_ARG2) | 0), 3},
321
322
323
324
325/* messages define for HAL Module */
326{BFA_LOG_HAL_ASSERT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_ERROR,
327 "HAL_ASSERT",
328 "Assertion failure: %s:%d: %s",
329 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) |
330 (BFA_LOG_S << BFA_LOG_ARG2) | 0), 3},
331
332{BFA_LOG_HAL_HEARTBEAT_FAILURE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
333 BFA_LOG_CRITICAL, "HAL_HEARTBEAT_FAILURE",
334 "Firmware heartbeat failure at %d",
335 ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1},
336
337{BFA_LOG_HAL_FCPIM_PARM_INVALID, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
338 BFA_LOG_INFO, "HAL_FCPIM_PARM_INVALID",
339 "Driver configuration %s value %d is invalid. Value should be within"
340 " %d and %d.",
341 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) |
342 (BFA_LOG_D << BFA_LOG_ARG2) | (BFA_LOG_D << BFA_LOG_ARG3) | 0), 4},
343
344{BFA_LOG_HAL_SM_ASSERT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_ERROR,
345 "HAL_SM_ASSERT",
346 "SM Assertion failure: %s:%d: event = %d",
347 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) |
348 (BFA_LOG_D << BFA_LOG_ARG2) | 0), 3},
349
350
351
352
353/* messages define for LINUX Module */
354{BFA_LOG_LINUX_DEVICE_CLAIMED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
355 BFA_LOG_INFO, "LINUX_DEVICE_CLAIMED",
356 "bfa device at %s claimed.",
357 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
358
359{BFA_LOG_LINUX_HASH_INIT_FAILED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
360 BFA_LOG_INFO, "LINUX_HASH_INIT_FAILED",
361 "Hash table initialization failure for the port %s.",
362 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
363
364{BFA_LOG_LINUX_SYSFS_FAILED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
365 BFA_LOG_INFO, "LINUX_SYSFS_FAILED",
366 "sysfs file creation failure for the port %s.",
367 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
368
369{BFA_LOG_LINUX_MEM_ALLOC_FAILED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
370 BFA_LOG_INFO, "LINUX_MEM_ALLOC_FAILED",
371 "Memory allocation failed: %s. ",
372 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
373
374{BFA_LOG_LINUX_DRIVER_REGISTRATION_FAILED,
375 BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
376 "LINUX_DRIVER_REGISTRATION_FAILED",
377 "%s. ",
378 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
379
380{BFA_LOG_LINUX_ITNIM_FREE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
381 "LINUX_ITNIM_FREE",
382 "scsi%d: FCID: %s WWPN: %s",
383 ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) |
384 (BFA_LOG_S << BFA_LOG_ARG2) | 0), 3},
385
386{BFA_LOG_LINUX_ITNIM_ONLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
387 BFA_LOG_INFO, "LINUX_ITNIM_ONLINE",
388 "Target: %d:0:%d FCID: %s WWPN: %s",
389 ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) |
390 (BFA_LOG_S << BFA_LOG_ARG2) | (BFA_LOG_S << BFA_LOG_ARG3) | 0), 4},
391
392{BFA_LOG_LINUX_ITNIM_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
393 BFA_LOG_INFO, "LINUX_ITNIM_OFFLINE",
394 "Target: %d:0:%d FCID: %s WWPN: %s",
395 ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) |
396 (BFA_LOG_S << BFA_LOG_ARG2) | (BFA_LOG_S << BFA_LOG_ARG3) | 0), 4},
397
398{BFA_LOG_LINUX_SCSI_HOST_FREE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
399 BFA_LOG_INFO, "LINUX_SCSI_HOST_FREE",
400 "Free scsi%d",
401 ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1},
402
403{BFA_LOG_LINUX_SCSI_ABORT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
404 "LINUX_SCSI_ABORT",
405 "scsi%d: abort cmnd %p, iotag %x",
406 ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_P << BFA_LOG_ARG1) |
407 (BFA_LOG_X << BFA_LOG_ARG2) | 0), 3},
408
409{BFA_LOG_LINUX_SCSI_ABORT_COMP, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
410 BFA_LOG_INFO, "LINUX_SCSI_ABORT_COMP",
411 "scsi%d: complete abort 0x%p, iotag 0x%x",
412 ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_P << BFA_LOG_ARG1) |
413 (BFA_LOG_X << BFA_LOG_ARG2) | 0), 3},
414
415
416
417
418/* messages define for WDRV Module */
419{BFA_LOG_WDRV_IOC_INIT_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
420 BFA_LOG_INFO, "WDRV_IOC_INIT_ERROR",
421 "IOC initialization has failed.",
422 (0), 0},
423
424{BFA_LOG_WDRV_IOC_INTERNAL_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
425 BFA_LOG_INFO, "WDRV_IOC_INTERNAL_ERROR",
426 "IOC internal error. ",
427 (0), 0},
428
429{BFA_LOG_WDRV_IOC_START_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
430 BFA_LOG_INFO, "WDRV_IOC_START_ERROR",
431 "IOC could not be started. ",
432 (0), 0},
433
434{BFA_LOG_WDRV_IOC_STOP_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
435 BFA_LOG_INFO, "WDRV_IOC_STOP_ERROR",
436 "IOC could not be stopped. ",
437 (0), 0},
438
439{BFA_LOG_WDRV_INSUFFICIENT_RESOURCES, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
440 BFA_LOG_INFO, "WDRV_INSUFFICIENT_RESOURCES",
441 "Insufficient memory. ",
442 (0), 0},
443
444{BFA_LOG_WDRV_BASE_ADDRESS_MAP_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
445 BFA_LOG_INFO, "WDRV_BASE_ADDRESS_MAP_ERROR",
446 "Unable to map the IOC onto the system address space. ",
447 (0), 0},
448
449
450{0, 0, 0, "", "", 0, 0},
451};
diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c
new file mode 100644
index 000000000000..9844b45412b6
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_lps.c
@@ -0,0 +1,782 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19#include <bfi/bfi_lps.h>
20#include <cs/bfa_debug.h>
21
22BFA_TRC_FILE(HAL, LPS);
23BFA_MODULE(lps);
24
25#define BFA_LPS_MIN_LPORTS (1)
26#define BFA_LPS_MAX_LPORTS (256)
27
28/**
29 * forward declarations
30 */
31static void bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
32 u32 *dm_len);
33static void bfa_lps_attach(struct bfa_s *bfa, void *bfad,
34 struct bfa_iocfc_cfg_s *cfg,
35 struct bfa_meminfo_s *meminfo,
36 struct bfa_pcidev_s *pcidev);
37static void bfa_lps_initdone(struct bfa_s *bfa);
38static void bfa_lps_detach(struct bfa_s *bfa);
39static void bfa_lps_start(struct bfa_s *bfa);
40static void bfa_lps_stop(struct bfa_s *bfa);
41static void bfa_lps_iocdisable(struct bfa_s *bfa);
42static void bfa_lps_login_rsp(struct bfa_s *bfa,
43 struct bfi_lps_login_rsp_s *rsp);
44static void bfa_lps_logout_rsp(struct bfa_s *bfa,
45 struct bfi_lps_logout_rsp_s *rsp);
46static void bfa_lps_reqq_resume(void *lps_arg);
47static void bfa_lps_free(struct bfa_lps_s *lps);
48static void bfa_lps_send_login(struct bfa_lps_s *lps);
49static void bfa_lps_send_logout(struct bfa_lps_s *lps);
50static void bfa_lps_login_comp(struct bfa_lps_s *lps);
51static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
52
53
54/**
55 * lps_pvt BFA LPS private functions
56 */
57
58enum bfa_lps_event {
59 BFA_LPS_SM_LOGIN = 1, /* login request from user */
60 BFA_LPS_SM_LOGOUT = 2, /* logout request from user */
61 BFA_LPS_SM_FWRSP = 3, /* f/w response to login/logout */
62 BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */
63 BFA_LPS_SM_DELETE = 5, /* lps delete from user */
64 BFA_LPS_SM_OFFLINE = 6, /* Link is offline */
65};
66
67static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event);
68static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event);
69static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps,
70 enum bfa_lps_event event);
71static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event);
72static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event);
73static void bfa_lps_sm_logowait(struct bfa_lps_s *lps,
74 enum bfa_lps_event event);
75
76/**
77 * Init state -- no login
78 */
79static void
80bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
81{
82 bfa_trc(lps->bfa, lps->lp_tag);
83 bfa_trc(lps->bfa, event);
84
85 switch (event) {
86 case BFA_LPS_SM_LOGIN:
87 if (bfa_reqq_full(lps->bfa, lps->reqq)) {
88 bfa_sm_set_state(lps, bfa_lps_sm_loginwait);
89 bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
90 } else {
91 bfa_sm_set_state(lps, bfa_lps_sm_login);
92 bfa_lps_send_login(lps);
93 }
94 break;
95
96 case BFA_LPS_SM_LOGOUT:
97 bfa_lps_logout_comp(lps);
98 break;
99
100 case BFA_LPS_SM_DELETE:
101 bfa_lps_free(lps);
102 break;
103
104 case BFA_LPS_SM_OFFLINE:
105 break;
106
107 case BFA_LPS_SM_FWRSP:
108 /* Could happen when fabric detects loopback and discards
109 * the lps request. Fw will eventually sent out the timeout
110 * Just ignore
111 */
112 break;
113
114 default:
115 bfa_assert(0);
116 }
117}
118
119/**
120 * login is in progress -- awaiting response from firmware
121 */
122static void
123bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
124{
125 bfa_trc(lps->bfa, lps->lp_tag);
126 bfa_trc(lps->bfa, event);
127
128 switch (event) {
129 case BFA_LPS_SM_FWRSP:
130 if (lps->status == BFA_STATUS_OK)
131 bfa_sm_set_state(lps, bfa_lps_sm_online);
132 else
133 bfa_sm_set_state(lps, bfa_lps_sm_init);
134 bfa_lps_login_comp(lps);
135 break;
136
137 case BFA_LPS_SM_OFFLINE:
138 bfa_sm_set_state(lps, bfa_lps_sm_init);
139 break;
140
141 default:
142 bfa_assert(0);
143 }
144}
145
146/**
147 * login pending - awaiting space in request queue
148 */
149static void
150bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event)
151{
152 bfa_trc(lps->bfa, lps->lp_tag);
153 bfa_trc(lps->bfa, event);
154
155 switch (event) {
156 case BFA_LPS_SM_RESUME:
157 bfa_sm_set_state(lps, bfa_lps_sm_login);
158 break;
159
160 case BFA_LPS_SM_OFFLINE:
161 bfa_sm_set_state(lps, bfa_lps_sm_init);
162 bfa_reqq_wcancel(&lps->wqe);
163 break;
164
165 default:
166 bfa_assert(0);
167 }
168}
169
170/**
171 * login complete
172 */
173static void
174bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
175{
176 bfa_trc(lps->bfa, lps->lp_tag);
177 bfa_trc(lps->bfa, event);
178
179 switch (event) {
180 case BFA_LPS_SM_LOGOUT:
181 if (bfa_reqq_full(lps->bfa, lps->reqq)) {
182 bfa_sm_set_state(lps, bfa_lps_sm_logowait);
183 bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
184 } else {
185 bfa_sm_set_state(lps, bfa_lps_sm_logout);
186 bfa_lps_send_logout(lps);
187 }
188 break;
189
190 case BFA_LPS_SM_OFFLINE:
191 case BFA_LPS_SM_DELETE:
192 bfa_sm_set_state(lps, bfa_lps_sm_init);
193 break;
194
195 default:
196 bfa_assert(0);
197 }
198}
199
200/**
201 * logout in progress - awaiting firmware response
202 */
203static void
204bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event)
205{
206 bfa_trc(lps->bfa, lps->lp_tag);
207 bfa_trc(lps->bfa, event);
208
209 switch (event) {
210 case BFA_LPS_SM_FWRSP:
211 bfa_sm_set_state(lps, bfa_lps_sm_init);
212 bfa_lps_logout_comp(lps);
213 break;
214
215 case BFA_LPS_SM_OFFLINE:
216 bfa_sm_set_state(lps, bfa_lps_sm_init);
217 break;
218
219 default:
220 bfa_assert(0);
221 }
222}
223
224/**
225 * logout pending -- awaiting space in request queue
226 */
227static void
228bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event)
229{
230 bfa_trc(lps->bfa, lps->lp_tag);
231 bfa_trc(lps->bfa, event);
232
233 switch (event) {
234 case BFA_LPS_SM_RESUME:
235 bfa_sm_set_state(lps, bfa_lps_sm_logout);
236 bfa_lps_send_logout(lps);
237 break;
238
239 case BFA_LPS_SM_OFFLINE:
240 bfa_sm_set_state(lps, bfa_lps_sm_init);
241 bfa_reqq_wcancel(&lps->wqe);
242 break;
243
244 default:
245 bfa_assert(0);
246 }
247}
248
249
250
251/**
252 * lps_pvt BFA LPS private functions
253 */
254
255/**
256 * return memory requirement
257 */
258static void
259bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len)
260{
261 if (cfg->drvcfg.min_cfg)
262 *ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MIN_LPORTS;
263 else
264 *ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MAX_LPORTS;
265}
266
267/**
268 * bfa module attach at initialization time
269 */
270static void
271bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
272 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
273{
274 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
275 struct bfa_lps_s *lps;
276 int i;
277
278 bfa_os_memset(mod, 0, sizeof(struct bfa_lps_mod_s));
279 mod->num_lps = BFA_LPS_MAX_LPORTS;
280 if (cfg->drvcfg.min_cfg)
281 mod->num_lps = BFA_LPS_MIN_LPORTS;
282 else
283 mod->num_lps = BFA_LPS_MAX_LPORTS;
284 mod->lps_arr = lps = (struct bfa_lps_s *) bfa_meminfo_kva(meminfo);
285
286 bfa_meminfo_kva(meminfo) += mod->num_lps * sizeof(struct bfa_lps_s);
287
288 INIT_LIST_HEAD(&mod->lps_free_q);
289 INIT_LIST_HEAD(&mod->lps_active_q);
290
291 for (i = 0; i < mod->num_lps; i++, lps++) {
292 lps->bfa = bfa;
293 lps->lp_tag = (u8) i;
294 lps->reqq = BFA_REQQ_LPS;
295 bfa_reqq_winit(&lps->wqe, bfa_lps_reqq_resume, lps);
296 list_add_tail(&lps->qe, &mod->lps_free_q);
297 }
298}
299
300static void
301bfa_lps_initdone(struct bfa_s *bfa)
302{
303}
304
305static void
306bfa_lps_detach(struct bfa_s *bfa)
307{
308}
309
310static void
311bfa_lps_start(struct bfa_s *bfa)
312{
313}
314
315static void
316bfa_lps_stop(struct bfa_s *bfa)
317{
318}
319
320/**
321 * IOC in disabled state -- consider all lps offline
322 */
323static void
324bfa_lps_iocdisable(struct bfa_s *bfa)
325{
326 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
327 struct bfa_lps_s *lps;
328 struct list_head *qe, *qen;
329
330 list_for_each_safe(qe, qen, &mod->lps_active_q) {
331 lps = (struct bfa_lps_s *) qe;
332 bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE);
333 }
334}
335
336/**
337 * Firmware login response
338 */
339static void
340bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp)
341{
342 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
343 struct bfa_lps_s *lps;
344
345 bfa_assert(rsp->lp_tag < mod->num_lps);
346 lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag);
347
348 lps->status = rsp->status;
349 switch (rsp->status) {
350 case BFA_STATUS_OK:
351 lps->fport = rsp->f_port;
352 lps->npiv_en = rsp->npiv_en;
353 lps->lp_pid = rsp->lp_pid;
354 lps->pr_bbcred = bfa_os_ntohs(rsp->bb_credit);
355 lps->pr_pwwn = rsp->port_name;
356 lps->pr_nwwn = rsp->node_name;
357 lps->auth_req = rsp->auth_req;
358 lps->lp_mac = rsp->lp_mac;
359 lps->brcd_switch = rsp->brcd_switch;
360 lps->fcf_mac = rsp->fcf_mac;
361
362 break;
363
364 case BFA_STATUS_FABRIC_RJT:
365 lps->lsrjt_rsn = rsp->lsrjt_rsn;
366 lps->lsrjt_expl = rsp->lsrjt_expl;
367
368 break;
369
370 case BFA_STATUS_EPROTOCOL:
371 lps->ext_status = rsp->ext_status;
372
373 break;
374
375 default:
376 /* Nothing to do with other status */
377 break;
378 }
379
380 bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
381}
382
383/**
384 * Firmware logout response
385 */
386static void
387bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp)
388{
389 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
390 struct bfa_lps_s *lps;
391
392 bfa_assert(rsp->lp_tag < mod->num_lps);
393 lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag);
394
395 bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
396}
397
398/**
399 * Space is available in request queue, resume queueing request to firmware.
400 */
401static void
402bfa_lps_reqq_resume(void *lps_arg)
403{
404 struct bfa_lps_s *lps = lps_arg;
405
406 bfa_sm_send_event(lps, BFA_LPS_SM_RESUME);
407}
408
409/**
410 * lps is freed -- triggered by vport delete
411 */
412static void
413bfa_lps_free(struct bfa_lps_s *lps)
414{
415 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(lps->bfa);
416
417 list_del(&lps->qe);
418 list_add_tail(&lps->qe, &mod->lps_free_q);
419}
420
421/**
422 * send login request to firmware
423 */
424static void
425bfa_lps_send_login(struct bfa_lps_s *lps)
426{
427 struct bfi_lps_login_req_s *m;
428
429 m = bfa_reqq_next(lps->bfa, lps->reqq);
430 bfa_assert(m);
431
432 bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGIN_REQ,
433 bfa_lpuid(lps->bfa));
434
435 m->lp_tag = lps->lp_tag;
436 m->alpa = lps->alpa;
437 m->pdu_size = bfa_os_htons(lps->pdusz);
438 m->pwwn = lps->pwwn;
439 m->nwwn = lps->nwwn;
440 m->fdisc = lps->fdisc;
441 m->auth_en = lps->auth_en;
442
443 bfa_reqq_produce(lps->bfa, lps->reqq);
444}
445
446/**
447 * send logout request to firmware
448 */
449static void
450bfa_lps_send_logout(struct bfa_lps_s *lps)
451{
452 struct bfi_lps_logout_req_s *m;
453
454 m = bfa_reqq_next(lps->bfa, lps->reqq);
455 bfa_assert(m);
456
457 bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGOUT_REQ,
458 bfa_lpuid(lps->bfa));
459
460 m->lp_tag = lps->lp_tag;
461 m->port_name = lps->pwwn;
462 bfa_reqq_produce(lps->bfa, lps->reqq);
463}
464
465/**
466 * Indirect login completion handler for non-fcs
467 */
468static void
469bfa_lps_login_comp_cb(void *arg, bfa_boolean_t complete)
470{
471 struct bfa_lps_s *lps = arg;
472
473 if (!complete)
474 return;
475
476 if (lps->fdisc)
477 bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status);
478 else
479 bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status);
480}
481
482/**
483 * Login completion handler -- direct call for fcs, queue for others
484 */
485static void
486bfa_lps_login_comp(struct bfa_lps_s *lps)
487{
488 if (!lps->bfa->fcs) {
489 bfa_cb_queue(lps->bfa, &lps->hcb_qe,
490 bfa_lps_login_comp_cb, lps);
491 return;
492 }
493
494 if (lps->fdisc)
495 bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status);
496 else
497 bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status);
498}
499
500/**
501 * Indirect logout completion handler for non-fcs
502 */
503static void
504bfa_lps_logout_comp_cb(void *arg, bfa_boolean_t complete)
505{
506 struct bfa_lps_s *lps = arg;
507
508 if (!complete)
509 return;
510
511 if (lps->fdisc)
512 bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg);
513 else
514 bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
515}
516
517/**
518 * Logout completion handler -- direct call for fcs, queue for others
519 */
520static void
521bfa_lps_logout_comp(struct bfa_lps_s *lps)
522{
523 if (!lps->bfa->fcs) {
524 bfa_cb_queue(lps->bfa, &lps->hcb_qe,
525 bfa_lps_logout_comp_cb, lps);
526 return;
527 }
528 if (lps->fdisc)
529 bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg);
530 else
531 bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
532}
533
534
535
536/**
537 * lps_public BFA LPS public functions
538 */
539
540/**
541 * Allocate a lport srvice tag.
542 */
543struct bfa_lps_s *
544bfa_lps_alloc(struct bfa_s *bfa)
545{
546 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
547 struct bfa_lps_s *lps = NULL;
548
549 bfa_q_deq(&mod->lps_free_q, &lps);
550
551 if (lps == NULL)
552 return NULL;
553
554 list_add_tail(&lps->qe, &mod->lps_active_q);
555
556 bfa_sm_set_state(lps, bfa_lps_sm_init);
557 return lps;
558}
559
560/**
561 * Free lport service tag. This can be called anytime after an alloc.
562 * No need to wait for any pending login/logout completions.
563 */
564void
565bfa_lps_delete(struct bfa_lps_s *lps)
566{
567 bfa_sm_send_event(lps, BFA_LPS_SM_DELETE);
568}
569
570/**
571 * Initiate a lport login.
572 */
573void
574bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz,
575 wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en)
576{
577 lps->uarg = uarg;
578 lps->alpa = alpa;
579 lps->pdusz = pdusz;
580 lps->pwwn = pwwn;
581 lps->nwwn = nwwn;
582 lps->fdisc = BFA_FALSE;
583 lps->auth_en = auth_en;
584 bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
585}
586
587/**
588 * Initiate a lport fdisc login.
589 */
590void
591bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn,
592 wwn_t nwwn)
593{
594 lps->uarg = uarg;
595 lps->alpa = 0;
596 lps->pdusz = pdusz;
597 lps->pwwn = pwwn;
598 lps->nwwn = nwwn;
599 lps->fdisc = BFA_TRUE;
600 lps->auth_en = BFA_FALSE;
601 bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
602}
603
604/**
605 * Initiate a lport logout (flogi).
606 */
607void
608bfa_lps_flogo(struct bfa_lps_s *lps)
609{
610 bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
611}
612
613/**
614 * Initiate a lport FDSIC logout.
615 */
616void
617bfa_lps_fdisclogo(struct bfa_lps_s *lps)
618{
619 bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
620}
621
622/**
623 * Discard a pending login request -- should be called only for
624 * link down handling.
625 */
626void
627bfa_lps_discard(struct bfa_lps_s *lps)
628{
629 bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE);
630}
631
632/**
633 * Return lport services tag
634 */
635u8
636bfa_lps_get_tag(struct bfa_lps_s *lps)
637{
638 return lps->lp_tag;
639}
640
641/**
642 * Return lport services tag given the pid
643 */
644u8
645bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid)
646{
647 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
648 struct bfa_lps_s *lps;
649 int i;
650
651 for (i = 0, lps = mod->lps_arr; i < mod->num_lps; i++, lps++) {
652 if (lps->lp_pid == pid)
653 return lps->lp_tag;
654 }
655
656 /* Return base port tag anyway */
657 return 0;
658}
659
660/**
661 * return if fabric login indicates support for NPIV
662 */
663bfa_boolean_t
664bfa_lps_is_npiv_en(struct bfa_lps_s *lps)
665{
666 return lps->npiv_en;
667}
668
669/**
670 * Return TRUE if attached to F-Port, else return FALSE
671 */
672bfa_boolean_t
673bfa_lps_is_fport(struct bfa_lps_s *lps)
674{
675 return lps->fport;
676}
677
678/**
679 * Return TRUE if attached to a Brocade Fabric
680 */
681bfa_boolean_t
682bfa_lps_is_brcd_fabric(struct bfa_lps_s *lps)
683{
684 return lps->brcd_switch;
685}
686/**
687 * return TRUE if authentication is required
688 */
689bfa_boolean_t
690bfa_lps_is_authreq(struct bfa_lps_s *lps)
691{
692 return lps->auth_req;
693}
694
695bfa_eproto_status_t
696bfa_lps_get_extstatus(struct bfa_lps_s *lps)
697{
698 return lps->ext_status;
699}
700
701/**
702 * return port id assigned to the lport
703 */
704u32
705bfa_lps_get_pid(struct bfa_lps_s *lps)
706{
707 return lps->lp_pid;
708}
709
710/**
711 * Return bb_credit assigned in FLOGI response
712 */
713u16
714bfa_lps_get_peer_bbcredit(struct bfa_lps_s *lps)
715{
716 return lps->pr_bbcred;
717}
718
719/**
720 * Return peer port name
721 */
722wwn_t
723bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps)
724{
725 return lps->pr_pwwn;
726}
727
728/**
729 * Return peer node name
730 */
731wwn_t
732bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps)
733{
734 return lps->pr_nwwn;
735}
736
737/**
738 * return reason code if login request is rejected
739 */
740u8
741bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps)
742{
743 return lps->lsrjt_rsn;
744}
745
746/**
747 * return explanation code if login request is rejected
748 */
749u8
750bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps)
751{
752 return lps->lsrjt_expl;
753}
754
755
756/**
757 * LPS firmware message class handler.
758 */
759void
760bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
761{
762 union bfi_lps_i2h_msg_u msg;
763
764 bfa_trc(bfa, m->mhdr.msg_id);
765 msg.msg = m;
766
767 switch (m->mhdr.msg_id) {
768 case BFI_LPS_H2I_LOGIN_RSP:
769 bfa_lps_login_rsp(bfa, msg.login_rsp);
770 break;
771
772 case BFI_LPS_H2I_LOGOUT_RSP:
773 bfa_lps_logout_rsp(bfa, msg.logout_rsp);
774 break;
775
776 default:
777 bfa_trc(bfa, m->mhdr.msg_id);
778 bfa_assert(0);
779 }
780}
781
782
diff --git a/drivers/scsi/bfa/bfa_lps_priv.h b/drivers/scsi/bfa/bfa_lps_priv.h
new file mode 100644
index 000000000000..d16c6ce995df
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_lps_priv.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_LPS_PRIV_H__
19#define __BFA_LPS_PRIV_H__
20
21#include <bfa_svc.h>
22
23struct bfa_lps_mod_s {
24 struct list_head lps_free_q;
25 struct list_head lps_active_q;
26 struct bfa_lps_s *lps_arr;
27 int num_lps;
28};
29
30#define BFA_LPS_MOD(__bfa) (&(__bfa)->modules.lps_mod)
31#define BFA_LPS_FROM_TAG(__mod, __tag) (&(__mod)->lps_arr[__tag])
32
33/*
34 * external functions
35 */
36void bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
37
38#endif /* __BFA_LPS_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_module.c b/drivers/scsi/bfa/bfa_module.c
new file mode 100644
index 000000000000..32eda8e1ec65
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_module.c
@@ -0,0 +1,90 @@
1/*
2 * Copyright (c) 2005-2009 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#include <bfa.h>
18#include <defs/bfa_defs_pci.h>
19#include <cs/bfa_debug.h>
20#include <bfa_iocfc.h>
21
22/**
23 * BFA module list terminated by NULL
24 */
25struct bfa_module_s *hal_mods[] = {
26 &hal_mod_sgpg,
27 &hal_mod_pport,
28 &hal_mod_fcxp,
29 &hal_mod_lps,
30 &hal_mod_uf,
31 &hal_mod_rport,
32 &hal_mod_fcpim,
33#ifdef BFA_CFG_PBIND
34 &hal_mod_pbind,
35#endif
36 NULL
37};
38
39/**
40 * Message handlers for various modules.
41 */
42bfa_isr_func_t bfa_isrs[BFI_MC_MAX] = {
43 bfa_isr_unhandled, /* NONE */
44 bfa_isr_unhandled, /* BFI_MC_IOC */
45 bfa_isr_unhandled, /* BFI_MC_DIAG */
46 bfa_isr_unhandled, /* BFI_MC_FLASH */
47 bfa_isr_unhandled, /* BFI_MC_CEE */
48 bfa_pport_isr, /* BFI_MC_PORT */
49 bfa_isr_unhandled, /* BFI_MC_IOCFC */
50 bfa_isr_unhandled, /* BFI_MC_LL */
51 bfa_uf_isr, /* BFI_MC_UF */
52 bfa_fcxp_isr, /* BFI_MC_FCXP */
53 bfa_lps_isr, /* BFI_MC_LPS */
54 bfa_rport_isr, /* BFI_MC_RPORT */
55 bfa_itnim_isr, /* BFI_MC_ITNIM */
56 bfa_isr_unhandled, /* BFI_MC_IOIM_READ */
57 bfa_isr_unhandled, /* BFI_MC_IOIM_WRITE */
58 bfa_isr_unhandled, /* BFI_MC_IOIM_IO */
59 bfa_ioim_isr, /* BFI_MC_IOIM */
60 bfa_ioim_good_comp_isr, /* BFI_MC_IOIM_IOCOM */
61 bfa_tskim_isr, /* BFI_MC_TSKIM */
62 bfa_isr_unhandled, /* BFI_MC_SBOOT */
63 bfa_isr_unhandled, /* BFI_MC_IPFC */
64 bfa_isr_unhandled, /* BFI_MC_PORT */
65 bfa_isr_unhandled, /* --------- */
66 bfa_isr_unhandled, /* --------- */
67 bfa_isr_unhandled, /* --------- */
68 bfa_isr_unhandled, /* --------- */
69 bfa_isr_unhandled, /* --------- */
70 bfa_isr_unhandled, /* --------- */
71 bfa_isr_unhandled, /* --------- */
72 bfa_isr_unhandled, /* --------- */
73 bfa_isr_unhandled, /* --------- */
74 bfa_isr_unhandled, /* --------- */
75};
76
77/**
78 * Message handlers for mailbox command classes
79 */
80bfa_ioc_mbox_mcfunc_t bfa_mbox_isrs[BFI_MC_MAX] = {
81 NULL,
82 NULL, /* BFI_MC_IOC */
83 NULL, /* BFI_MC_DIAG */
84 NULL, /* BFI_MC_FLASH */
85 NULL, /* BFI_MC_CEE */
86 NULL, /* BFI_MC_PORT */
87 bfa_iocfc_isr, /* BFI_MC_IOCFC */
88 NULL,
89};
90
diff --git a/drivers/scsi/bfa/bfa_modules_priv.h b/drivers/scsi/bfa/bfa_modules_priv.h
new file mode 100644
index 000000000000..96f70534593c
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_modules_priv.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_MODULES_PRIV_H__
19#define __BFA_MODULES_PRIV_H__
20
21#include "bfa_uf_priv.h"
22#include "bfa_port_priv.h"
23#include "bfa_rport_priv.h"
24#include "bfa_fcxp_priv.h"
25#include "bfa_lps_priv.h"
26#include "bfa_fcpim_priv.h"
27#include <cee/bfa_cee.h>
28#include <port/bfa_port.h>
29
30
31struct bfa_modules_s {
32 struct bfa_pport_s pport; /* physical port module */
33 struct bfa_fcxp_mod_s fcxp_mod; /* fcxp module */
34 struct bfa_lps_mod_s lps_mod; /* fcxp module */
35 struct bfa_uf_mod_s uf_mod; /* unsolicited frame module */
36 struct bfa_rport_mod_s rport_mod; /* remote port module */
37 struct bfa_fcpim_mod_s fcpim_mod; /* FCP initiator module */
38 struct bfa_sgpg_mod_s sgpg_mod; /* SG page module */
39 struct bfa_cee_s cee; /* CEE Module */
40 struct bfa_port_s port; /* Physical port module */
41};
42
43#endif /* __BFA_MODULES_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_os_inc.h b/drivers/scsi/bfa/bfa_os_inc.h
new file mode 100644
index 000000000000..10a89f75fa94
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_os_inc.h
@@ -0,0 +1,222 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * Contains declarations all OS Specific files needed for BFA layer
20 */
21
22#ifndef __BFA_OS_INC_H__
23#define __BFA_OS_INC_H__
24
25#ifndef __KERNEL__
26#include <stdint.h>
27#else
28#include <linux/types.h>
29
30#include <linux/version.h>
31#include <linux/pci.h>
32
33#include <linux/dma-mapping.h>
34#define SET_MODULE_VERSION(VER)
35
36#include <linux/idr.h>
37
38#include <linux/interrupt.h>
39#include <linux/cdev.h>
40#include <linux/fs.h>
41#include <linux/delay.h>
42#include <linux/vmalloc.h>
43
44#include <linux/workqueue.h>
45
46#include <scsi/scsi.h>
47#include <scsi/scsi_host.h>
48
49#include <scsi/scsi_tcq.h>
50#include <scsi/scsi_transport_fc.h>
51#include <scsi/scsi_transport.h>
52
53#define BFA_ERR KERN_ERR
54#define BFA_WARNING KERN_WARNING
55#define BFA_NOTICE KERN_NOTICE
56#define BFA_INFO KERN_INFO
57#define BFA_DEBUG KERN_DEBUG
58
59#define LOG_BFAD_INIT 0x00000001
60#define LOG_FCP_IO 0x00000002
61
62#ifdef DEBUG
63#define BFA_LOG_TRACE(bfad, level, mask, fmt, arg...) \
64 BFA_LOG(bfad, level, mask, fmt, ## arg)
65#define BFA_DEV_TRACE(bfad, level, fmt, arg...) \
66 BFA_DEV_PRINTF(bfad, level, fmt, ## arg)
67#define BFA_TRACE(level, fmt, arg...) \
68 BFA_PRINTF(level, fmt, ## arg)
69#else
70#define BFA_LOG_TRACE(bfad, level, mask, fmt, arg...)
71#define BFA_DEV_TRACE(bfad, level, fmt, arg...)
72#define BFA_TRACE(level, fmt, arg...)
73#endif
74
75#define BFA_ASSERT(p) do { \
76 if (!(p)) { \
77 printk(KERN_ERR "assert(%s) failed at %s:%d\n", \
78 #p, __FILE__, __LINE__); \
79 BUG(); \
80 } \
81} while (0)
82
83
84#define BFA_LOG(bfad, level, mask, fmt, arg...) \
85do { \
86 if (((mask) & (((struct bfad_s *)(bfad))-> \
87 cfg_data[cfg_log_mask])) || (level[1] <= '3')) \
88 dev_printk(level, &(((struct bfad_s *) \
89 (bfad))->pcidev->dev), fmt, ##arg); \
90} while (0)
91
92#ifndef BFA_DEV_PRINTF
93#define BFA_DEV_PRINTF(bfad, level, fmt, arg...) \
94 dev_printk(level, &(((struct bfad_s *) \
95 (bfad))->pcidev->dev), fmt, ##arg);
96#endif
97
98#define BFA_PRINTF(level, fmt, arg...) \
99 printk(level fmt, ##arg);
100
101int bfa_os_MWB(void *);
102
103#define bfa_os_mmiowb() mmiowb()
104
105#define bfa_swap_3b(_x) \
106 ((((_x) & 0xff) << 16) | \
107 ((_x) & 0x00ff00) | \
108 (((_x) & 0xff0000) >> 16))
109
110#define bfa_swap_8b(_x) \
111 ((((_x) & 0xff00000000000000ull) >> 56) \
112 | (((_x) & 0x00ff000000000000ull) >> 40) \
113 | (((_x) & 0x0000ff0000000000ull) >> 24) \
114 | (((_x) & 0x000000ff00000000ull) >> 8) \
115 | (((_x) & 0x00000000ff000000ull) << 8) \
116 | (((_x) & 0x0000000000ff0000ull) << 24) \
117 | (((_x) & 0x000000000000ff00ull) << 40) \
118 | (((_x) & 0x00000000000000ffull) << 56))
119
120#define bfa_os_swap32(_x) \
121 ((((_x) & 0xff) << 24) | \
122 (((_x) & 0x0000ff00) << 8) | \
123 (((_x) & 0x00ff0000) >> 8) | \
124 (((_x) & 0xff000000) >> 24))
125
126
127#ifndef __BIGENDIAN
128#define bfa_os_htons(_x) ((u16)((((_x) & 0xff00) >> 8) | \
129 (((_x) & 0x00ff) << 8)))
130
131#define bfa_os_htonl(_x) bfa_os_swap32(_x)
132#define bfa_os_htonll(_x) bfa_swap_8b(_x)
133#define bfa_os_hton3b(_x) bfa_swap_3b(_x)
134
135#define bfa_os_wtole(_x) (_x)
136
137#else
138
139#define bfa_os_htons(_x) (_x)
140#define bfa_os_htonl(_x) (_x)
141#define bfa_os_hton3b(_x) (_x)
142#define bfa_os_htonll(_x) (_x)
143#define bfa_os_wtole(_x) bfa_os_swap32(_x)
144
145#endif
146
147#define bfa_os_ntohs(_x) bfa_os_htons(_x)
148#define bfa_os_ntohl(_x) bfa_os_htonl(_x)
149#define bfa_os_ntohll(_x) bfa_os_htonll(_x)
150#define bfa_os_ntoh3b(_x) bfa_os_hton3b(_x)
151
152#define bfa_os_u32(__pa64) ((__pa64) >> 32)
153
154#define bfa_os_memset memset
155#define bfa_os_memcpy memcpy
156#define bfa_os_udelay udelay
157#define bfa_os_vsprintf vsprintf
158
159#define bfa_os_assign(__t, __s) __t = __s
160
161#define bfa_os_addr_t char __iomem *
162#define bfa_os_panic()
163
164#define bfa_os_reg_read(_raddr) bfa_os_wtole(readl(_raddr))
165#define bfa_os_reg_write(_raddr, _val) writel(bfa_os_wtole((_val)), (_raddr))
166#define bfa_os_mem_read(_raddr, _off) \
167 bfa_os_ntohl(readl(((_raddr) + (_off))))
168#define bfa_os_mem_write(_raddr, _off, _val) \
169 writel(bfa_os_htonl((_val)), ((_raddr) + (_off)))
170
171#define BFA_TRC_TS(_trcm) \
172 ({ \
173 struct timeval tv; \
174 \
175 do_gettimeofday(&tv); \
176 (tv.tv_sec*1000000+tv.tv_usec); \
177 })
178
179struct bfa_log_mod_s;
180void bfa_os_printf(struct bfa_log_mod_s *log_mod, u32 msg_id,
181 const char *fmt, ...);
182#endif
183
184#define boolean_t int
185
186/**
187 * For current time stamp, OS API will fill-in
188 */
189struct bfa_timeval_s {
190 u32 tv_sec; /* seconds */
191 u32 tv_usec; /* microseconds */
192};
193
194void bfa_os_gettimeofday(struct bfa_timeval_s *tv);
195
196static inline void
197wwn2str(char *wwn_str, u64 wwn)
198{
199 union {
200 u64 wwn;
201 u8 byte[8];
202 } w;
203
204 w.wwn = wwn;
205 sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", w.byte[0],
206 w.byte[1], w.byte[2], w.byte[3], w.byte[4], w.byte[5],
207 w.byte[6], w.byte[7]);
208}
209
210static inline void
211fcid2str(char *fcid_str, u32 fcid)
212{
213 union {
214 u32 fcid;
215 u8 byte[4];
216 } f;
217
218 f.fcid = fcid;
219 sprintf(fcid_str, "%02x:%02x:%02x", f.byte[1], f.byte[2], f.byte[3]);
220}
221
222#endif /* __BFA_OS_INC_H__ */
diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c
new file mode 100644
index 000000000000..cab19028361a
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_port.c
@@ -0,0 +1,460 @@
1/*
2 * Copyright (c) 2005-2009 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 <defs/bfa_defs_port.h>
19#include <cs/bfa_trc.h>
20#include <cs/bfa_log.h>
21#include <cs/bfa_debug.h>
22#include <port/bfa_port.h>
23#include <bfi/bfi.h>
24#include <bfi/bfi_port.h>
25#include <bfa_ioc.h>
26#include <cna/bfa_cna_trcmod.h>
27
28BFA_TRC_FILE(CNA, PORT);
29
30#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
31#define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc)
32
33static void
34bfa_port_stats_swap(struct bfa_port_s *port, union bfa_pport_stats_u *stats)
35{
36 u32 *dip = (u32 *) stats;
37 u32 t0, t1;
38 int i;
39
40 for (i = 0; i < sizeof(union bfa_pport_stats_u) / sizeof(u32);
41 i += 2) {
42 t0 = dip[i];
43 t1 = dip[i + 1];
44#ifdef __BIGENDIAN
45 dip[i] = bfa_os_ntohl(t0);
46 dip[i + 1] = bfa_os_ntohl(t1);
47#else
48 dip[i] = bfa_os_ntohl(t1);
49 dip[i + 1] = bfa_os_ntohl(t0);
50#endif
51 }
52
53 /** todo
54 * QoS stats r also swapped as 64bit; that structure also
55 * has to use 64 bit counters
56 */
57}
58
59/**
60 * bfa_port_enable_isr()
61 *
62 *
63 * @param[in] port - Pointer to the port module
64 * status - Return status from the f/w
65 *
66 * @return void
67 */
68static void
69bfa_port_enable_isr(struct bfa_port_s *port, bfa_status_t status)
70{
71 bfa_assert(0);
72}
73
74/**
75 * bfa_port_disable_isr()
76 *
77 *
78 * @param[in] port - Pointer to the port module
79 * status - Return status from the f/w
80 *
81 * @return void
82 */
83static void
84bfa_port_disable_isr(struct bfa_port_s *port, bfa_status_t status)
85{
86 bfa_assert(0);
87}
88
89/**
90 * bfa_port_get_stats_isr()
91 *
92 *
93 * @param[in] port - Pointer to the Port module
94 * status - Return status from the f/w
95 *
96 * @return void
97 */
98static void
99bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status)
100{
101 port->stats_status = status;
102 port->stats_busy = BFA_FALSE;
103
104 if (status == BFA_STATUS_OK) {
105 memcpy(port->stats, port->stats_dma.kva,
106 sizeof(union bfa_pport_stats_u));
107 bfa_port_stats_swap(port, port->stats);
108 }
109
110 if (port->stats_cbfn) {
111 port->stats_cbfn(port->stats_cbarg, status);
112 port->stats_cbfn = NULL;
113 }
114}
115
116/**
117 * bfa_port_clear_stats_isr()
118 *
119 *
120 * @param[in] port - Pointer to the Port module
121 * status - Return status from the f/w
122 *
123 * @return void
124 */
125static void
126bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status)
127{
128 port->stats_status = status;
129 port->stats_busy = BFA_FALSE;
130
131 if (port->stats_cbfn) {
132 port->stats_cbfn(port->stats_cbarg, status);
133 port->stats_cbfn = NULL;
134 }
135}
136
137/**
138 * bfa_port_isr()
139 *
140 *
141 * @param[in] Pointer to the Port module data structure.
142 *
143 * @return void
144 */
145static void
146bfa_port_isr(void *cbarg, struct bfi_mbmsg_s *m)
147{
148 struct bfa_port_s *port = (struct bfa_port_s *)cbarg;
149 union bfi_port_i2h_msg_u *i2hmsg;
150
151 i2hmsg = (union bfi_port_i2h_msg_u *)m;
152 bfa_trc(port, m->mh.msg_id);
153
154 switch (m->mh.msg_id) {
155 case BFI_PORT_I2H_ENABLE_RSP:
156 if (port->endis_pending == BFA_FALSE)
157 break;
158 bfa_port_enable_isr(port, i2hmsg->enable_rsp.status);
159 break;
160
161 case BFI_PORT_I2H_DISABLE_RSP:
162 if (port->endis_pending == BFA_FALSE)
163 break;
164 bfa_port_disable_isr(port, i2hmsg->disable_rsp.status);
165 break;
166
167 case BFI_PORT_I2H_GET_STATS_RSP:
168 /*
169 * Stats busy flag is still set? (may be cmd timed out)
170 */
171 if (port->stats_busy == BFA_FALSE)
172 break;
173 bfa_port_get_stats_isr(port, i2hmsg->getstats_rsp.status);
174 break;
175
176 case BFI_PORT_I2H_CLEAR_STATS_RSP:
177 if (port->stats_busy == BFA_FALSE)
178 break;
179 bfa_port_clear_stats_isr(port, i2hmsg->clearstats_rsp.status);
180 break;
181
182 default:
183 bfa_assert(0);
184 }
185}
186
187/**
188 * bfa_port_meminfo()
189 *
190 *
191 * @param[in] void
192 *
193 * @return Size of DMA region
194 */
195u32
196bfa_port_meminfo(void)
197{
198 return BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), BFA_DMA_ALIGN_SZ);
199}
200
201/**
202 * bfa_port_mem_claim()
203 *
204 *
205 * @param[in] port Port module pointer
206 * dma_kva Kernel Virtual Address of Port DMA Memory
207 * dma_pa Physical Address of Port DMA Memory
208 *
209 * @return void
210 */
211void
212bfa_port_mem_claim(struct bfa_port_s *port, u8 *dma_kva, u64 dma_pa)
213{
214 port->stats_dma.kva = dma_kva;
215 port->stats_dma.pa = dma_pa;
216}
217
218/**
219 * bfa_port_enable()
220 *
221 * Send the Port enable request to the f/w
222 *
223 * @param[in] Pointer to the Port module data structure.
224 *
225 * @return Status
226 */
227bfa_status_t
228bfa_port_enable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
229 void *cbarg)
230{
231 struct bfi_port_generic_req_s *m;
232
233 /** todo Not implemented */
234 bfa_assert(0);
235
236 if (!bfa_ioc_is_operational(port->ioc)) {
237 bfa_trc(port, BFA_STATUS_IOC_FAILURE);
238 return BFA_STATUS_IOC_FAILURE;
239 }
240
241 if (port->endis_pending) {
242 bfa_trc(port, BFA_STATUS_DEVBUSY);
243 return BFA_STATUS_DEVBUSY;
244 }
245
246 m = (struct bfi_port_generic_req_s *)port->endis_mb.msg;
247
248 port->msgtag++;
249 port->endis_cbfn = cbfn;
250 port->endis_cbarg = cbarg;
251 port->endis_pending = BFA_TRUE;
252
253 bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_ENABLE_REQ,
254 bfa_ioc_portid(port->ioc));
255 bfa_ioc_mbox_queue(port->ioc, &port->endis_mb);
256
257 return BFA_STATUS_OK;
258}
259
260/**
261 * bfa_port_disable()
262 *
263 * Send the Port disable request to the f/w
264 *
265 * @param[in] Pointer to the Port module data structure.
266 *
267 * @return Status
268 */
269bfa_status_t
270bfa_port_disable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
271 void *cbarg)
272{
273 struct bfi_port_generic_req_s *m;
274
275 /** todo Not implemented */
276 bfa_assert(0);
277
278 if (!bfa_ioc_is_operational(port->ioc)) {
279 bfa_trc(port, BFA_STATUS_IOC_FAILURE);
280 return BFA_STATUS_IOC_FAILURE;
281 }
282
283 if (port->endis_pending) {
284 bfa_trc(port, BFA_STATUS_DEVBUSY);
285 return BFA_STATUS_DEVBUSY;
286 }
287
288 m = (struct bfi_port_generic_req_s *)port->endis_mb.msg;
289
290 port->msgtag++;
291 port->endis_cbfn = cbfn;
292 port->endis_cbarg = cbarg;
293 port->endis_pending = BFA_TRUE;
294
295 bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_DISABLE_REQ,
296 bfa_ioc_portid(port->ioc));
297 bfa_ioc_mbox_queue(port->ioc, &port->endis_mb);
298
299 return BFA_STATUS_OK;
300}
301
302/**
303 * bfa_port_get_stats()
304 *
305 * Send the request to the f/w to fetch Port statistics.
306 *
307 * @param[in] Pointer to the Port module data structure.
308 *
309 * @return Status
310 */
311bfa_status_t
312bfa_port_get_stats(struct bfa_port_s *port, union bfa_pport_stats_u *stats,
313 bfa_port_stats_cbfn_t cbfn, void *cbarg)
314{
315 struct bfi_port_get_stats_req_s *m;
316
317 if (!bfa_ioc_is_operational(port->ioc)) {
318 bfa_trc(port, BFA_STATUS_IOC_FAILURE);
319 return BFA_STATUS_IOC_FAILURE;
320 }
321
322 if (port->stats_busy) {
323 bfa_trc(port, BFA_STATUS_DEVBUSY);
324 return BFA_STATUS_DEVBUSY;
325 }
326
327 m = (struct bfi_port_get_stats_req_s *)port->stats_mb.msg;
328
329 port->stats = stats;
330 port->stats_cbfn = cbfn;
331 port->stats_cbarg = cbarg;
332 port->stats_busy = BFA_TRUE;
333 bfa_dma_be_addr_set(m->dma_addr, port->stats_dma.pa);
334
335 bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_GET_STATS_REQ,
336 bfa_ioc_portid(port->ioc));
337 bfa_ioc_mbox_queue(port->ioc, &port->stats_mb);
338
339 return BFA_STATUS_OK;
340}
341
342/**
343 * bfa_port_clear_stats()
344 *
345 *
346 * @param[in] Pointer to the Port module data structure.
347 *
348 * @return Status
349 */
350bfa_status_t
351bfa_port_clear_stats(struct bfa_port_s *port, bfa_port_stats_cbfn_t cbfn,
352 void *cbarg)
353{
354 struct bfi_port_generic_req_s *m;
355
356 if (!bfa_ioc_is_operational(port->ioc)) {
357 bfa_trc(port, BFA_STATUS_IOC_FAILURE);
358 return BFA_STATUS_IOC_FAILURE;
359 }
360
361 if (port->stats_busy) {
362 bfa_trc(port, BFA_STATUS_DEVBUSY);
363 return BFA_STATUS_DEVBUSY;
364 }
365
366 m = (struct bfi_port_generic_req_s *)port->stats_mb.msg;
367
368 port->stats_cbfn = cbfn;
369 port->stats_cbarg = cbarg;
370 port->stats_busy = BFA_TRUE;
371
372 bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_CLEAR_STATS_REQ,
373 bfa_ioc_portid(port->ioc));
374 bfa_ioc_mbox_queue(port->ioc, &port->stats_mb);
375
376 return BFA_STATUS_OK;
377}
378
379/**
380 * bfa_port_hbfail()
381 *
382 *
383 * @param[in] Pointer to the Port module data structure.
384 *
385 * @return void
386 */
387void
388bfa_port_hbfail(void *arg)
389{
390 struct bfa_port_s *port = (struct bfa_port_s *)arg;
391
392 /*
393 * Fail any pending get_stats/clear_stats requests
394 */
395 if (port->stats_busy) {
396 if (port->stats_cbfn)
397 port->stats_cbfn(port->dev, BFA_STATUS_FAILED);
398 port->stats_cbfn = NULL;
399 port->stats_busy = BFA_FALSE;
400 }
401
402 /*
403 * Clear any enable/disable is pending
404 */
405 if (port->endis_pending) {
406 if (port->endis_cbfn)
407 port->endis_cbfn(port->dev, BFA_STATUS_FAILED);
408 port->endis_cbfn = NULL;
409 port->endis_pending = BFA_FALSE;
410 }
411}
412
413/**
414 * bfa_port_attach()
415 *
416 *
417 * @param[in] port - Pointer to the Port module data structure
418 * ioc - Pointer to the ioc module data structure
419 * dev - Pointer to the device driver module data structure
420 * The device driver specific mbox ISR functions have
421 * this pointer as one of the parameters.
422 * trcmod -
423 * logmod -
424 *
425 * @return void
426 */
427void
428bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, void *dev,
429 struct bfa_trc_mod_s *trcmod, struct bfa_log_mod_s *logmod)
430{
431 bfa_assert(port);
432
433 port->dev = dev;
434 port->ioc = ioc;
435 port->trcmod = trcmod;
436 port->logmod = logmod;
437
438 port->stats_busy = port->endis_pending = BFA_FALSE;
439 port->stats_cbfn = port->endis_cbfn = NULL;
440
441 bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port);
442 bfa_ioc_hbfail_init(&port->hbfail, bfa_port_hbfail, port);
443 bfa_ioc_hbfail_register(port->ioc, &port->hbfail);
444
445 bfa_trc(port, 0);
446}
447
448/**
449 * bfa_port_detach()
450 *
451 *
452 * @param[in] port - Pointer to the Port module data structure
453 *
454 * @return void
455 */
456void
457bfa_port_detach(struct bfa_port_s *port)
458{
459 bfa_trc(port, 0);
460}
diff --git a/drivers/scsi/bfa/bfa_port_priv.h b/drivers/scsi/bfa/bfa_port_priv.h
new file mode 100644
index 000000000000..4b97e2759908
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_port_priv.h
@@ -0,0 +1,90 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_PORT_PRIV_H__
19#define __BFA_PORT_PRIV_H__
20
21#include <defs/bfa_defs_pport.h>
22#include <bfi/bfi_pport.h>
23#include "bfa_intr_priv.h"
24
25/**
26 * BFA physical port data structure
27 */
28struct bfa_pport_s {
29 struct bfa_s *bfa; /* parent BFA instance */
30 bfa_sm_t sm; /* port state machine */
31 wwn_t nwwn; /* node wwn of physical port */
32 wwn_t pwwn; /* port wwn of physical oprt */
33 enum bfa_pport_speed speed_sup;
34 /* supported speeds */
35 enum bfa_pport_speed speed; /* current speed */
36 enum bfa_pport_topology topology; /* current topology */
37 u8 myalpa; /* my ALPA in LOOP topology */
38 u8 rsvd[3];
39 struct bfa_pport_cfg_s cfg; /* current port configuration */
40 struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
41 struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */
42 struct bfa_reqq_wait_s reqq_wait;
43 /* to wait for room in reqq */
44 struct bfa_reqq_wait_s svcreq_wait;
45 /* to wait for room in reqq */
46 struct bfa_reqq_wait_s stats_reqq_wait;
47 /* to wait for room in reqq (stats) */
48 void *event_cbarg;
49 void (*event_cbfn) (void *cbarg,
50 bfa_pport_event_t event);
51 union {
52 union bfi_pport_i2h_msg_u i2hmsg;
53 } event_arg;
54 void *bfad; /* BFA driver handle */
55 struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */
56 enum bfa_pport_linkstate hcb_event;
57 /* link event for callback */
58 u32 msgtag; /* fimrware msg tag for reply */
59 u8 *stats_kva;
60 u64 stats_pa;
61 union bfa_pport_stats_u *stats; /* pport stats */
62 u32 mypid : 24;
63 u32 rsvd_b : 8;
64 struct bfa_timer_s timer; /* timer */
65 union bfa_pport_stats_u *stats_ret;
66 /* driver stats location */
67 bfa_status_t stats_status;
68 /* stats/statsclr status */
69 bfa_boolean_t stats_busy;
70 /* outstanding stats/statsclr */
71 bfa_boolean_t stats_qfull;
72 bfa_boolean_t diag_busy;
73 /* diag busy status */
74 bfa_boolean_t beacon;
75 /* port beacon status */
76 bfa_boolean_t link_e2e_beacon;
77 /* link beacon status */
78 bfa_cb_pport_t stats_cbfn;
79 /* driver callback function */
80 void *stats_cbarg;
81 /* *!< user callback arg */
82};
83
84#define BFA_PORT_MOD(__bfa) (&(__bfa)->modules.pport)
85
86/*
87 * public functions
88 */
89void bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
90#endif /* __BFA_PORT_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_priv.h b/drivers/scsi/bfa/bfa_priv.h
new file mode 100644
index 000000000000..0747a6b26f7b
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_priv.h
@@ -0,0 +1,113 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_PRIV_H__
19#define __BFA_PRIV_H__
20
21#include "bfa_iocfc.h"
22#include "bfa_intr_priv.h"
23#include "bfa_trcmod_priv.h"
24#include "bfa_modules_priv.h"
25#include "bfa_fwimg_priv.h"
26#include <cs/bfa_log.h>
27#include <bfa_timer.h>
28
29/**
30 * Macro to define a new BFA module
31 */
32#define BFA_MODULE(__mod) \
33 static void bfa_ ## __mod ## _meminfo( \
34 struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, \
35 u32 *dm_len); \
36 static void bfa_ ## __mod ## _attach(struct bfa_s *bfa, \
37 void *bfad, struct bfa_iocfc_cfg_s *cfg, \
38 struct bfa_meminfo_s *meminfo, \
39 struct bfa_pcidev_s *pcidev); \
40 static void bfa_ ## __mod ## _initdone(struct bfa_s *bfa); \
41 static void bfa_ ## __mod ## _detach(struct bfa_s *bfa); \
42 static void bfa_ ## __mod ## _start(struct bfa_s *bfa); \
43 static void bfa_ ## __mod ## _stop(struct bfa_s *bfa); \
44 static void bfa_ ## __mod ## _iocdisable(struct bfa_s *bfa); \
45 \
46 extern struct bfa_module_s hal_mod_ ## __mod; \
47 struct bfa_module_s hal_mod_ ## __mod = { \
48 bfa_ ## __mod ## _meminfo, \
49 bfa_ ## __mod ## _attach, \
50 bfa_ ## __mod ## _initdone, \
51 bfa_ ## __mod ## _detach, \
52 bfa_ ## __mod ## _start, \
53 bfa_ ## __mod ## _stop, \
54 bfa_ ## __mod ## _iocdisable, \
55 }
56
57#define BFA_CACHELINE_SZ (256)
58
59/**
60 * Structure used to interact between different BFA sub modules
61 *
62 * Each sub module needs to implement only the entry points relevant to it (and
63 * can leave entry points as NULL)
64 */
65struct bfa_module_s {
66 void (*meminfo) (struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
67 u32 *dm_len);
68 void (*attach) (struct bfa_s *bfa, void *bfad,
69 struct bfa_iocfc_cfg_s *cfg,
70 struct bfa_meminfo_s *meminfo,
71 struct bfa_pcidev_s *pcidev);
72 void (*initdone) (struct bfa_s *bfa);
73 void (*detach) (struct bfa_s *bfa);
74 void (*start) (struct bfa_s *bfa);
75 void (*stop) (struct bfa_s *bfa);
76 void (*iocdisable) (struct bfa_s *bfa);
77};
78
79extern struct bfa_module_s *hal_mods[];
80
81struct bfa_s {
82 void *bfad; /* BFA driver instance */
83 struct bfa_aen_s *aen; /* AEN module */
84 struct bfa_plog_s *plog; /* portlog buffer */
85 struct bfa_log_mod_s *logm; /* driver logging modulen */
86 struct bfa_trc_mod_s *trcmod; /* driver tracing */
87 struct bfa_ioc_s ioc; /* IOC module */
88 struct bfa_iocfc_s iocfc; /* IOCFC module */
89 struct bfa_timer_mod_s timer_mod; /* timer module */
90 struct bfa_modules_s modules; /* BFA modules */
91 struct list_head comp_q; /* pending completions */
92 bfa_boolean_t rme_process; /* RME processing enabled */
93 struct list_head reqq_waitq[BFI_IOC_MAX_CQS];
94 bfa_boolean_t fcs; /* FCS is attached to BFA */
95 struct bfa_msix_s msix;
96};
97
98extern bfa_isr_func_t bfa_isrs[BFI_MC_MAX];
99extern bfa_ioc_mbox_mcfunc_t bfa_mbox_isrs[];
100extern bfa_boolean_t bfa_auto_recover;
101extern struct bfa_module_s hal_mod_flash;
102extern struct bfa_module_s hal_mod_fcdiag;
103extern struct bfa_module_s hal_mod_sgpg;
104extern struct bfa_module_s hal_mod_pport;
105extern struct bfa_module_s hal_mod_fcxp;
106extern struct bfa_module_s hal_mod_lps;
107extern struct bfa_module_s hal_mod_uf;
108extern struct bfa_module_s hal_mod_rport;
109extern struct bfa_module_s hal_mod_fcpim;
110extern struct bfa_module_s hal_mod_pbind;
111
112#endif /* __BFA_PRIV_H__ */
113
diff --git a/drivers/scsi/bfa/bfa_rport.c b/drivers/scsi/bfa/bfa_rport.c
new file mode 100644
index 000000000000..16da77a8db28
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_rport.c
@@ -0,0 +1,911 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19#include <bfa_svc.h>
20#include <cs/bfa_debug.h>
21#include <bfi/bfi_rport.h>
22#include "bfa_intr_priv.h"
23
24BFA_TRC_FILE(HAL, RPORT);
25BFA_MODULE(rport);
26
27#define bfa_rport_offline_cb(__rp) do { \
28 if ((__rp)->bfa->fcs) \
29 bfa_cb_rport_offline((__rp)->rport_drv); \
30 else { \
31 bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \
32 __bfa_cb_rport_offline, (__rp)); \
33 } \
34} while (0)
35
36#define bfa_rport_online_cb(__rp) do { \
37 if ((__rp)->bfa->fcs) \
38 bfa_cb_rport_online((__rp)->rport_drv); \
39 else { \
40 bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \
41 __bfa_cb_rport_online, (__rp)); \
42 } \
43} while (0)
44
45/*
46 * forward declarations
47 */
48static struct bfa_rport_s *bfa_rport_alloc(struct bfa_rport_mod_s *rp_mod);
49static void bfa_rport_free(struct bfa_rport_s *rport);
50static bfa_boolean_t bfa_rport_send_fwcreate(struct bfa_rport_s *rp);
51static bfa_boolean_t bfa_rport_send_fwdelete(struct bfa_rport_s *rp);
52static bfa_boolean_t bfa_rport_send_fwspeed(struct bfa_rport_s *rp);
53static void __bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete);
54static void __bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete);
55
56/**
57 * bfa_rport_sm BFA rport state machine
58 */
59
60
61enum bfa_rport_event {
62 BFA_RPORT_SM_CREATE = 1, /* rport create event */
63 BFA_RPORT_SM_DELETE = 2, /* deleting an existing rport */
64 BFA_RPORT_SM_ONLINE = 3, /* rport is online */
65 BFA_RPORT_SM_OFFLINE = 4, /* rport is offline */
66 BFA_RPORT_SM_FWRSP = 5, /* firmware response */
67 BFA_RPORT_SM_HWFAIL = 6, /* IOC h/w failure */
68 BFA_RPORT_SM_QOS_SCN = 7, /* QoS SCN from firmware */
69 BFA_RPORT_SM_SET_SPEED = 8, /* Set Rport Speed */
70 BFA_RPORT_SM_QRESUME = 9, /* space in requeue queue */
71};
72
73static void bfa_rport_sm_uninit(struct bfa_rport_s *rp,
74 enum bfa_rport_event event);
75static void bfa_rport_sm_created(struct bfa_rport_s *rp,
76 enum bfa_rport_event event);
77static void bfa_rport_sm_fwcreate(struct bfa_rport_s *rp,
78 enum bfa_rport_event event);
79static void bfa_rport_sm_online(struct bfa_rport_s *rp,
80 enum bfa_rport_event event);
81static void bfa_rport_sm_fwdelete(struct bfa_rport_s *rp,
82 enum bfa_rport_event event);
83static void bfa_rport_sm_offline(struct bfa_rport_s *rp,
84 enum bfa_rport_event event);
85static void bfa_rport_sm_deleting(struct bfa_rport_s *rp,
86 enum bfa_rport_event event);
87static void bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
88 enum bfa_rport_event event);
89static void bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
90 enum bfa_rport_event event);
91static void bfa_rport_sm_iocdisable(struct bfa_rport_s *rp,
92 enum bfa_rport_event event);
93static void bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp,
94 enum bfa_rport_event event);
95static void bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp,
96 enum bfa_rport_event event);
97static void bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp,
98 enum bfa_rport_event event);
99
100/**
101 * Beginning state, only online event expected.
102 */
103static void
104bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event)
105{
106 bfa_trc(rp->bfa, rp->rport_tag);
107 bfa_trc(rp->bfa, event);
108
109 switch (event) {
110 case BFA_RPORT_SM_CREATE:
111 bfa_stats(rp, sm_un_cr);
112 bfa_sm_set_state(rp, bfa_rport_sm_created);
113 break;
114
115 default:
116 bfa_stats(rp, sm_un_unexp);
117 bfa_assert(0);
118 }
119}
120
121static void
122bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event)
123{
124 bfa_trc(rp->bfa, rp->rport_tag);
125 bfa_trc(rp->bfa, event);
126
127 switch (event) {
128 case BFA_RPORT_SM_ONLINE:
129 bfa_stats(rp, sm_cr_on);
130 if (bfa_rport_send_fwcreate(rp))
131 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
132 else
133 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
134 break;
135
136 case BFA_RPORT_SM_DELETE:
137 bfa_stats(rp, sm_cr_del);
138 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
139 bfa_rport_free(rp);
140 break;
141
142 case BFA_RPORT_SM_HWFAIL:
143 bfa_stats(rp, sm_cr_hwf);
144 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
145 break;
146
147 default:
148 bfa_stats(rp, sm_cr_unexp);
149 bfa_assert(0);
150 }
151}
152
153/**
154 * Waiting for rport create response from firmware.
155 */
156static void
157bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event)
158{
159 bfa_trc(rp->bfa, rp->rport_tag);
160 bfa_trc(rp->bfa, event);
161
162 switch (event) {
163 case BFA_RPORT_SM_FWRSP:
164 bfa_stats(rp, sm_fwc_rsp);
165 bfa_sm_set_state(rp, bfa_rport_sm_online);
166 bfa_rport_online_cb(rp);
167 break;
168
169 case BFA_RPORT_SM_DELETE:
170 bfa_stats(rp, sm_fwc_del);
171 bfa_sm_set_state(rp, bfa_rport_sm_delete_pending);
172 break;
173
174 case BFA_RPORT_SM_OFFLINE:
175 bfa_stats(rp, sm_fwc_off);
176 bfa_sm_set_state(rp, bfa_rport_sm_offline_pending);
177 break;
178
179 case BFA_RPORT_SM_HWFAIL:
180 bfa_stats(rp, sm_fwc_hwf);
181 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
182 break;
183
184 default:
185 bfa_stats(rp, sm_fwc_unexp);
186 bfa_assert(0);
187 }
188}
189
190/**
191 * Request queue is full, awaiting queue resume to send create request.
192 */
193static void
194bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
195{
196 bfa_trc(rp->bfa, rp->rport_tag);
197 bfa_trc(rp->bfa, event);
198
199 switch (event) {
200 case BFA_RPORT_SM_QRESUME:
201 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
202 bfa_rport_send_fwcreate(rp);
203 break;
204
205 case BFA_RPORT_SM_DELETE:
206 bfa_stats(rp, sm_fwc_del);
207 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
208 bfa_reqq_wcancel(&rp->reqq_wait);
209 bfa_rport_free(rp);
210 break;
211
212 case BFA_RPORT_SM_OFFLINE:
213 bfa_stats(rp, sm_fwc_off);
214 bfa_sm_set_state(rp, bfa_rport_sm_offline);
215 bfa_reqq_wcancel(&rp->reqq_wait);
216 bfa_rport_offline_cb(rp);
217 break;
218
219 case BFA_RPORT_SM_HWFAIL:
220 bfa_stats(rp, sm_fwc_hwf);
221 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
222 bfa_reqq_wcancel(&rp->reqq_wait);
223 break;
224
225 default:
226 bfa_stats(rp, sm_fwc_unexp);
227 bfa_assert(0);
228 }
229}
230
231/**
232 * Online state - normal parking state.
233 */
234static void
235bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event)
236{
237 struct bfi_rport_qos_scn_s *qos_scn;
238
239 bfa_trc(rp->bfa, rp->rport_tag);
240 bfa_trc(rp->bfa, event);
241
242 switch (event) {
243 case BFA_RPORT_SM_OFFLINE:
244 bfa_stats(rp, sm_on_off);
245 if (bfa_rport_send_fwdelete(rp))
246 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
247 else
248 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull);
249 break;
250
251 case BFA_RPORT_SM_DELETE:
252 bfa_stats(rp, sm_on_del);
253 if (bfa_rport_send_fwdelete(rp))
254 bfa_sm_set_state(rp, bfa_rport_sm_deleting);
255 else
256 bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
257 break;
258
259 case BFA_RPORT_SM_HWFAIL:
260 bfa_stats(rp, sm_on_hwf);
261 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
262 break;
263
264 case BFA_RPORT_SM_SET_SPEED:
265 bfa_rport_send_fwspeed(rp);
266 break;
267
268 case BFA_RPORT_SM_QOS_SCN:
269 qos_scn = (struct bfi_rport_qos_scn_s *) rp->event_arg.fw_msg;
270 rp->qos_attr = qos_scn->new_qos_attr;
271 bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_flow_id);
272 bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_flow_id);
273 bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_priority);
274 bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_priority);
275
276 qos_scn->old_qos_attr.qos_flow_id =
277 bfa_os_ntohl(qos_scn->old_qos_attr.qos_flow_id);
278 qos_scn->new_qos_attr.qos_flow_id =
279 bfa_os_ntohl(qos_scn->new_qos_attr.qos_flow_id);
280 qos_scn->old_qos_attr.qos_priority =
281 bfa_os_ntohl(qos_scn->old_qos_attr.qos_priority);
282 qos_scn->new_qos_attr.qos_priority =
283 bfa_os_ntohl(qos_scn->new_qos_attr.qos_priority);
284
285 if (qos_scn->old_qos_attr.qos_flow_id !=
286 qos_scn->new_qos_attr.qos_flow_id)
287 bfa_cb_rport_qos_scn_flowid(rp->rport_drv,
288 qos_scn->old_qos_attr,
289 qos_scn->new_qos_attr);
290 if (qos_scn->old_qos_attr.qos_priority !=
291 qos_scn->new_qos_attr.qos_priority)
292 bfa_cb_rport_qos_scn_prio(rp->rport_drv,
293 qos_scn->old_qos_attr,
294 qos_scn->new_qos_attr);
295 break;
296
297 default:
298 bfa_stats(rp, sm_on_unexp);
299 bfa_assert(0);
300 }
301}
302
303/**
304 * Firmware rport is being deleted - awaiting f/w response.
305 */
306static void
307bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event)
308{
309 bfa_trc(rp->bfa, rp->rport_tag);
310 bfa_trc(rp->bfa, event);
311
312 switch (event) {
313 case BFA_RPORT_SM_FWRSP:
314 bfa_stats(rp, sm_fwd_rsp);
315 bfa_sm_set_state(rp, bfa_rport_sm_offline);
316 bfa_rport_offline_cb(rp);
317 break;
318
319 case BFA_RPORT_SM_DELETE:
320 bfa_stats(rp, sm_fwd_del);
321 bfa_sm_set_state(rp, bfa_rport_sm_deleting);
322 break;
323
324 case BFA_RPORT_SM_HWFAIL:
325 bfa_stats(rp, sm_fwd_hwf);
326 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
327 bfa_rport_offline_cb(rp);
328 break;
329
330 default:
331 bfa_stats(rp, sm_fwd_unexp);
332 bfa_assert(0);
333 }
334}
335
336static void
337bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
338{
339 bfa_trc(rp->bfa, rp->rport_tag);
340 bfa_trc(rp->bfa, event);
341
342 switch (event) {
343 case BFA_RPORT_SM_QRESUME:
344 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
345 bfa_rport_send_fwdelete(rp);
346 break;
347
348 case BFA_RPORT_SM_DELETE:
349 bfa_stats(rp, sm_fwd_del);
350 bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
351 break;
352
353 case BFA_RPORT_SM_HWFAIL:
354 bfa_stats(rp, sm_fwd_hwf);
355 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
356 bfa_reqq_wcancel(&rp->reqq_wait);
357 bfa_rport_offline_cb(rp);
358 break;
359
360 default:
361 bfa_stats(rp, sm_fwd_unexp);
362 bfa_assert(0);
363 }
364}
365
366/**
367 * Offline state.
368 */
369static void
370bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event)
371{
372 bfa_trc(rp->bfa, rp->rport_tag);
373 bfa_trc(rp->bfa, event);
374
375 switch (event) {
376 case BFA_RPORT_SM_DELETE:
377 bfa_stats(rp, sm_off_del);
378 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
379 bfa_rport_free(rp);
380 break;
381
382 case BFA_RPORT_SM_ONLINE:
383 bfa_stats(rp, sm_off_on);
384 if (bfa_rport_send_fwcreate(rp))
385 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
386 else
387 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
388 break;
389
390 case BFA_RPORT_SM_HWFAIL:
391 bfa_stats(rp, sm_off_hwf);
392 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
393 break;
394
395 default:
396 bfa_stats(rp, sm_off_unexp);
397 bfa_assert(0);
398 }
399}
400
401/**
402 * Rport is deleted, waiting for firmware response to delete.
403 */
404static void
405bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event)
406{
407 bfa_trc(rp->bfa, rp->rport_tag);
408 bfa_trc(rp->bfa, event);
409
410 switch (event) {
411 case BFA_RPORT_SM_FWRSP:
412 bfa_stats(rp, sm_del_fwrsp);
413 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
414 bfa_rport_free(rp);
415 break;
416
417 case BFA_RPORT_SM_HWFAIL:
418 bfa_stats(rp, sm_del_hwf);
419 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
420 bfa_rport_free(rp);
421 break;
422
423 default:
424 bfa_assert(0);
425 }
426}
427
428static void
429bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
430{
431 bfa_trc(rp->bfa, rp->rport_tag);
432 bfa_trc(rp->bfa, event);
433
434 switch (event) {
435 case BFA_RPORT_SM_QRESUME:
436 bfa_stats(rp, sm_del_fwrsp);
437 bfa_sm_set_state(rp, bfa_rport_sm_deleting);
438 bfa_rport_send_fwdelete(rp);
439 break;
440
441 case BFA_RPORT_SM_HWFAIL:
442 bfa_stats(rp, sm_del_hwf);
443 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
444 bfa_reqq_wcancel(&rp->reqq_wait);
445 bfa_rport_free(rp);
446 break;
447
448 default:
449 bfa_assert(0);
450 }
451}
452
453/**
454 * Waiting for rport create response from firmware. A delete is pending.
455 */
456static void
457bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
458 enum bfa_rport_event event)
459{
460 bfa_trc(rp->bfa, rp->rport_tag);
461 bfa_trc(rp->bfa, event);
462
463 switch (event) {
464 case BFA_RPORT_SM_FWRSP:
465 bfa_stats(rp, sm_delp_fwrsp);
466 if (bfa_rport_send_fwdelete(rp))
467 bfa_sm_set_state(rp, bfa_rport_sm_deleting);
468 else
469 bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
470 break;
471
472 case BFA_RPORT_SM_HWFAIL:
473 bfa_stats(rp, sm_delp_hwf);
474 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
475 bfa_rport_free(rp);
476 break;
477
478 default:
479 bfa_stats(rp, sm_delp_unexp);
480 bfa_assert(0);
481 }
482}
483
484/**
485 * Waiting for rport create response from firmware. Rport offline is pending.
486 */
487static void
488bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
489 enum bfa_rport_event event)
490{
491 bfa_trc(rp->bfa, rp->rport_tag);
492 bfa_trc(rp->bfa, event);
493
494 switch (event) {
495 case BFA_RPORT_SM_FWRSP:
496 bfa_stats(rp, sm_offp_fwrsp);
497 if (bfa_rport_send_fwdelete(rp))
498 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
499 else
500 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull);
501 break;
502
503 case BFA_RPORT_SM_DELETE:
504 bfa_stats(rp, sm_offp_del);
505 bfa_sm_set_state(rp, bfa_rport_sm_delete_pending);
506 break;
507
508 case BFA_RPORT_SM_HWFAIL:
509 bfa_stats(rp, sm_offp_hwf);
510 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
511 break;
512
513 default:
514 bfa_stats(rp, sm_offp_unexp);
515 bfa_assert(0);
516 }
517}
518
519/**
520 * IOC h/w failed.
521 */
522static void
523bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event)
524{
525 bfa_trc(rp->bfa, rp->rport_tag);
526 bfa_trc(rp->bfa, event);
527
528 switch (event) {
529 case BFA_RPORT_SM_OFFLINE:
530 bfa_stats(rp, sm_iocd_off);
531 bfa_rport_offline_cb(rp);
532 break;
533
534 case BFA_RPORT_SM_DELETE:
535 bfa_stats(rp, sm_iocd_del);
536 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
537 bfa_rport_free(rp);
538 break;
539
540 case BFA_RPORT_SM_ONLINE:
541 bfa_stats(rp, sm_iocd_on);
542 if (bfa_rport_send_fwcreate(rp))
543 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
544 else
545 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
546 break;
547
548 case BFA_RPORT_SM_HWFAIL:
549 break;
550
551 default:
552 bfa_stats(rp, sm_iocd_unexp);
553 bfa_assert(0);
554 }
555}
556
557
558
559/**
560 * bfa_rport_private BFA rport private functions
561 */
562
563static void
564__bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete)
565{
566 struct bfa_rport_s *rp = cbarg;
567
568 if (complete)
569 bfa_cb_rport_online(rp->rport_drv);
570}
571
572static void
573__bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete)
574{
575 struct bfa_rport_s *rp = cbarg;
576
577 if (complete)
578 bfa_cb_rport_offline(rp->rport_drv);
579}
580
581static void
582bfa_rport_qresume(void *cbarg)
583{
584 struct bfa_rport_s *rp = cbarg;
585
586 bfa_sm_send_event(rp, BFA_RPORT_SM_QRESUME);
587}
588
589static void
590bfa_rport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
591 u32 *dm_len)
592{
593 if (cfg->fwcfg.num_rports < BFA_RPORT_MIN)
594 cfg->fwcfg.num_rports = BFA_RPORT_MIN;
595
596 *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_rport_s);
597}
598
599static void
600bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
601 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
602{
603 struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa);
604 struct bfa_rport_s *rp;
605 u16 i;
606
607 INIT_LIST_HEAD(&mod->rp_free_q);
608 INIT_LIST_HEAD(&mod->rp_active_q);
609
610 rp = (struct bfa_rport_s *) bfa_meminfo_kva(meminfo);
611 mod->rps_list = rp;
612 mod->num_rports = cfg->fwcfg.num_rports;
613
614 bfa_assert(mod->num_rports
615 && !(mod->num_rports & (mod->num_rports - 1)));
616
617 for (i = 0; i < mod->num_rports; i++, rp++) {
618 bfa_os_memset(rp, 0, sizeof(struct bfa_rport_s));
619 rp->bfa = bfa;
620 rp->rport_tag = i;
621 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
622
623 /**
624 * - is unused
625 */
626 if (i)
627 list_add_tail(&rp->qe, &mod->rp_free_q);
628
629 bfa_reqq_winit(&rp->reqq_wait, bfa_rport_qresume, rp);
630 }
631
632 /**
633 * consume memory
634 */
635 bfa_meminfo_kva(meminfo) = (u8 *) rp;
636}
637
638static void
639bfa_rport_initdone(struct bfa_s *bfa)
640{
641}
642
643static void
644bfa_rport_detach(struct bfa_s *bfa)
645{
646}
647
648static void
649bfa_rport_start(struct bfa_s *bfa)
650{
651}
652
653static void
654bfa_rport_stop(struct bfa_s *bfa)
655{
656}
657
658static void
659bfa_rport_iocdisable(struct bfa_s *bfa)
660{
661 struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa);
662 struct bfa_rport_s *rport;
663 struct list_head *qe, *qen;
664
665 list_for_each_safe(qe, qen, &mod->rp_active_q) {
666 rport = (struct bfa_rport_s *) qe;
667 bfa_sm_send_event(rport, BFA_RPORT_SM_HWFAIL);
668 }
669}
670
671static struct bfa_rport_s *
672bfa_rport_alloc(struct bfa_rport_mod_s *mod)
673{
674 struct bfa_rport_s *rport;
675
676 bfa_q_deq(&mod->rp_free_q, &rport);
677 if (rport)
678 list_add_tail(&rport->qe, &mod->rp_active_q);
679
680 return (rport);
681}
682
683static void
684bfa_rport_free(struct bfa_rport_s *rport)
685{
686 struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(rport->bfa);
687
688 bfa_assert(bfa_q_is_on_q(&mod->rp_active_q, rport));
689 list_del(&rport->qe);
690 list_add_tail(&rport->qe, &mod->rp_free_q);
691}
692
693static bfa_boolean_t
694bfa_rport_send_fwcreate(struct bfa_rport_s *rp)
695{
696 struct bfi_rport_create_req_s *m;
697
698 /**
699 * check for room in queue to send request now
700 */
701 m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
702 if (!m) {
703 bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait);
704 return BFA_FALSE;
705 }
706
707 bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_CREATE_REQ,
708 bfa_lpuid(rp->bfa));
709 m->bfa_handle = rp->rport_tag;
710 m->max_frmsz = bfa_os_htons(rp->rport_info.max_frmsz);
711 m->pid = rp->rport_info.pid;
712 m->lp_tag = rp->rport_info.lp_tag;
713 m->local_pid = rp->rport_info.local_pid;
714 m->fc_class = rp->rport_info.fc_class;
715 m->vf_en = rp->rport_info.vf_en;
716 m->vf_id = rp->rport_info.vf_id;
717 m->cisc = rp->rport_info.cisc;
718
719 /**
720 * queue I/O message to firmware
721 */
722 bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
723 return BFA_TRUE;
724}
725
726static bfa_boolean_t
727bfa_rport_send_fwdelete(struct bfa_rport_s *rp)
728{
729 struct bfi_rport_delete_req_s *m;
730
731 /**
732 * check for room in queue to send request now
733 */
734 m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
735 if (!m) {
736 bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait);
737 return BFA_FALSE;
738 }
739
740 bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_DELETE_REQ,
741 bfa_lpuid(rp->bfa));
742 m->fw_handle = rp->fw_handle;
743
744 /**
745 * queue I/O message to firmware
746 */
747 bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
748 return BFA_TRUE;
749}
750
751static bfa_boolean_t
752bfa_rport_send_fwspeed(struct bfa_rport_s *rp)
753{
754 struct bfa_rport_speed_req_s *m;
755
756 /**
757 * check for room in queue to send request now
758 */
759 m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
760 if (!m) {
761 bfa_trc(rp->bfa, rp->rport_info.speed);
762 return BFA_FALSE;
763 }
764
765 bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_SET_SPEED_REQ,
766 bfa_lpuid(rp->bfa));
767 m->fw_handle = rp->fw_handle;
768 m->speed = (u8)rp->rport_info.speed;
769
770 /**
771 * queue I/O message to firmware
772 */
773 bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
774 return BFA_TRUE;
775}
776
777
778
779/**
780 * bfa_rport_public
781 */
782
783/**
784 * Rport interrupt processing.
785 */
786void
787bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
788{
789 union bfi_rport_i2h_msg_u msg;
790 struct bfa_rport_s *rp;
791
792 bfa_trc(bfa, m->mhdr.msg_id);
793
794 msg.msg = m;
795
796 switch (m->mhdr.msg_id) {
797 case BFI_RPORT_I2H_CREATE_RSP:
798 rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle);
799 rp->fw_handle = msg.create_rsp->fw_handle;
800 rp->qos_attr = msg.create_rsp->qos_attr;
801 bfa_assert(msg.create_rsp->status == BFA_STATUS_OK);
802 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
803 break;
804
805 case BFI_RPORT_I2H_DELETE_RSP:
806 rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle);
807 bfa_assert(msg.delete_rsp->status == BFA_STATUS_OK);
808 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
809 break;
810
811 case BFI_RPORT_I2H_QOS_SCN:
812 rp = BFA_RPORT_FROM_TAG(bfa, msg.qos_scn_evt->bfa_handle);
813 rp->event_arg.fw_msg = msg.qos_scn_evt;
814 bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN);
815 break;
816
817 default:
818 bfa_trc(bfa, m->mhdr.msg_id);
819 bfa_assert(0);
820 }
821}
822
823
824
825/**
826 * bfa_rport_api
827 */
828
829struct bfa_rport_s *
830bfa_rport_create(struct bfa_s *bfa, void *rport_drv)
831{
832 struct bfa_rport_s *rp;
833
834 rp = bfa_rport_alloc(BFA_RPORT_MOD(bfa));
835
836 if (rp == NULL)
837 return (NULL);
838
839 rp->bfa = bfa;
840 rp->rport_drv = rport_drv;
841 bfa_rport_clear_stats(rp);
842
843 bfa_assert(bfa_sm_cmp_state(rp, bfa_rport_sm_uninit));
844 bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE);
845
846 return (rp);
847}
848
849void
850bfa_rport_delete(struct bfa_rport_s *rport)
851{
852 bfa_sm_send_event(rport, BFA_RPORT_SM_DELETE);
853}
854
855void
856bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info)
857{
858 bfa_assert(rport_info->max_frmsz != 0);
859
860 /**
861 * Some JBODs are seen to be not setting PDU size correctly in PLOGI
862 * responses. Default to minimum size.
863 */
864 if (rport_info->max_frmsz == 0) {
865 bfa_trc(rport->bfa, rport->rport_tag);
866 rport_info->max_frmsz = FC_MIN_PDUSZ;
867 }
868
869 bfa_os_assign(rport->rport_info, *rport_info);
870 bfa_sm_send_event(rport, BFA_RPORT_SM_ONLINE);
871}
872
873void
874bfa_rport_offline(struct bfa_rport_s *rport)
875{
876 bfa_sm_send_event(rport, BFA_RPORT_SM_OFFLINE);
877}
878
879void
880bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_pport_speed speed)
881{
882 bfa_assert(speed != 0);
883 bfa_assert(speed != BFA_PPORT_SPEED_AUTO);
884
885 rport->rport_info.speed = speed;
886 bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED);
887}
888
889void
890bfa_rport_get_stats(struct bfa_rport_s *rport,
891 struct bfa_rport_hal_stats_s *stats)
892{
893 *stats = rport->stats;
894}
895
896void
897bfa_rport_get_qos_attr(struct bfa_rport_s *rport,
898 struct bfa_rport_qos_attr_s *qos_attr)
899{
900 qos_attr->qos_priority = bfa_os_ntohl(rport->qos_attr.qos_priority);
901 qos_attr->qos_flow_id = bfa_os_ntohl(rport->qos_attr.qos_flow_id);
902
903}
904
905void
906bfa_rport_clear_stats(struct bfa_rport_s *rport)
907{
908 bfa_os_memset(&rport->stats, 0, sizeof(rport->stats));
909}
910
911
diff --git a/drivers/scsi/bfa/bfa_rport_priv.h b/drivers/scsi/bfa/bfa_rport_priv.h
new file mode 100644
index 000000000000..6490ce2e990d
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_rport_priv.h
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_RPORT_PRIV_H__
19#define __BFA_RPORT_PRIV_H__
20
21#include <bfa_svc.h>
22
23#define BFA_RPORT_MIN 4
24
25struct bfa_rport_mod_s {
26 struct bfa_rport_s *rps_list; /* list of rports */
27 struct list_head rp_free_q; /* free bfa_rports */
28 struct list_head rp_active_q; /* free bfa_rports */
29 u16 num_rports; /* number of rports */
30};
31
32#define BFA_RPORT_MOD(__bfa) (&(__bfa)->modules.rport_mod)
33
34/**
35 * Convert rport tag to RPORT
36 */
37#define BFA_RPORT_FROM_TAG(__bfa, _tag) \
38 (BFA_RPORT_MOD(__bfa)->rps_list + \
39 ((_tag) & (BFA_RPORT_MOD(__bfa)->num_rports - 1)))
40
41/*
42 * external functions
43 */
44void bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
45#endif /* __BFA_RPORT_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_sgpg.c b/drivers/scsi/bfa/bfa_sgpg.c
new file mode 100644
index 000000000000..279d8f9b8907
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_sgpg.c
@@ -0,0 +1,231 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19
20BFA_TRC_FILE(HAL, SGPG);
21BFA_MODULE(sgpg);
22
23/**
24 * bfa_sgpg_mod BFA SGPG Mode module
25 */
26
27/**
28 * Compute and return memory needed by FCP(im) module.
29 */
30static void
31bfa_sgpg_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
32 u32 *dm_len)
33{
34 if (cfg->drvcfg.num_sgpgs < BFA_SGPG_MIN)
35 cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN;
36
37 *km_len += (cfg->drvcfg.num_sgpgs + 1) * sizeof(struct bfa_sgpg_s);
38 *dm_len += (cfg->drvcfg.num_sgpgs + 1) * sizeof(struct bfi_sgpg_s);
39}
40
41
42static void
43bfa_sgpg_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
44 struct bfa_meminfo_s *minfo, struct bfa_pcidev_s *pcidev)
45{
46 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
47 int i;
48 struct bfa_sgpg_s *hsgpg;
49 struct bfi_sgpg_s *sgpg;
50 u64 align_len;
51
52 union {
53 u64 pa;
54 union bfi_addr_u addr;
55 } sgpg_pa;
56
57 INIT_LIST_HEAD(&mod->sgpg_q);
58 INIT_LIST_HEAD(&mod->sgpg_wait_q);
59
60 bfa_trc(bfa, cfg->drvcfg.num_sgpgs);
61
62 mod->num_sgpgs = cfg->drvcfg.num_sgpgs;
63 mod->sgpg_arr_pa = bfa_meminfo_dma_phys(minfo);
64 align_len = (BFA_SGPG_ROUNDUP(mod->sgpg_arr_pa) - mod->sgpg_arr_pa);
65 mod->sgpg_arr_pa += align_len;
66 mod->hsgpg_arr = (struct bfa_sgpg_s *) (bfa_meminfo_kva(minfo) +
67 align_len);
68 mod->sgpg_arr = (struct bfi_sgpg_s *) (bfa_meminfo_dma_virt(minfo) +
69 align_len);
70
71 hsgpg = mod->hsgpg_arr;
72 sgpg = mod->sgpg_arr;
73 sgpg_pa.pa = mod->sgpg_arr_pa;
74 mod->free_sgpgs = mod->num_sgpgs;
75
76 bfa_assert(!(sgpg_pa.pa & (sizeof(struct bfi_sgpg_s) - 1)));
77
78 for (i = 0; i < mod->num_sgpgs; i++) {
79 bfa_os_memset(hsgpg, 0, sizeof(*hsgpg));
80 bfa_os_memset(sgpg, 0, sizeof(*sgpg));
81
82 hsgpg->sgpg = sgpg;
83 hsgpg->sgpg_pa = sgpg_pa.addr;
84 list_add_tail(&hsgpg->qe, &mod->sgpg_q);
85
86 hsgpg++;
87 sgpg++;
88 sgpg_pa.pa += sizeof(struct bfi_sgpg_s);
89 }
90
91 bfa_meminfo_kva(minfo) = (u8 *) hsgpg;
92 bfa_meminfo_dma_virt(minfo) = (u8 *) sgpg;
93 bfa_meminfo_dma_phys(minfo) = sgpg_pa.pa;
94}
95
96static void
97bfa_sgpg_initdone(struct bfa_s *bfa)
98{
99}
100
101static void
102bfa_sgpg_detach(struct bfa_s *bfa)
103{
104}
105
106static void
107bfa_sgpg_start(struct bfa_s *bfa)
108{
109}
110
111static void
112bfa_sgpg_stop(struct bfa_s *bfa)
113{
114}
115
116static void
117bfa_sgpg_iocdisable(struct bfa_s *bfa)
118{
119}
120
121
122
123/**
124 * bfa_sgpg_public BFA SGPG public functions
125 */
126
127bfa_status_t
128bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpgs)
129{
130 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
131 struct bfa_sgpg_s *hsgpg;
132 int i;
133
134 bfa_trc_fp(bfa, nsgpgs);
135
136 if (mod->free_sgpgs < nsgpgs)
137 return BFA_STATUS_ENOMEM;
138
139 for (i = 0; i < nsgpgs; i++) {
140 bfa_q_deq(&mod->sgpg_q, &hsgpg);
141 bfa_assert(hsgpg);
142 list_add_tail(&hsgpg->qe, sgpg_q);
143 }
144
145 mod->free_sgpgs -= nsgpgs;
146 return BFA_STATUS_OK;
147}
148
149void
150bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpg)
151{
152 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
153 struct bfa_sgpg_wqe_s *wqe;
154
155 bfa_trc_fp(bfa, nsgpg);
156
157 mod->free_sgpgs += nsgpg;
158 bfa_assert(mod->free_sgpgs <= mod->num_sgpgs);
159
160 list_splice_tail_init(sgpg_q, &mod->sgpg_q);
161
162 if (list_empty(&mod->sgpg_wait_q))
163 return;
164
165 /**
166 * satisfy as many waiting requests as possible
167 */
168 do {
169 wqe = bfa_q_first(&mod->sgpg_wait_q);
170 if (mod->free_sgpgs < wqe->nsgpg)
171 nsgpg = mod->free_sgpgs;
172 else
173 nsgpg = wqe->nsgpg;
174 bfa_sgpg_malloc(bfa, &wqe->sgpg_q, nsgpg);
175 wqe->nsgpg -= nsgpg;
176 if (wqe->nsgpg == 0) {
177 list_del(&wqe->qe);
178 wqe->cbfn(wqe->cbarg);
179 }
180 } while (mod->free_sgpgs && !list_empty(&mod->sgpg_wait_q));
181}
182
183void
184bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, int nsgpg)
185{
186 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
187
188 bfa_assert(nsgpg > 0);
189 bfa_assert(nsgpg > mod->free_sgpgs);
190
191 wqe->nsgpg_total = wqe->nsgpg = nsgpg;
192
193 /**
194 * allocate any left to this one first
195 */
196 if (mod->free_sgpgs) {
197 /**
198 * no one else is waiting for SGPG
199 */
200 bfa_assert(list_empty(&mod->sgpg_wait_q));
201 list_splice_tail_init(&mod->sgpg_q, &wqe->sgpg_q);
202 wqe->nsgpg -= mod->free_sgpgs;
203 mod->free_sgpgs = 0;
204 }
205
206 list_add_tail(&wqe->qe, &mod->sgpg_wait_q);
207}
208
209void
210bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe)
211{
212 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
213
214 bfa_assert(bfa_q_is_on_q(&mod->sgpg_wait_q, wqe));
215 list_del(&wqe->qe);
216
217 if (wqe->nsgpg_total != wqe->nsgpg)
218 bfa_sgpg_mfree(bfa, &wqe->sgpg_q,
219 wqe->nsgpg_total - wqe->nsgpg);
220}
221
222void
223bfa_sgpg_winit(struct bfa_sgpg_wqe_s *wqe, void (*cbfn) (void *cbarg),
224 void *cbarg)
225{
226 INIT_LIST_HEAD(&wqe->sgpg_q);
227 wqe->cbfn = cbfn;
228 wqe->cbarg = cbarg;
229}
230
231
diff --git a/drivers/scsi/bfa/bfa_sgpg_priv.h b/drivers/scsi/bfa/bfa_sgpg_priv.h
new file mode 100644
index 000000000000..9c2a8cbe7522
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_sgpg_priv.h
@@ -0,0 +1,79 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * hal_sgpg.h BFA SG page module
20 */
21
22#ifndef __BFA_SGPG_PRIV_H__
23#define __BFA_SGPG_PRIV_H__
24
25#include <cs/bfa_q.h>
26
27#define BFA_SGPG_MIN (16)
28
29/**
30 * Alignment macro for SG page allocation
31 */
32#define BFA_SGPG_ROUNDUP(_l) (((_l) + (sizeof(struct bfi_sgpg_s) - 1)) \
33 & ~(sizeof(struct bfi_sgpg_s) - 1))
34
35struct bfa_sgpg_wqe_s {
36 struct list_head qe; /* queue sg page element */
37 int nsgpg; /* pages to be allocated */
38 int nsgpg_total; /* total pages required */
39 void (*cbfn) (void *cbarg);
40 /* callback function */
41 void *cbarg; /* callback arg */
42 struct list_head sgpg_q; /* queue of alloced sgpgs */
43};
44
45struct bfa_sgpg_s {
46 struct list_head qe; /* queue sg page element */
47 struct bfi_sgpg_s *sgpg; /* va of SG page */
48 union bfi_addr_u sgpg_pa;/* pa of SG page */
49};
50
51/**
52 * Given number of SG elements, BFA_SGPG_NPAGE() returns the number of
53 * SG pages required.
54 */
55#define BFA_SGPG_NPAGE(_nsges) (((_nsges) / BFI_SGPG_DATA_SGES) + 1)
56
57struct bfa_sgpg_mod_s {
58 struct bfa_s *bfa;
59 int num_sgpgs; /* number of SG pages */
60 int free_sgpgs; /* number of free SG pages */
61 struct bfa_sgpg_s *hsgpg_arr; /* BFA SG page array */
62 struct bfi_sgpg_s *sgpg_arr; /* actual SG page array */
63 u64 sgpg_arr_pa; /* SG page array DMA addr */
64 struct list_head sgpg_q; /* queue of free SG pages */
65 struct list_head sgpg_wait_q; /* wait queue for SG pages */
66};
67#define BFA_SGPG_MOD(__bfa) (&(__bfa)->modules.sgpg_mod)
68
69bfa_status_t bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q,
70 int nsgpgs);
71void bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q,
72 int nsgpgs);
73void bfa_sgpg_winit(struct bfa_sgpg_wqe_s *wqe,
74 void (*cbfn) (void *cbarg), void *cbarg);
75void bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe,
76 int nsgpgs);
77void bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe);
78
79#endif /* __BFA_SGPG_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_sm.c b/drivers/scsi/bfa/bfa_sm.c
new file mode 100644
index 000000000000..5420f4f45e58
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_sm.c
@@ -0,0 +1,38 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfasm.c BFA State machine utility functions
20 */
21
22#include <cs/bfa_sm.h>
23
24/**
25 * cs_sm_api
26 */
27
28int
29bfa_sm_to_state(struct bfa_sm_table_s *smt, bfa_sm_t sm)
30{
31 int i = 0;
32
33 while (smt[i].sm && smt[i].sm != sm)
34 i++;
35 return smt[i].state;
36}
37
38
diff --git a/drivers/scsi/bfa/bfa_timer.c b/drivers/scsi/bfa/bfa_timer.c
new file mode 100644
index 000000000000..cb76481f5cb1
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_timer.c
@@ -0,0 +1,90 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa_timer.h>
19#include <cs/bfa_debug.h>
20
21void
22bfa_timer_init(struct bfa_timer_mod_s *mod)
23{
24 INIT_LIST_HEAD(&mod->timer_q);
25}
26
27void
28bfa_timer_beat(struct bfa_timer_mod_s *mod)
29{
30 struct list_head *qh = &mod->timer_q;
31 struct list_head *qe, *qe_next;
32 struct bfa_timer_s *elem;
33 struct list_head timedout_q;
34
35 INIT_LIST_HEAD(&timedout_q);
36
37 qe = bfa_q_next(qh);
38
39 while (qe != qh) {
40 qe_next = bfa_q_next(qe);
41
42 elem = (struct bfa_timer_s *) qe;
43 if (elem->timeout <= BFA_TIMER_FREQ) {
44 elem->timeout = 0;
45 list_del(&elem->qe);
46 list_add_tail(&elem->qe, &timedout_q);
47 } else {
48 elem->timeout -= BFA_TIMER_FREQ;
49 }
50
51 qe = qe_next; /* go to next elem */
52 }
53
54 /*
55 * Pop all the timeout entries
56 */
57 while (!list_empty(&timedout_q)) {
58 bfa_q_deq(&timedout_q, &elem);
59 elem->timercb(elem->arg);
60 }
61}
62
63/**
64 * Should be called with lock protection
65 */
66void
67bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
68 void (*timercb) (void *), void *arg, unsigned int timeout)
69{
70
71 bfa_assert(timercb != NULL);
72 bfa_assert(!bfa_q_is_on_q(&mod->timer_q, timer));
73
74 timer->timeout = timeout;
75 timer->timercb = timercb;
76 timer->arg = arg;
77
78 list_add_tail(&timer->qe, &mod->timer_q);
79}
80
81/**
82 * Should be called with lock protection
83 */
84void
85bfa_timer_stop(struct bfa_timer_s *timer)
86{
87 bfa_assert(!list_empty(&timer->qe));
88
89 list_del(&timer->qe);
90}
diff --git a/drivers/scsi/bfa/bfa_trcmod_priv.h b/drivers/scsi/bfa/bfa_trcmod_priv.h
new file mode 100644
index 000000000000..b3562dce7e9f
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_trcmod_priv.h
@@ -0,0 +1,66 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * hal_trcmod.h BFA trace modules
20 */
21
22#ifndef __BFA_TRCMOD_PRIV_H__
23#define __BFA_TRCMOD_PRIV_H__
24
25#include <cs/bfa_trc.h>
26
27/*
28 * !!! Only append to the enums defined here to avoid any versioning
29 * !!! needed between trace utility and driver version
30 */
31enum {
32 BFA_TRC_HAL_IOC = 1,
33 BFA_TRC_HAL_INTR = 2,
34 BFA_TRC_HAL_FCXP = 3,
35 BFA_TRC_HAL_UF = 4,
36 BFA_TRC_HAL_DIAG = 5,
37 BFA_TRC_HAL_RPORT = 6,
38 BFA_TRC_HAL_FCPIM = 7,
39 BFA_TRC_HAL_IOIM = 8,
40 BFA_TRC_HAL_TSKIM = 9,
41 BFA_TRC_HAL_ITNIM = 10,
42 BFA_TRC_HAL_PPORT = 11,
43 BFA_TRC_HAL_SGPG = 12,
44 BFA_TRC_HAL_FLASH = 13,
45 BFA_TRC_HAL_DEBUG = 14,
46 BFA_TRC_HAL_WWN = 15,
47 BFA_TRC_HAL_FLASH_RAW = 16,
48 BFA_TRC_HAL_SBOOT = 17,
49 BFA_TRC_HAL_SBOOT_IO = 18,
50 BFA_TRC_HAL_SBOOT_INTR = 19,
51 BFA_TRC_HAL_SBTEST = 20,
52 BFA_TRC_HAL_IPFC = 21,
53 BFA_TRC_HAL_IOCFC = 22,
54 BFA_TRC_HAL_FCPTM = 23,
55 BFA_TRC_HAL_IOTM = 24,
56 BFA_TRC_HAL_TSKTM = 25,
57 BFA_TRC_HAL_TIN = 26,
58 BFA_TRC_HAL_LPS = 27,
59 BFA_TRC_HAL_FCDIAG = 28,
60 BFA_TRC_HAL_PBIND = 29,
61 BFA_TRC_HAL_IOCFC_CT = 30,
62 BFA_TRC_HAL_IOCFC_CB = 31,
63 BFA_TRC_HAL_IOCFC_Q = 32,
64};
65
66#endif /* __BFA_TRCMOD_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_tskim.c b/drivers/scsi/bfa/bfa_tskim.c
new file mode 100644
index 000000000000..010d40d1e5d3
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_tskim.c
@@ -0,0 +1,689 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19#include <bfa_cb_ioim_macros.h>
20
21BFA_TRC_FILE(HAL, TSKIM);
22
23/**
24 * task management completion handling
25 */
26#define bfa_tskim_qcomp(__tskim, __cbfn) do { \
27 bfa_cb_queue((__tskim)->bfa, &(__tskim)->hcb_qe, __cbfn, (__tskim)); \
28 bfa_tskim_notify_comp(__tskim); \
29} while (0)
30
31#define bfa_tskim_notify_comp(__tskim) do { \
32 if ((__tskim)->notify) \
33 bfa_itnim_tskdone((__tskim)->itnim); \
34} while (0)
35
36/*
37 * forward declarations
38 */
39static void __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete);
40static void __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete);
41static bfa_boolean_t bfa_tskim_match_scope(struct bfa_tskim_s *tskim,
42 lun_t lun);
43static void bfa_tskim_gather_ios(struct bfa_tskim_s *tskim);
44static void bfa_tskim_cleanp_comp(void *tskim_cbarg);
45static void bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim);
46static bfa_boolean_t bfa_tskim_send(struct bfa_tskim_s *tskim);
47static bfa_boolean_t bfa_tskim_send_abort(struct bfa_tskim_s *tskim);
48static void bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim);
49
50/**
51 * bfa_tskim_sm
52 */
53
54enum bfa_tskim_event {
55 BFA_TSKIM_SM_START = 1, /* TM command start */
56 BFA_TSKIM_SM_DONE = 2, /* TM completion */
57 BFA_TSKIM_SM_QRESUME = 3, /* resume after qfull */
58 BFA_TSKIM_SM_HWFAIL = 5, /* IOC h/w failure event */
59 BFA_TSKIM_SM_HCB = 6, /* BFA callback completion */
60 BFA_TSKIM_SM_IOS_DONE = 7, /* IO and sub TM completions */
61 BFA_TSKIM_SM_CLEANUP = 8, /* TM cleanup on ITN offline */
62 BFA_TSKIM_SM_CLEANUP_DONE = 9, /* TM abort completion */
63};
64
65static void bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim,
66 enum bfa_tskim_event event);
67static void bfa_tskim_sm_active(struct bfa_tskim_s *tskim,
68 enum bfa_tskim_event event);
69static void bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim,
70 enum bfa_tskim_event event);
71static void bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim,
72 enum bfa_tskim_event event);
73static void bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim,
74 enum bfa_tskim_event event);
75static void bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
76 enum bfa_tskim_event event);
77static void bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim,
78 enum bfa_tskim_event event);
79
80/**
81 * Task management command beginning state.
82 */
83static void
84bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
85{
86 bfa_trc(tskim->bfa, event);
87
88 switch (event) {
89 case BFA_TSKIM_SM_START:
90 bfa_sm_set_state(tskim, bfa_tskim_sm_active);
91 bfa_tskim_gather_ios(tskim);
92
93 /**
94 * If device is offline, do not send TM on wire. Just cleanup
95 * any pending IO requests and complete TM request.
96 */
97 if (!bfa_itnim_is_online(tskim->itnim)) {
98 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
99 tskim->tsk_status = BFI_TSKIM_STS_OK;
100 bfa_tskim_cleanup_ios(tskim);
101 return;
102 }
103
104 if (!bfa_tskim_send(tskim)) {
105 bfa_sm_set_state(tskim, bfa_tskim_sm_qfull);
106 bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq,
107 &tskim->reqq_wait);
108 }
109 break;
110
111 default:
112 bfa_assert(0);
113 }
114}
115
116/**
117 * brief
118 * TM command is active, awaiting completion from firmware to
119 * cleanup IO requests in TM scope.
120 */
121static void
122bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
123{
124 bfa_trc(tskim->bfa, event);
125
126 switch (event) {
127 case BFA_TSKIM_SM_DONE:
128 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
129 bfa_tskim_cleanup_ios(tskim);
130 break;
131
132 case BFA_TSKIM_SM_CLEANUP:
133 bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup);
134 if (!bfa_tskim_send_abort(tskim)) {
135 bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup_qfull);
136 bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq,
137 &tskim->reqq_wait);
138 }
139 break;
140
141 case BFA_TSKIM_SM_HWFAIL:
142 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
143 bfa_tskim_iocdisable_ios(tskim);
144 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
145 break;
146
147 default:
148 bfa_assert(0);
149 }
150}
151
152/**
153 * An active TM is being cleaned up since ITN is offline. Awaiting cleanup
154 * completion event from firmware.
155 */
156static void
157bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
158{
159 bfa_trc(tskim->bfa, event);
160
161 switch (event) {
162 case BFA_TSKIM_SM_DONE:
163 /**
164 * Ignore and wait for ABORT completion from firmware.
165 */
166 break;
167
168 case BFA_TSKIM_SM_CLEANUP_DONE:
169 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
170 bfa_tskim_cleanup_ios(tskim);
171 break;
172
173 case BFA_TSKIM_SM_HWFAIL:
174 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
175 bfa_tskim_iocdisable_ios(tskim);
176 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
177 break;
178
179 default:
180 bfa_assert(0);
181 }
182}
183
184static void
185bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
186{
187 bfa_trc(tskim->bfa, event);
188
189 switch (event) {
190 case BFA_TSKIM_SM_IOS_DONE:
191 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
192 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_done);
193 break;
194
195 case BFA_TSKIM_SM_CLEANUP:
196 /**
197 * Ignore, TM command completed on wire.
198 * Notify TM conmpletion on IO cleanup completion.
199 */
200 break;
201
202 case BFA_TSKIM_SM_HWFAIL:
203 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
204 bfa_tskim_iocdisable_ios(tskim);
205 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
206 break;
207
208 default:
209 bfa_assert(0);
210 }
211}
212
213/**
214 * Task management command is waiting for room in request CQ
215 */
216static void
217bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
218{
219 bfa_trc(tskim->bfa, event);
220
221 switch (event) {
222 case BFA_TSKIM_SM_QRESUME:
223 bfa_sm_set_state(tskim, bfa_tskim_sm_active);
224 bfa_tskim_send(tskim);
225 break;
226
227 case BFA_TSKIM_SM_CLEANUP:
228 /**
229 * No need to send TM on wire since ITN is offline.
230 */
231 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
232 bfa_reqq_wcancel(&tskim->reqq_wait);
233 bfa_tskim_cleanup_ios(tskim);
234 break;
235
236 case BFA_TSKIM_SM_HWFAIL:
237 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
238 bfa_reqq_wcancel(&tskim->reqq_wait);
239 bfa_tskim_iocdisable_ios(tskim);
240 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
241 break;
242
243 default:
244 bfa_assert(0);
245 }
246}
247
248/**
249 * Task management command is active, awaiting for room in request CQ
250 * to send clean up request.
251 */
252static void
253bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
254 enum bfa_tskim_event event)
255{
256 bfa_trc(tskim->bfa, event);
257
258 switch (event) {
259 case BFA_TSKIM_SM_DONE:
260 bfa_reqq_wcancel(&tskim->reqq_wait);
261 /**
262 *
263 * Fall through !!!
264 */
265
266 case BFA_TSKIM_SM_QRESUME:
267 bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup);
268 bfa_tskim_send_abort(tskim);
269 break;
270
271 case BFA_TSKIM_SM_HWFAIL:
272 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
273 bfa_reqq_wcancel(&tskim->reqq_wait);
274 bfa_tskim_iocdisable_ios(tskim);
275 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
276 break;
277
278 default:
279 bfa_assert(0);
280 }
281}
282
283/**
284 * BFA callback is pending
285 */
286static void
287bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
288{
289 bfa_trc(tskim->bfa, event);
290
291 switch (event) {
292 case BFA_TSKIM_SM_HCB:
293 bfa_sm_set_state(tskim, bfa_tskim_sm_uninit);
294 bfa_tskim_free(tskim);
295 break;
296
297 case BFA_TSKIM_SM_CLEANUP:
298 bfa_tskim_notify_comp(tskim);
299 break;
300
301 case BFA_TSKIM_SM_HWFAIL:
302 break;
303
304 default:
305 bfa_assert(0);
306 }
307}
308
309
310
311/**
312 * bfa_tskim_private
313 */
314
315static void
316__bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete)
317{
318 struct bfa_tskim_s *tskim = cbarg;
319
320 if (!complete) {
321 bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB);
322 return;
323 }
324
325 bfa_stats(tskim->itnim, tm_success);
326 bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk, tskim->tsk_status);
327}
328
329static void
330__bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete)
331{
332 struct bfa_tskim_s *tskim = cbarg;
333
334 if (!complete) {
335 bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB);
336 return;
337 }
338
339 bfa_stats(tskim->itnim, tm_failures);
340 bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk,
341 BFI_TSKIM_STS_FAILED);
342}
343
344static bfa_boolean_t
345bfa_tskim_match_scope(struct bfa_tskim_s *tskim, lun_t lun)
346{
347 switch (tskim->tm_cmnd) {
348 case FCP_TM_TARGET_RESET:
349 return BFA_TRUE;
350
351 case FCP_TM_ABORT_TASK_SET:
352 case FCP_TM_CLEAR_TASK_SET:
353 case FCP_TM_LUN_RESET:
354 case FCP_TM_CLEAR_ACA:
355 return (tskim->lun == lun);
356
357 default:
358 bfa_assert(0);
359 }
360
361 return BFA_FALSE;
362}
363
364/**
365 * Gather affected IO requests and task management commands.
366 */
367static void
368bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
369{
370 struct bfa_itnim_s *itnim = tskim->itnim;
371 struct bfa_ioim_s *ioim;
372 struct list_head *qe, *qen;
373
374 INIT_LIST_HEAD(&tskim->io_q);
375
376 /**
377 * Gather any active IO requests first.
378 */
379 list_for_each_safe(qe, qen, &itnim->io_q) {
380 ioim = (struct bfa_ioim_s *) qe;
381 if (bfa_tskim_match_scope
382 (tskim, bfa_cb_ioim_get_lun(ioim->dio))) {
383 list_del(&ioim->qe);
384 list_add_tail(&ioim->qe, &tskim->io_q);
385 }
386 }
387
388 /**
389 * Failback any pending IO requests immediately.
390 */
391 list_for_each_safe(qe, qen, &itnim->pending_q) {
392 ioim = (struct bfa_ioim_s *) qe;
393 if (bfa_tskim_match_scope
394 (tskim, bfa_cb_ioim_get_lun(ioim->dio))) {
395 list_del(&ioim->qe);
396 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
397 bfa_ioim_tov(ioim);
398 }
399 }
400}
401
402/**
403 * IO cleanup completion
404 */
405static void
406bfa_tskim_cleanp_comp(void *tskim_cbarg)
407{
408 struct bfa_tskim_s *tskim = tskim_cbarg;
409
410 bfa_stats(tskim->itnim, tm_io_comps);
411 bfa_sm_send_event(tskim, BFA_TSKIM_SM_IOS_DONE);
412}
413
414/**
415 * Gather affected IO requests and task management commands.
416 */
417static void
418bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim)
419{
420 struct bfa_ioim_s *ioim;
421 struct list_head *qe, *qen;
422
423 bfa_wc_init(&tskim->wc, bfa_tskim_cleanp_comp, tskim);
424
425 list_for_each_safe(qe, qen, &tskim->io_q) {
426 ioim = (struct bfa_ioim_s *) qe;
427 bfa_wc_up(&tskim->wc);
428 bfa_ioim_cleanup_tm(ioim, tskim);
429 }
430
431 bfa_wc_wait(&tskim->wc);
432}
433
434/**
435 * Send task management request to firmware.
436 */
437static bfa_boolean_t
438bfa_tskim_send(struct bfa_tskim_s *tskim)
439{
440 struct bfa_itnim_s *itnim = tskim->itnim;
441 struct bfi_tskim_req_s *m;
442
443 /**
444 * check for room in queue to send request now
445 */
446 m = bfa_reqq_next(tskim->bfa, itnim->reqq);
447 if (!m)
448 return BFA_FALSE;
449
450 /**
451 * build i/o request message next
452 */
453 bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_TM_REQ,
454 bfa_lpuid(tskim->bfa));
455
456 m->tsk_tag = bfa_os_htons(tskim->tsk_tag);
457 m->itn_fhdl = tskim->itnim->rport->fw_handle;
458 m->t_secs = tskim->tsecs;
459 m->lun = tskim->lun;
460 m->tm_flags = tskim->tm_cmnd;
461
462 /**
463 * queue I/O message to firmware
464 */
465 bfa_reqq_produce(tskim->bfa, itnim->reqq);
466 return BFA_TRUE;
467}
468
469/**
470 * Send abort request to cleanup an active TM to firmware.
471 */
472static bfa_boolean_t
473bfa_tskim_send_abort(struct bfa_tskim_s *tskim)
474{
475 struct bfa_itnim_s *itnim = tskim->itnim;
476 struct bfi_tskim_abortreq_s *m;
477
478 /**
479 * check for room in queue to send request now
480 */
481 m = bfa_reqq_next(tskim->bfa, itnim->reqq);
482 if (!m)
483 return BFA_FALSE;
484
485 /**
486 * build i/o request message next
487 */
488 bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_ABORT_REQ,
489 bfa_lpuid(tskim->bfa));
490
491 m->tsk_tag = bfa_os_htons(tskim->tsk_tag);
492
493 /**
494 * queue I/O message to firmware
495 */
496 bfa_reqq_produce(tskim->bfa, itnim->reqq);
497 return BFA_TRUE;
498}
499
500/**
501 * Call to resume task management cmnd waiting for room in request queue.
502 */
503static void
504bfa_tskim_qresume(void *cbarg)
505{
506 struct bfa_tskim_s *tskim = cbarg;
507
508 bfa_fcpim_stats(tskim->fcpim, qresumes);
509 bfa_stats(tskim->itnim, tm_qresumes);
510 bfa_sm_send_event(tskim, BFA_TSKIM_SM_QRESUME);
511}
512
513/**
514 * Cleanup IOs associated with a task mangement command on IOC failures.
515 */
516static void
517bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim)
518{
519 struct bfa_ioim_s *ioim;
520 struct list_head *qe, *qen;
521
522 list_for_each_safe(qe, qen, &tskim->io_q) {
523 ioim = (struct bfa_ioim_s *) qe;
524 bfa_ioim_iocdisable(ioim);
525 }
526}
527
528
529
530/**
531 * bfa_tskim_friend
532 */
533
534/**
535 * Notification on completions from related ioim.
536 */
537void
538bfa_tskim_iodone(struct bfa_tskim_s *tskim)
539{
540 bfa_wc_down(&tskim->wc);
541}
542
543/**
544 * Handle IOC h/w failure notification from itnim.
545 */
546void
547bfa_tskim_iocdisable(struct bfa_tskim_s *tskim)
548{
549 tskim->notify = BFA_FALSE;
550 bfa_stats(tskim->itnim, tm_iocdowns);
551 bfa_sm_send_event(tskim, BFA_TSKIM_SM_HWFAIL);
552}
553
554/**
555 * Cleanup TM command and associated IOs as part of ITNIM offline.
556 */
557void
558bfa_tskim_cleanup(struct bfa_tskim_s *tskim)
559{
560 tskim->notify = BFA_TRUE;
561 bfa_stats(tskim->itnim, tm_cleanups);
562 bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP);
563}
564
565/**
566 * Memory allocation and initialization.
567 */
568void
569bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
570{
571 struct bfa_tskim_s *tskim;
572 u16 i;
573
574 INIT_LIST_HEAD(&fcpim->tskim_free_q);
575
576 tskim = (struct bfa_tskim_s *) bfa_meminfo_kva(minfo);
577 fcpim->tskim_arr = tskim;
578
579 for (i = 0; i < fcpim->num_tskim_reqs; i++, tskim++) {
580 /*
581 * initialize TSKIM
582 */
583 bfa_os_memset(tskim, 0, sizeof(struct bfa_tskim_s));
584 tskim->tsk_tag = i;
585 tskim->bfa = fcpim->bfa;
586 tskim->fcpim = fcpim;
587 tskim->notify = BFA_FALSE;
588 bfa_reqq_winit(&tskim->reqq_wait, bfa_tskim_qresume,
589 tskim);
590 bfa_sm_set_state(tskim, bfa_tskim_sm_uninit);
591
592 list_add_tail(&tskim->qe, &fcpim->tskim_free_q);
593 }
594
595 bfa_meminfo_kva(minfo) = (u8 *) tskim;
596}
597
598void
599bfa_tskim_detach(struct bfa_fcpim_mod_s *fcpim)
600{
601 /**
602 * @todo
603 */
604}
605
606void
607bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
608{
609 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
610 struct bfi_tskim_rsp_s *rsp = (struct bfi_tskim_rsp_s *) m;
611 struct bfa_tskim_s *tskim;
612 u16 tsk_tag = bfa_os_ntohs(rsp->tsk_tag);
613
614 tskim = BFA_TSKIM_FROM_TAG(fcpim, tsk_tag);
615 bfa_assert(tskim->tsk_tag == tsk_tag);
616
617 tskim->tsk_status = rsp->tsk_status;
618
619 /**
620 * Firmware sends BFI_TSKIM_STS_ABORTED status for abort
621 * requests. All other statuses are for normal completions.
622 */
623 if (rsp->tsk_status == BFI_TSKIM_STS_ABORTED) {
624 bfa_stats(tskim->itnim, tm_cleanup_comps);
625 bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP_DONE);
626 } else {
627 bfa_stats(tskim->itnim, tm_fw_rsps);
628 bfa_sm_send_event(tskim, BFA_TSKIM_SM_DONE);
629 }
630}
631
632
633
634/**
635 * bfa_tskim_api
636 */
637
638
639struct bfa_tskim_s *
640bfa_tskim_alloc(struct bfa_s *bfa, struct bfad_tskim_s *dtsk)
641{
642 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
643 struct bfa_tskim_s *tskim;
644
645 bfa_q_deq(&fcpim->tskim_free_q, &tskim);
646
647 if (!tskim)
648 bfa_fcpim_stats(fcpim, no_tskims);
649 else
650 tskim->dtsk = dtsk;
651
652 return tskim;
653}
654
655void
656bfa_tskim_free(struct bfa_tskim_s *tskim)
657{
658 bfa_assert(bfa_q_is_on_q_func(&tskim->itnim->tsk_q, &tskim->qe));
659 list_del(&tskim->qe);
660 list_add_tail(&tskim->qe, &tskim->fcpim->tskim_free_q);
661}
662
663/**
664 * Start a task management command.
665 *
666 * @param[in] tskim BFA task management command instance
667 * @param[in] itnim i-t nexus for the task management command
668 * @param[in] lun lun, if applicable
669 * @param[in] tm_cmnd Task management command code.
670 * @param[in] t_secs Timeout in seconds
671 *
672 * @return None.
673 */
674void
675bfa_tskim_start(struct bfa_tskim_s *tskim, struct bfa_itnim_s *itnim, lun_t lun,
676 enum fcp_tm_cmnd tm_cmnd, u8 tsecs)
677{
678 tskim->itnim = itnim;
679 tskim->lun = lun;
680 tskim->tm_cmnd = tm_cmnd;
681 tskim->tsecs = tsecs;
682 tskim->notify = BFA_FALSE;
683 bfa_stats(itnim, tm_cmnds);
684
685 list_add_tail(&tskim->qe, &itnim->tsk_q);
686 bfa_sm_send_event(tskim, BFA_TSKIM_SM_START);
687}
688
689
diff --git a/drivers/scsi/bfa/bfa_uf.c b/drivers/scsi/bfa/bfa_uf.c
new file mode 100644
index 000000000000..ff5f9deb1b22
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_uf.c
@@ -0,0 +1,345 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_uf.c BFA unsolicited frame receive implementation
20 */
21
22#include <bfa.h>
23#include <bfa_svc.h>
24#include <bfi/bfi_uf.h>
25#include <cs/bfa_debug.h>
26
27BFA_TRC_FILE(HAL, UF);
28BFA_MODULE(uf);
29
30/*
31 *****************************************************************************
32 * Internal functions
33 *****************************************************************************
34 */
35static void
36__bfa_cb_uf_recv(void *cbarg, bfa_boolean_t complete)
37{
38 struct bfa_uf_s *uf = cbarg;
39 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(uf->bfa);
40
41 if (complete)
42 ufm->ufrecv(ufm->cbarg, uf);
43}
44
45static void
46claim_uf_pbs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
47{
48 u32 uf_pb_tot_sz;
49
50 ufm->uf_pbs_kva = (struct bfa_uf_buf_s *) bfa_meminfo_dma_virt(mi);
51 ufm->uf_pbs_pa = bfa_meminfo_dma_phys(mi);
52 uf_pb_tot_sz = BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * ufm->num_ufs),
53 BFA_DMA_ALIGN_SZ);
54
55 bfa_meminfo_dma_virt(mi) += uf_pb_tot_sz;
56 bfa_meminfo_dma_phys(mi) += uf_pb_tot_sz;
57
58 bfa_os_memset((void *)ufm->uf_pbs_kva, 0, uf_pb_tot_sz);
59}
60
61static void
62claim_uf_post_msgs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
63{
64 struct bfi_uf_buf_post_s *uf_bp_msg;
65 struct bfi_sge_s *sge;
66 union bfi_addr_u sga_zero = { {0} };
67 u16 i;
68 u16 buf_len;
69
70 ufm->uf_buf_posts = (struct bfi_uf_buf_post_s *) bfa_meminfo_kva(mi);
71 uf_bp_msg = ufm->uf_buf_posts;
72
73 for (i = 0, uf_bp_msg = ufm->uf_buf_posts; i < ufm->num_ufs;
74 i++, uf_bp_msg++) {
75 bfa_os_memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s));
76
77 uf_bp_msg->buf_tag = i;
78 buf_len = sizeof(struct bfa_uf_buf_s);
79 uf_bp_msg->buf_len = bfa_os_htons(buf_len);
80 bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST,
81 bfa_lpuid(ufm->bfa));
82
83 sge = uf_bp_msg->sge;
84 sge[0].sg_len = buf_len;
85 sge[0].flags = BFI_SGE_DATA_LAST;
86 bfa_dma_addr_set(sge[0].sga, ufm_pbs_pa(ufm, i));
87 bfa_sge_to_be(sge);
88
89 sge[1].sg_len = buf_len;
90 sge[1].flags = BFI_SGE_PGDLEN;
91 sge[1].sga = sga_zero;
92 bfa_sge_to_be(&sge[1]);
93 }
94
95 /**
96 * advance pointer beyond consumed memory
97 */
98 bfa_meminfo_kva(mi) = (u8 *) uf_bp_msg;
99}
100
101static void
102claim_ufs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
103{
104 u16 i;
105 struct bfa_uf_s *uf;
106
107 /*
108 * Claim block of memory for UF list
109 */
110 ufm->uf_list = (struct bfa_uf_s *) bfa_meminfo_kva(mi);
111
112 /*
113 * Initialize UFs and queue it in UF free queue
114 */
115 for (i = 0, uf = ufm->uf_list; i < ufm->num_ufs; i++, uf++) {
116 bfa_os_memset(uf, 0, sizeof(struct bfa_uf_s));
117 uf->bfa = ufm->bfa;
118 uf->uf_tag = i;
119 uf->pb_len = sizeof(struct bfa_uf_buf_s);
120 uf->buf_kva = (void *)&ufm->uf_pbs_kva[i];
121 uf->buf_pa = ufm_pbs_pa(ufm, i);
122 list_add_tail(&uf->qe, &ufm->uf_free_q);
123 }
124
125 /**
126 * advance memory pointer
127 */
128 bfa_meminfo_kva(mi) = (u8 *) uf;
129}
130
131static void
132uf_mem_claim(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
133{
134 claim_uf_pbs(ufm, mi);
135 claim_ufs(ufm, mi);
136 claim_uf_post_msgs(ufm, mi);
137}
138
139static void
140bfa_uf_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len)
141{
142 u32 num_ufs = cfg->fwcfg.num_uf_bufs;
143
144 /*
145 * dma-able memory for UF posted bufs
146 */
147 *dm_len += BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * num_ufs),
148 BFA_DMA_ALIGN_SZ);
149
150 /*
151 * kernel Virtual memory for UFs and UF buf post msg copies
152 */
153 *ndm_len += sizeof(struct bfa_uf_s) * num_ufs;
154 *ndm_len += sizeof(struct bfi_uf_buf_post_s) * num_ufs;
155}
156
157static void
158bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
159 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
160{
161 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
162
163 bfa_os_memset(ufm, 0, sizeof(struct bfa_uf_mod_s));
164 ufm->bfa = bfa;
165 ufm->num_ufs = cfg->fwcfg.num_uf_bufs;
166 INIT_LIST_HEAD(&ufm->uf_free_q);
167 INIT_LIST_HEAD(&ufm->uf_posted_q);
168
169 uf_mem_claim(ufm, meminfo);
170}
171
172static void
173bfa_uf_initdone(struct bfa_s *bfa)
174{
175}
176
177static void
178bfa_uf_detach(struct bfa_s *bfa)
179{
180}
181
182static struct bfa_uf_s *
183bfa_uf_get(struct bfa_uf_mod_s *uf_mod)
184{
185 struct bfa_uf_s *uf;
186
187 bfa_q_deq(&uf_mod->uf_free_q, &uf);
188 return (uf);
189}
190
191static void
192bfa_uf_put(struct bfa_uf_mod_s *uf_mod, struct bfa_uf_s *uf)
193{
194 list_add_tail(&uf->qe, &uf_mod->uf_free_q);
195}
196
197static bfa_status_t
198bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf)
199{
200 struct bfi_uf_buf_post_s *uf_post_msg;
201
202 uf_post_msg = bfa_reqq_next(ufm->bfa, BFA_REQQ_FCXP);
203 if (!uf_post_msg)
204 return BFA_STATUS_FAILED;
205
206 bfa_os_memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag],
207 sizeof(struct bfi_uf_buf_post_s));
208 bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP);
209
210 bfa_trc(ufm->bfa, uf->uf_tag);
211
212 list_add_tail(&uf->qe, &ufm->uf_posted_q);
213 return BFA_STATUS_OK;
214}
215
216static void
217bfa_uf_post_all(struct bfa_uf_mod_s *uf_mod)
218{
219 struct bfa_uf_s *uf;
220
221 while ((uf = bfa_uf_get(uf_mod)) != NULL) {
222 if (bfa_uf_post(uf_mod, uf) != BFA_STATUS_OK)
223 break;
224 }
225}
226
227static void
228uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m)
229{
230 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
231 u16 uf_tag = m->buf_tag;
232 struct bfa_uf_buf_s *uf_buf = &ufm->uf_pbs_kva[uf_tag];
233 struct bfa_uf_s *uf = &ufm->uf_list[uf_tag];
234 u8 *buf = &uf_buf->d[0];
235 struct fchs_s *fchs;
236
237 m->frm_len = bfa_os_ntohs(m->frm_len);
238 m->xfr_len = bfa_os_ntohs(m->xfr_len);
239
240 fchs = (struct fchs_s *) uf_buf;
241
242 list_del(&uf->qe); /* dequeue from posted queue */
243
244 uf->data_ptr = buf;
245 uf->data_len = m->xfr_len;
246
247 bfa_assert(uf->data_len >= sizeof(struct fchs_s));
248
249 if (uf->data_len == sizeof(struct fchs_s)) {
250 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_UF, BFA_PL_EID_RX,
251 uf->data_len, (struct fchs_s *) buf);
252 } else {
253 u32 pld_w0 = *((u32 *) (buf + sizeof(struct fchs_s)));
254 bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_UF,
255 BFA_PL_EID_RX, uf->data_len,
256 (struct fchs_s *) buf, pld_w0);
257 }
258
259 bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf);
260}
261
262static void
263bfa_uf_stop(struct bfa_s *bfa)
264{
265}
266
267static void
268bfa_uf_iocdisable(struct bfa_s *bfa)
269{
270 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
271 struct bfa_uf_s *uf;
272 struct list_head *qe, *qen;
273
274 list_for_each_safe(qe, qen, &ufm->uf_posted_q) {
275 uf = (struct bfa_uf_s *) qe;
276 list_del(&uf->qe);
277 bfa_uf_put(ufm, uf);
278 }
279}
280
281static void
282bfa_uf_start(struct bfa_s *bfa)
283{
284 bfa_uf_post_all(BFA_UF_MOD(bfa));
285}
286
287
288
289/**
290 * bfa_uf_api
291 */
292
293/**
294 * Register handler for all unsolicted recieve frames.
295 *
296 * @param[in] bfa BFA instance
297 * @param[in] ufrecv receive handler function
298 * @param[in] cbarg receive handler arg
299 */
300void
301bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, void *cbarg)
302{
303 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
304
305 ufm->ufrecv = ufrecv;
306 ufm->cbarg = cbarg;
307}
308
309/**
310 * Free an unsolicited frame back to BFA.
311 *
312 * @param[in] uf unsolicited frame to be freed
313 *
314 * @return None
315 */
316void
317bfa_uf_free(struct bfa_uf_s *uf)
318{
319 bfa_uf_put(BFA_UF_MOD(uf->bfa), uf);
320 bfa_uf_post_all(BFA_UF_MOD(uf->bfa));
321}
322
323
324
325/**
326 * uf_pub BFA uf module public functions
327 */
328
329void
330bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
331{
332 bfa_trc(bfa, msg->mhdr.msg_id);
333
334 switch (msg->mhdr.msg_id) {
335 case BFI_UF_I2H_FRM_RCVD:
336 uf_recv(bfa, (struct bfi_uf_frm_rcvd_s *) msg);
337 break;
338
339 default:
340 bfa_trc(bfa, msg->mhdr.msg_id);
341 bfa_assert(0);
342 }
343}
344
345
diff --git a/drivers/scsi/bfa/bfa_uf_priv.h b/drivers/scsi/bfa/bfa_uf_priv.h
new file mode 100644
index 000000000000..bcb490f834f3
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_uf_priv.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_UF_PRIV_H__
18#define __BFA_UF_PRIV_H__
19
20#include <cs/bfa_sm.h>
21#include <bfa_svc.h>
22#include <bfi/bfi_uf.h>
23
24#define BFA_UF_MIN (4)
25
26struct bfa_uf_mod_s {
27 struct bfa_s *bfa; /* back pointer to BFA */
28 struct bfa_uf_s *uf_list; /* array of UFs */
29 u16 num_ufs; /* num unsolicited rx frames */
30 struct list_head uf_free_q; /* free UFs */
31 struct list_head uf_posted_q; /* UFs posted to IOC */
32 struct bfa_uf_buf_s *uf_pbs_kva; /* list UF bufs request pld */
33 u64 uf_pbs_pa; /* phy addr for UF bufs */
34 struct bfi_uf_buf_post_s *uf_buf_posts;
35 /* pre-built UF post msgs */
36 bfa_cb_uf_recv_t ufrecv; /* uf recv handler function */
37 void *cbarg; /* uf receive handler arg */
38};
39
40#define BFA_UF_MOD(__bfa) (&(__bfa)->modules.uf_mod)
41
42#define ufm_pbs_pa(_ufmod, _uftag) \
43 ((_ufmod)->uf_pbs_pa + sizeof(struct bfa_uf_buf_s) * (_uftag))
44
45void bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
46
47#endif /* __BFA_UF_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
new file mode 100644
index 000000000000..6f2be5abf561
--- /dev/null
+++ b/drivers/scsi/bfa/bfad.c
@@ -0,0 +1,1182 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfad.c Linux driver PCI interface module.
20 */
21
22#include <linux/module.h>
23#include "bfad_drv.h"
24#include "bfad_im.h"
25#include "bfad_tm.h"
26#include "bfad_ipfc.h"
27#include "bfad_trcmod.h"
28#include <fcb/bfa_fcb_vf.h>
29#include <fcb/bfa_fcb_rport.h>
30#include <fcb/bfa_fcb_port.h>
31#include <fcb/bfa_fcb.h>
32
33BFA_TRC_FILE(LDRV, BFAD);
34static DEFINE_MUTEX(bfad_mutex);
35LIST_HEAD(bfad_list);
36static int bfad_inst;
37int bfad_supported_fc4s;
38
39static char *host_name;
40static char *os_name;
41static char *os_patch;
42static int num_rports;
43static int num_ios;
44static int num_tms;
45static int num_fcxps;
46static int num_ufbufs;
47static int reqq_size;
48static int rspq_size;
49static int num_sgpgs;
50static int rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT;
51static int bfa_io_max_sge = BFAD_IO_MAX_SGE;
52static int log_level = BFA_LOG_WARNING;
53static int ioc_auto_recover = BFA_TRUE;
54static int ipfc_enable = BFA_FALSE;
55static int ipfc_mtu = -1;
56int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
57int bfa_linkup_delay = -1;
58
59module_param(os_name, charp, S_IRUGO | S_IWUSR);
60module_param(os_patch, charp, S_IRUGO | S_IWUSR);
61module_param(host_name, charp, S_IRUGO | S_IWUSR);
62module_param(num_rports, int, S_IRUGO | S_IWUSR);
63module_param(num_ios, int, S_IRUGO | S_IWUSR);
64module_param(num_tms, int, S_IRUGO | S_IWUSR);
65module_param(num_fcxps, int, S_IRUGO | S_IWUSR);
66module_param(num_ufbufs, int, S_IRUGO | S_IWUSR);
67module_param(reqq_size, int, S_IRUGO | S_IWUSR);
68module_param(rspq_size, int, S_IRUGO | S_IWUSR);
69module_param(num_sgpgs, int, S_IRUGO | S_IWUSR);
70module_param(rport_del_timeout, int, S_IRUGO | S_IWUSR);
71module_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR);
72module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR);
73module_param(log_level, int, S_IRUGO | S_IWUSR);
74module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
75module_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
76module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR);
77module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
78
79/*
80 * Stores the module parm num_sgpgs value;
81 * used to reset for bfad next instance.
82 */
83static int num_sgpgs_parm;
84
85static bfa_status_t
86bfad_fc4_probe(struct bfad_s *bfad)
87{
88 int rc;
89
90 rc = bfad_im_probe(bfad);
91 if (rc != BFA_STATUS_OK)
92 goto ext;
93
94 bfad_tm_probe(bfad);
95
96 if (ipfc_enable)
97 bfad_ipfc_probe(bfad);
98ext:
99 return rc;
100}
101
102static void
103bfad_fc4_probe_undo(struct bfad_s *bfad)
104{
105 bfad_im_probe_undo(bfad);
106 bfad_tm_probe_undo(bfad);
107 if (ipfc_enable)
108 bfad_ipfc_probe_undo(bfad);
109}
110
111static void
112bfad_fc4_probe_post(struct bfad_s *bfad)
113{
114 if (bfad->im)
115 bfad_im_probe_post(bfad->im);
116
117 bfad_tm_probe_post(bfad);
118 if (ipfc_enable)
119 bfad_ipfc_probe_post(bfad);
120}
121
122static bfa_status_t
123bfad_fc4_port_new(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
124{
125 int rc = BFA_STATUS_FAILED;
126
127 if (roles & BFA_PORT_ROLE_FCP_IM)
128 rc = bfad_im_port_new(bfad, port);
129 if (rc != BFA_STATUS_OK)
130 goto ext;
131
132 if (roles & BFA_PORT_ROLE_FCP_TM)
133 rc = bfad_tm_port_new(bfad, port);
134 if (rc != BFA_STATUS_OK)
135 goto ext;
136
137 if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
138 rc = bfad_ipfc_port_new(bfad, port, port->pvb_type);
139ext:
140 return rc;
141}
142
143static void
144bfad_fc4_port_delete(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
145{
146 if (roles & BFA_PORT_ROLE_FCP_IM)
147 bfad_im_port_delete(bfad, port);
148
149 if (roles & BFA_PORT_ROLE_FCP_TM)
150 bfad_tm_port_delete(bfad, port);
151
152 if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
153 bfad_ipfc_port_delete(bfad, port);
154}
155
156/**
157 * BFA callbacks
158 */
159void
160bfad_hcb_comp(void *arg, bfa_status_t status)
161{
162 struct bfad_hal_comp *fcomp = (struct bfad_hal_comp *)arg;
163
164 fcomp->status = status;
165 complete(&fcomp->comp);
166}
167
168/**
169 * bfa_init callback
170 */
171void
172bfa_cb_init(void *drv, bfa_status_t init_status)
173{
174 struct bfad_s *bfad = drv;
175
176 if (init_status == BFA_STATUS_OK)
177 bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
178
179 complete(&bfad->comp);
180}
181
182
183
184/**
185 * BFA_FCS callbacks
186 */
187static struct bfad_port_s *
188bfad_get_drv_port(struct bfad_s *bfad, struct bfad_vf_s *vf_drv,
189 struct bfad_vport_s *vp_drv)
190{
191 return ((vp_drv) ? (&(vp_drv)->drv_port)
192 : ((vf_drv) ? (&(vf_drv)->base_port) : (&(bfad)->pport)));
193}
194
195struct bfad_port_s *
196bfa_fcb_port_new(struct bfad_s *bfad, struct bfa_fcs_port_s *port,
197 enum bfa_port_role roles, struct bfad_vf_s *vf_drv,
198 struct bfad_vport_s *vp_drv)
199{
200 bfa_status_t rc;
201 struct bfad_port_s *port_drv;
202
203 if (!vp_drv && !vf_drv) {
204 port_drv = &bfad->pport;
205 port_drv->pvb_type = BFAD_PORT_PHYS_BASE;
206 } else if (!vp_drv && vf_drv) {
207 port_drv = &vf_drv->base_port;
208 port_drv->pvb_type = BFAD_PORT_VF_BASE;
209 } else if (vp_drv && !vf_drv) {
210 port_drv = &vp_drv->drv_port;
211 port_drv->pvb_type = BFAD_PORT_PHYS_VPORT;
212 } else {
213 port_drv = &vp_drv->drv_port;
214 port_drv->pvb_type = BFAD_PORT_VF_VPORT;
215 }
216
217 port_drv->fcs_port = port;
218 port_drv->roles = roles;
219 rc = bfad_fc4_port_new(bfad, port_drv, roles);
220 if (rc != BFA_STATUS_OK) {
221 bfad_fc4_port_delete(bfad, port_drv, roles);
222 port_drv = NULL;
223 }
224
225 return port_drv;
226}
227
228void
229bfa_fcb_port_delete(struct bfad_s *bfad, enum bfa_port_role roles,
230 struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
231{
232 struct bfad_port_s *port_drv;
233
234 /*
235 * this will be only called from rmmod context
236 */
237 if (vp_drv && !vp_drv->comp_del) {
238 port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
239 bfa_trc(bfad, roles);
240 bfad_fc4_port_delete(bfad, port_drv, roles);
241 }
242}
243
244void
245bfa_fcb_port_online(struct bfad_s *bfad, enum bfa_port_role roles,
246 struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
247{
248 struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
249
250 if (roles & BFA_PORT_ROLE_FCP_IM)
251 bfad_im_port_online(bfad, port_drv);
252
253 if (roles & BFA_PORT_ROLE_FCP_TM)
254 bfad_tm_port_online(bfad, port_drv);
255
256 if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
257 bfad_ipfc_port_online(bfad, port_drv);
258
259 bfad->bfad_flags |= BFAD_PORT_ONLINE;
260}
261
262void
263bfa_fcb_port_offline(struct bfad_s *bfad, enum bfa_port_role roles,
264 struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
265{
266 struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
267
268 if (roles & BFA_PORT_ROLE_FCP_IM)
269 bfad_im_port_offline(bfad, port_drv);
270
271 if (roles & BFA_PORT_ROLE_FCP_TM)
272 bfad_tm_port_offline(bfad, port_drv);
273
274 if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
275 bfad_ipfc_port_offline(bfad, port_drv);
276}
277
278void
279bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv)
280{
281 if (vport_drv->comp_del) {
282 complete(vport_drv->comp_del);
283 return;
284 }
285
286 kfree(vport_drv);
287}
288
289/**
290 * FCS RPORT alloc callback, after successful PLOGI by FCS
291 */
292bfa_status_t
293bfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport,
294 struct bfad_rport_s **rport_drv)
295{
296 bfa_status_t rc = BFA_STATUS_OK;
297
298 *rport_drv = kzalloc(sizeof(struct bfad_rport_s), GFP_ATOMIC);
299 if (*rport_drv == NULL) {
300 rc = BFA_STATUS_ENOMEM;
301 goto ext;
302 }
303
304 *rport = &(*rport_drv)->fcs_rport;
305
306ext:
307 return rc;
308}
309
310
311
312void
313bfad_hal_mem_release(struct bfad_s *bfad)
314{
315 int i;
316 struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
317 struct bfa_mem_elem_s *meminfo_elem;
318
319 for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
320 meminfo_elem = &hal_meminfo->meminfo[i];
321 if (meminfo_elem->kva != NULL) {
322 switch (meminfo_elem->mem_type) {
323 case BFA_MEM_TYPE_KVA:
324 vfree(meminfo_elem->kva);
325 break;
326 case BFA_MEM_TYPE_DMA:
327 dma_free_coherent(&bfad->pcidev->dev,
328 meminfo_elem->mem_len,
329 meminfo_elem->kva,
330 (dma_addr_t) meminfo_elem->dma);
331 break;
332 default:
333 bfa_assert(0);
334 break;
335 }
336 }
337 }
338
339 memset(hal_meminfo, 0, sizeof(struct bfa_meminfo_s));
340}
341
342void
343bfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg)
344{
345 if (num_rports > 0)
346 bfa_cfg->fwcfg.num_rports = num_rports;
347 if (num_ios > 0)
348 bfa_cfg->fwcfg.num_ioim_reqs = num_ios;
349 if (num_tms > 0)
350 bfa_cfg->fwcfg.num_tskim_reqs = num_tms;
351 if (num_fcxps > 0)
352 bfa_cfg->fwcfg.num_fcxp_reqs = num_fcxps;
353 if (num_ufbufs > 0)
354 bfa_cfg->fwcfg.num_uf_bufs = num_ufbufs;
355 if (reqq_size > 0)
356 bfa_cfg->drvcfg.num_reqq_elems = reqq_size;
357 if (rspq_size > 0)
358 bfa_cfg->drvcfg.num_rspq_elems = rspq_size;
359 if (num_sgpgs > 0)
360 bfa_cfg->drvcfg.num_sgpgs = num_sgpgs;
361
362 /*
363 * populate the hal values back to the driver for sysfs use.
364 * otherwise, the default values will be shown as 0 in sysfs
365 */
366 num_rports = bfa_cfg->fwcfg.num_rports;
367 num_ios = bfa_cfg->fwcfg.num_ioim_reqs;
368 num_tms = bfa_cfg->fwcfg.num_tskim_reqs;
369 num_fcxps = bfa_cfg->fwcfg.num_fcxp_reqs;
370 num_ufbufs = bfa_cfg->fwcfg.num_uf_bufs;
371 reqq_size = bfa_cfg->drvcfg.num_reqq_elems;
372 rspq_size = bfa_cfg->drvcfg.num_rspq_elems;
373 num_sgpgs = bfa_cfg->drvcfg.num_sgpgs;
374}
375
376bfa_status_t
377bfad_hal_mem_alloc(struct bfad_s *bfad)
378{
379 struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
380 struct bfa_mem_elem_s *meminfo_elem;
381 bfa_status_t rc = BFA_STATUS_OK;
382 dma_addr_t phys_addr;
383 int retry_count = 0;
384 int reset_value = 1;
385 int min_num_sgpgs = 512;
386 void *kva;
387 int i;
388
389 bfa_cfg_get_default(&bfad->ioc_cfg);
390
391retry:
392 bfad_update_hal_cfg(&bfad->ioc_cfg);
393 bfad->cfg_data.ioc_queue_depth = bfad->ioc_cfg.fwcfg.num_ioim_reqs;
394 bfa_cfg_get_meminfo(&bfad->ioc_cfg, hal_meminfo);
395
396 for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
397 meminfo_elem = &hal_meminfo->meminfo[i];
398 switch (meminfo_elem->mem_type) {
399 case BFA_MEM_TYPE_KVA:
400 kva = vmalloc(meminfo_elem->mem_len);
401 if (kva == NULL) {
402 bfad_hal_mem_release(bfad);
403 rc = BFA_STATUS_ENOMEM;
404 goto ext;
405 }
406 memset(kva, 0, meminfo_elem->mem_len);
407 meminfo_elem->kva = kva;
408 break;
409 case BFA_MEM_TYPE_DMA:
410 kva = dma_alloc_coherent(&bfad->pcidev->dev,
411 meminfo_elem->mem_len,
412 &phys_addr, GFP_KERNEL);
413 if (kva == NULL) {
414 bfad_hal_mem_release(bfad);
415 /*
416 * If we cannot allocate with default
417 * num_sgpages try with half the value.
418 */
419 if (num_sgpgs > min_num_sgpgs) {
420 printk(KERN_INFO "bfad[%d]: memory"
421 " allocation failed with"
422 " num_sgpgs: %d\n",
423 bfad->inst_no, num_sgpgs);
424 nextLowerInt(&num_sgpgs);
425 printk(KERN_INFO "bfad[%d]: trying to"
426 " allocate memory with"
427 " num_sgpgs: %d\n",
428 bfad->inst_no, num_sgpgs);
429 retry_count++;
430 goto retry;
431 } else {
432 if (num_sgpgs_parm > 0)
433 num_sgpgs = num_sgpgs_parm;
434 else {
435 reset_value =
436 (1 << retry_count);
437 num_sgpgs *= reset_value;
438 }
439 rc = BFA_STATUS_ENOMEM;
440 goto ext;
441 }
442 }
443
444 if (num_sgpgs_parm > 0)
445 num_sgpgs = num_sgpgs_parm;
446 else {
447 reset_value = (1 << retry_count);
448 num_sgpgs *= reset_value;
449 }
450
451 memset(kva, 0, meminfo_elem->mem_len);
452 meminfo_elem->kva = kva;
453 meminfo_elem->dma = phys_addr;
454 break;
455 default:
456 break;
457
458 }
459 }
460ext:
461 return rc;
462}
463
464/**
465 * Create a vport under a vf.
466 */
467bfa_status_t
468bfad_vport_create(struct bfad_s *bfad, u16 vf_id,
469 struct bfa_port_cfg_s *port_cfg)
470{
471 struct bfad_vport_s *vport;
472 int rc = BFA_STATUS_OK;
473 unsigned long flags;
474 struct completion fcomp;
475
476 vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL);
477 if (!vport) {
478 rc = BFA_STATUS_ENOMEM;
479 goto ext;
480 }
481
482 vport->drv_port.bfad = bfad;
483 spin_lock_irqsave(&bfad->bfad_lock, flags);
484 rc = bfa_fcs_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, vf_id,
485 port_cfg, vport);
486 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
487
488 if (rc != BFA_STATUS_OK)
489 goto ext_free_vport;
490
491 if (port_cfg->roles & BFA_PORT_ROLE_FCP_IM) {
492 rc = bfad_im_scsi_host_alloc(bfad, vport->drv_port.im_port);
493 if (rc != BFA_STATUS_OK)
494 goto ext_free_fcs_vport;
495 }
496
497 spin_lock_irqsave(&bfad->bfad_lock, flags);
498 bfa_fcs_vport_start(&vport->fcs_vport);
499 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
500
501 return BFA_STATUS_OK;
502
503ext_free_fcs_vport:
504 spin_lock_irqsave(&bfad->bfad_lock, flags);
505 vport->comp_del = &fcomp;
506 init_completion(vport->comp_del);
507 bfa_fcs_vport_delete(&vport->fcs_vport);
508 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
509 wait_for_completion(vport->comp_del);
510ext_free_vport:
511 kfree(vport);
512ext:
513 return rc;
514}
515
516/**
517 * Create a vf and its base vport implicitely.
518 */
519bfa_status_t
520bfad_vf_create(struct bfad_s *bfad, u16 vf_id,
521 struct bfa_port_cfg_s *port_cfg)
522{
523 struct bfad_vf_s *vf;
524 int rc = BFA_STATUS_OK;
525
526 vf = kzalloc(sizeof(struct bfad_vf_s), GFP_KERNEL);
527 if (!vf) {
528 rc = BFA_STATUS_FAILED;
529 goto ext;
530 }
531
532 rc = bfa_fcs_vf_create(&vf->fcs_vf, &bfad->bfa_fcs, vf_id, port_cfg,
533 vf);
534 if (rc != BFA_STATUS_OK)
535 kfree(vf);
536ext:
537 return rc;
538}
539
540void
541bfad_bfa_tmo(unsigned long data)
542{
543 struct bfad_s *bfad = (struct bfad_s *)data;
544 unsigned long flags;
545 struct list_head doneq;
546
547 spin_lock_irqsave(&bfad->bfad_lock, flags);
548
549 bfa_timer_tick(&bfad->bfa);
550
551 bfa_comp_deq(&bfad->bfa, &doneq);
552 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
553
554 if (!list_empty(&doneq)) {
555 bfa_comp_process(&bfad->bfa, &doneq);
556 spin_lock_irqsave(&bfad->bfad_lock, flags);
557 bfa_comp_free(&bfad->bfa, &doneq);
558 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
559 }
560
561 mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
562}
563
564void
565bfad_init_timer(struct bfad_s *bfad)
566{
567 init_timer(&bfad->hal_tmo);
568 bfad->hal_tmo.function = bfad_bfa_tmo;
569 bfad->hal_tmo.data = (unsigned long)bfad;
570
571 mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
572}
573
574int
575bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad)
576{
577 unsigned long bar0_len;
578 int rc = -ENODEV;
579
580 if (pci_enable_device(pdev)) {
581 BFA_PRINTF(BFA_ERR, "pci_enable_device fail %p\n", pdev);
582 goto out;
583 }
584
585 if (pci_request_regions(pdev, BFAD_DRIVER_NAME))
586 goto out_disable_device;
587
588 pci_set_master(pdev);
589
590
591 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)
592 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
593 BFA_PRINTF(BFA_ERR, "pci_set_dma_mask fail %p\n", pdev);
594 goto out_release_region;
595 }
596
597 bfad->pci_bar0_map = pci_resource_start(pdev, 0);
598 bar0_len = pci_resource_len(pdev, 0);
599 bfad->pci_bar0_kva = ioremap(bfad->pci_bar0_map, bar0_len);
600
601 if (bfad->pci_bar0_kva == NULL) {
602 BFA_PRINTF(BFA_ERR, "Fail to map bar0\n");
603 goto out_release_region;
604 }
605
606 bfad->hal_pcidev.pci_slot = PCI_SLOT(pdev->devfn);
607 bfad->hal_pcidev.pci_func = PCI_FUNC(pdev->devfn);
608 bfad->hal_pcidev.pci_bar_kva = bfad->pci_bar0_kva;
609 bfad->hal_pcidev.device_id = pdev->device;
610 bfad->pci_name = pci_name(pdev);
611
612 bfad->pci_attr.vendor_id = pdev->vendor;
613 bfad->pci_attr.device_id = pdev->device;
614 bfad->pci_attr.ssid = pdev->subsystem_device;
615 bfad->pci_attr.ssvid = pdev->subsystem_vendor;
616 bfad->pci_attr.pcifn = PCI_FUNC(pdev->devfn);
617
618 bfad->pcidev = pdev;
619 return 0;
620
621out_release_region:
622 pci_release_regions(pdev);
623out_disable_device:
624 pci_disable_device(pdev);
625out:
626 return rc;
627}
628
629void
630bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad)
631{
632#if defined(__ia64__)
633 pci_iounmap(pdev, bfad->pci_bar0_kva);
634#else
635 iounmap(bfad->pci_bar0_kva);
636#endif
637 pci_release_regions(pdev);
638 pci_disable_device(pdev);
639 pci_set_drvdata(pdev, NULL);
640}
641
642void
643bfad_fcs_port_cfg(struct bfad_s *bfad)
644{
645 struct bfa_port_cfg_s port_cfg;
646 struct bfa_pport_attr_s attr;
647 char symname[BFA_SYMNAME_MAXLEN];
648
649 sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
650 memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
651 bfa_pport_get_attr(&bfad->bfa, &attr);
652 port_cfg.nwwn = attr.nwwn;
653 port_cfg.pwwn = attr.pwwn;
654
655 bfa_fcs_cfg_base_port(&bfad->bfa_fcs, &port_cfg);
656}
657
658bfa_status_t
659bfad_drv_init(struct bfad_s *bfad)
660{
661 bfa_status_t rc;
662 unsigned long flags;
663 struct bfa_fcs_driver_info_s driver_info;
664 int i;
665
666 bfad->cfg_data.rport_del_timeout = rport_del_timeout;
667 bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
668 bfad->cfg_data.io_max_sge = bfa_io_max_sge;
669 bfad->cfg_data.binding_method = FCP_PWWN_BINDING;
670
671 rc = bfad_hal_mem_alloc(bfad);
672 if (rc != BFA_STATUS_OK) {
673 printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n",
674 bfad->inst_no);
675 printk(KERN_WARNING
676 "Not enough memory to attach all Brocade HBA ports,"
677 " System may need more memory.\n");
678 goto out_hal_mem_alloc_failure;
679 }
680
681 bfa_init_log(&bfad->bfa, bfad->logmod);
682 bfa_init_trc(&bfad->bfa, bfad->trcmod);
683 bfa_init_aen(&bfad->bfa, bfad->aen);
684 INIT_LIST_HEAD(&bfad->file_q);
685 INIT_LIST_HEAD(&bfad->file_free_q);
686 for (i = 0; i < BFAD_AEN_MAX_APPS; i++) {
687 bfa_q_qe_init(&bfad->file_buf[i].qe);
688 list_add_tail(&bfad->file_buf[i].qe, &bfad->file_free_q);
689 }
690 bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
691 bfa_plog_init(&bfad->plog_buf);
692 bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
693 0, "Driver Attach");
694
695 bfa_attach(&bfad->bfa, bfad, &bfad->ioc_cfg, &bfad->meminfo,
696 &bfad->hal_pcidev);
697
698 init_completion(&bfad->comp);
699
700 /*
701 * Enable Interrupt and wait bfa_init completion
702 */
703 if (bfad_setup_intr(bfad)) {
704 printk(KERN_WARNING "bfad%d: bfad_setup_intr failed\n",
705 bfad->inst_no);
706 goto out_setup_intr_failure;
707 }
708
709 spin_lock_irqsave(&bfad->bfad_lock, flags);
710 bfa_init(&bfad->bfa);
711 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
712
713 /*
714 * Set up interrupt handler for each vectors
715 */
716 if ((bfad->bfad_flags & BFAD_MSIX_ON)
717 && bfad_install_msix_handler(bfad)) {
718 printk(KERN_WARNING "%s: install_msix failed, bfad%d\n",
719 __FUNCTION__, bfad->inst_no);
720 }
721
722 bfad_init_timer(bfad);
723
724 wait_for_completion(&bfad->comp);
725
726 memset(&driver_info, 0, sizeof(driver_info));
727 strncpy(driver_info.version, BFAD_DRIVER_VERSION,
728 sizeof(driver_info.version) - 1);
729 if (host_name)
730 strncpy(driver_info.host_machine_name, host_name,
731 sizeof(driver_info.host_machine_name) - 1);
732 if (os_name)
733 strncpy(driver_info.host_os_name, os_name,
734 sizeof(driver_info.host_os_name) - 1);
735 if (os_patch)
736 strncpy(driver_info.host_os_patch, os_patch,
737 sizeof(driver_info.host_os_patch) - 1);
738
739 strncpy(driver_info.os_device_name, bfad->pci_name,
740 sizeof(driver_info.os_device_name - 1));
741
742 /*
743 * FCS INIT
744 */
745 spin_lock_irqsave(&bfad->bfad_lock, flags);
746 bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod);
747 bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
748 bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen);
749 bfa_fcs_init(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
750 bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
751 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
752
753 bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
754 return BFA_STATUS_OK;
755
756out_setup_intr_failure:
757 bfa_detach(&bfad->bfa);
758 bfad_hal_mem_release(bfad);
759out_hal_mem_alloc_failure:
760 return BFA_STATUS_FAILED;
761}
762
763void
764bfad_drv_uninit(struct bfad_s *bfad)
765{
766 del_timer_sync(&bfad->hal_tmo);
767 bfa_isr_disable(&bfad->bfa);
768 bfa_detach(&bfad->bfa);
769 bfad_remove_intr(bfad);
770 bfa_assert(list_empty(&bfad->file_q));
771 bfad_hal_mem_release(bfad);
772}
773
774void
775bfad_drv_start(struct bfad_s *bfad)
776{
777 unsigned long flags;
778
779 spin_lock_irqsave(&bfad->bfad_lock, flags);
780 bfa_start(&bfad->bfa);
781 bfa_fcs_start(&bfad->bfa_fcs);
782 bfad->bfad_flags |= BFAD_HAL_START_DONE;
783 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
784
785 bfad_fc4_probe_post(bfad);
786}
787
788void
789bfad_drv_stop(struct bfad_s *bfad)
790{
791 unsigned long flags;
792
793 spin_lock_irqsave(&bfad->bfad_lock, flags);
794 init_completion(&bfad->comp);
795 bfad->pport.flags |= BFAD_PORT_DELETE;
796 bfa_fcs_exit(&bfad->bfa_fcs);
797 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
798 wait_for_completion(&bfad->comp);
799
800 spin_lock_irqsave(&bfad->bfad_lock, flags);
801 init_completion(&bfad->comp);
802 bfa_stop(&bfad->bfa);
803 bfad->bfad_flags &= ~BFAD_HAL_START_DONE;
804 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
805 wait_for_completion(&bfad->comp);
806}
807
808bfa_status_t
809bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role)
810{
811 int rc = BFA_STATUS_OK;
812
813 /*
814 * Allocate scsi_host for the physical port
815 */
816 if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
817 && (role & BFA_PORT_ROLE_FCP_IM)) {
818 if (bfad->pport.im_port == NULL) {
819 rc = BFA_STATUS_FAILED;
820 goto out;
821 }
822
823 rc = bfad_im_scsi_host_alloc(bfad, bfad->pport.im_port);
824 if (rc != BFA_STATUS_OK)
825 goto out;
826
827 bfad->pport.roles |= BFA_PORT_ROLE_FCP_IM;
828 }
829
830 bfad->bfad_flags |= BFAD_CFG_PPORT_DONE;
831
832out:
833 return rc;
834}
835
836void
837bfad_uncfg_pport(struct bfad_s *bfad)
838{
839 if ((bfad->pport.roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) {
840 bfad_ipfc_port_delete(bfad, &bfad->pport);
841 bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IPFC;
842 }
843
844 if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
845 && (bfad->pport.roles & BFA_PORT_ROLE_FCP_IM)) {
846 bfad_im_scsi_host_free(bfad, bfad->pport.im_port);
847 bfad_im_port_clean(bfad->pport.im_port);
848 kfree(bfad->pport.im_port);
849 bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IM;
850 }
851
852 bfad->bfad_flags &= ~BFAD_CFG_PPORT_DONE;
853}
854
855void
856bfad_drv_log_level_set(struct bfad_s *bfad)
857{
858 if (log_level > BFA_LOG_INVALID && log_level <= BFA_LOG_LEVEL_MAX)
859 bfa_log_set_level_all(&bfad->log_data, log_level);
860}
861
862 /*
863 * PCI_entry PCI driver entries * {
864 */
865
866/**
867 * PCI probe entry.
868 */
869int
870bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
871{
872 struct bfad_s *bfad;
873 int error = -ENODEV, retval;
874 char buf[16];
875
876 /*
877 * For single port cards - only claim function 0
878 */
879 if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P)
880 && (PCI_FUNC(pdev->devfn) != 0))
881 return -ENODEV;
882
883 BFA_TRACE(BFA_INFO, "bfad_pci_probe entry");
884
885 bfad = kzalloc(sizeof(struct bfad_s), GFP_KERNEL);
886 if (!bfad) {
887 error = -ENOMEM;
888 goto out;
889 }
890
891 bfad->trcmod = kzalloc(sizeof(struct bfa_trc_mod_s), GFP_KERNEL);
892 if (!bfad->trcmod) {
893 printk(KERN_WARNING "Error alloc trace buffer!\n");
894 error = -ENOMEM;
895 goto out_alloc_trace_failure;
896 }
897
898 /*
899 * LOG/TRACE INIT
900 */
901 bfa_trc_init(bfad->trcmod);
902 bfa_trc(bfad, bfad_inst);
903
904 bfad->logmod = &bfad->log_data;
905 sprintf(buf, "%d", bfad_inst);
906 bfa_log_init(bfad->logmod, buf, bfa_os_printf);
907
908 bfad_drv_log_level_set(bfad);
909
910 bfad->aen = &bfad->aen_buf;
911
912 if (!(bfad_load_fwimg(pdev))) {
913 printk(KERN_WARNING "bfad_load_fwimg failure!\n");
914 kfree(bfad->trcmod);
915 goto out_alloc_trace_failure;
916 }
917
918 retval = bfad_pci_init(pdev, bfad);
919 if (retval) {
920 printk(KERN_WARNING "bfad_pci_init failure!\n");
921 error = retval;
922 goto out_pci_init_failure;
923 }
924
925 mutex_lock(&bfad_mutex);
926 bfad->inst_no = bfad_inst++;
927 list_add_tail(&bfad->list_entry, &bfad_list);
928 mutex_unlock(&bfad_mutex);
929
930 spin_lock_init(&bfad->bfad_lock);
931 pci_set_drvdata(pdev, bfad);
932
933 bfad->ref_count = 0;
934 bfad->pport.bfad = bfad;
935
936 retval = bfad_drv_init(bfad);
937 if (retval != BFA_STATUS_OK)
938 goto out_drv_init_failure;
939 if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
940 printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no);
941 goto ok;
942 }
943
944 /*
945 * PPORT FCS config
946 */
947 bfad_fcs_port_cfg(bfad);
948
949 retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
950 if (retval != BFA_STATUS_OK)
951 goto out_cfg_pport_failure;
952
953 /*
954 * BFAD level FC4 (IM/TM/IPFC) specific resource allocation
955 */
956 retval = bfad_fc4_probe(bfad);
957 if (retval != BFA_STATUS_OK) {
958 printk(KERN_WARNING "bfad_fc4_probe failed\n");
959 goto out_fc4_probe_failure;
960 }
961
962 bfad_drv_start(bfad);
963
964 /*
965 * If bfa_linkup_delay is set to -1 default; try to retrive the
966 * value using the bfad_os_get_linkup_delay(); else use the
967 * passed in module param value as the bfa_linkup_delay.
968 */
969 if (bfa_linkup_delay < 0) {
970 bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
971 bfad_os_rport_online_wait(bfad);
972 bfa_linkup_delay = -1;
973 } else {
974 bfad_os_rport_online_wait(bfad);
975 }
976
977 bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
978ok:
979 return 0;
980
981out_fc4_probe_failure:
982 bfad_fc4_probe_undo(bfad);
983 bfad_uncfg_pport(bfad);
984out_cfg_pport_failure:
985 bfad_drv_uninit(bfad);
986out_drv_init_failure:
987 mutex_lock(&bfad_mutex);
988 bfad_inst--;
989 list_del(&bfad->list_entry);
990 mutex_unlock(&bfad_mutex);
991 bfad_pci_uninit(pdev, bfad);
992out_pci_init_failure:
993 kfree(bfad->trcmod);
994out_alloc_trace_failure:
995 kfree(bfad);
996out:
997 return error;
998}
999
1000/**
1001 * PCI remove entry.
1002 */
1003void
1004bfad_pci_remove(struct pci_dev *pdev)
1005{
1006 struct bfad_s *bfad = pci_get_drvdata(pdev);
1007 unsigned long flags;
1008
1009 bfa_trc(bfad, bfad->inst_no);
1010
1011 if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE)
1012 && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
1013
1014 spin_lock_irqsave(&bfad->bfad_lock, flags);
1015 init_completion(&bfad->comp);
1016 bfa_stop(&bfad->bfa);
1017 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1018 wait_for_completion(&bfad->comp);
1019
1020 bfad_remove_intr(bfad);
1021 del_timer_sync(&bfad->hal_tmo);
1022 goto hal_detach;
1023 } else if (!(bfad->bfad_flags & BFAD_DRV_INIT_DONE)) {
1024 goto remove_sysfs;
1025 }
1026
1027 if (bfad->bfad_flags & BFAD_HAL_START_DONE)
1028 bfad_drv_stop(bfad);
1029
1030 bfad_remove_intr(bfad);
1031
1032 del_timer_sync(&bfad->hal_tmo);
1033 bfad_fc4_probe_undo(bfad);
1034
1035 if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
1036 bfad_uncfg_pport(bfad);
1037
1038hal_detach:
1039 spin_lock_irqsave(&bfad->bfad_lock, flags);
1040 bfa_detach(&bfad->bfa);
1041 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1042 bfad_hal_mem_release(bfad);
1043remove_sysfs:
1044
1045 mutex_lock(&bfad_mutex);
1046 bfad_inst--;
1047 list_del(&bfad->list_entry);
1048 mutex_unlock(&bfad_mutex);
1049 bfad_pci_uninit(pdev, bfad);
1050
1051 kfree(bfad->trcmod);
1052 kfree(bfad);
1053}
1054
1055
1056static struct pci_device_id bfad_id_table[] = {
1057 {
1058 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1059 .device = BFA_PCI_DEVICE_ID_FC_8G2P,
1060 .subvendor = PCI_ANY_ID,
1061 .subdevice = PCI_ANY_ID,
1062 },
1063 {
1064 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1065 .device = BFA_PCI_DEVICE_ID_FC_8G1P,
1066 .subvendor = PCI_ANY_ID,
1067 .subdevice = PCI_ANY_ID,
1068 },
1069 {
1070 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1071 .device = BFA_PCI_DEVICE_ID_CT,
1072 .subvendor = PCI_ANY_ID,
1073 .subdevice = PCI_ANY_ID,
1074 .class = (PCI_CLASS_SERIAL_FIBER << 8),
1075 .class_mask = ~0,
1076 },
1077
1078 {0, 0},
1079};
1080
1081MODULE_DEVICE_TABLE(pci, bfad_id_table);
1082
1083static struct pci_driver bfad_pci_driver = {
1084 .name = BFAD_DRIVER_NAME,
1085 .id_table = bfad_id_table,
1086 .probe = bfad_pci_probe,
1087 .remove = __devexit_p(bfad_pci_remove),
1088};
1089
1090/**
1091 * Linux driver module functions
1092 */
1093bfa_status_t
1094bfad_fc4_module_init(void)
1095{
1096 int rc;
1097
1098 rc = bfad_im_module_init();
1099 if (rc != BFA_STATUS_OK)
1100 goto ext;
1101
1102 bfad_tm_module_init();
1103 if (ipfc_enable)
1104 bfad_ipfc_module_init();
1105ext:
1106 return rc;
1107}
1108
1109void
1110bfad_fc4_module_exit(void)
1111{
1112 if (ipfc_enable)
1113 bfad_ipfc_module_exit();
1114 bfad_tm_module_exit();
1115 bfad_im_module_exit();
1116}
1117
1118/**
1119 * Driver module init.
1120 */
1121static int __init
1122bfad_init(void)
1123{
1124 int error = 0;
1125
1126 printk(KERN_INFO "Brocade BFA FC/FCOE SCSI driver - version: %s\n",
1127 BFAD_DRIVER_VERSION);
1128
1129 if (num_sgpgs > 0)
1130 num_sgpgs_parm = num_sgpgs;
1131
1132 error = bfad_fc4_module_init();
1133 if (error) {
1134 error = -ENOMEM;
1135 printk(KERN_WARNING "bfad_fc4_module_init failure\n");
1136 goto ext;
1137 }
1138
1139 if (!strcmp(FCPI_NAME, " fcpim"))
1140 bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IM;
1141 if (!strcmp(FCPT_NAME, " fcptm"))
1142 bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_TM;
1143 if (!strcmp(IPFC_NAME, " ipfc"))
1144 bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IPFC;
1145
1146 bfa_ioc_auto_recover(ioc_auto_recover);
1147 bfa_fcs_rport_set_del_timeout(rport_del_timeout);
1148 error = pci_register_driver(&bfad_pci_driver);
1149
1150 if (error) {
1151 printk(KERN_WARNING "bfad pci_register_driver failure\n");
1152 goto ext;
1153 }
1154
1155 return 0;
1156
1157ext:
1158 bfad_fc4_module_exit();
1159 return error;
1160}
1161
1162/**
1163 * Driver module exit.
1164 */
1165static void __exit
1166bfad_exit(void)
1167{
1168 pci_unregister_driver(&bfad_pci_driver);
1169 bfad_fc4_module_exit();
1170 bfad_free_fwimg();
1171}
1172
1173#define BFAD_PROTO_NAME FCPI_NAME FCPT_NAME IPFC_NAME
1174
1175module_init(bfad_init);
1176module_exit(bfad_exit);
1177MODULE_LICENSE("GPL");
1178MODULE_DESCRIPTION("Brocade Fibre Channel HBA Driver" BFAD_PROTO_NAME);
1179MODULE_AUTHOR("Brocade Communications Systems, Inc.");
1180MODULE_VERSION(BFAD_DRIVER_VERSION);
1181
1182
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c
new file mode 100644
index 000000000000..9129ae3040ff
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_attr.c
@@ -0,0 +1,649 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_attr.c Linux driver configuration interface module.
20 */
21
22#include "bfad_drv.h"
23#include "bfad_im.h"
24#include "bfad_trcmod.h"
25#include "bfad_attr.h"
26
27/**
28 * FC_transport_template FC transport template
29 */
30
31/**
32 * FC transport template entry, get SCSI target port ID.
33 */
34void
35bfad_im_get_starget_port_id(struct scsi_target *starget)
36{
37 struct Scsi_Host *shost;
38 struct bfad_im_port_s *im_port;
39 struct bfad_s *bfad;
40 struct bfad_itnim_s *itnim = NULL;
41 u32 fc_id = -1;
42 unsigned long flags;
43
44 shost = bfad_os_starget_to_shost(starget);
45 im_port = (struct bfad_im_port_s *) shost->hostdata[0];
46 bfad = im_port->bfad;
47 spin_lock_irqsave(&bfad->bfad_lock, flags);
48
49 itnim = bfad_os_get_itnim(im_port, starget->id);
50 if (itnim)
51 fc_id = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim);
52
53 fc_starget_port_id(starget) = fc_id;
54 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
55}
56
57/**
58 * FC transport template entry, get SCSI target nwwn.
59 */
60void
61bfad_im_get_starget_node_name(struct scsi_target *starget)
62{
63 struct Scsi_Host *shost;
64 struct bfad_im_port_s *im_port;
65 struct bfad_s *bfad;
66 struct bfad_itnim_s *itnim = NULL;
67 u64 node_name = 0;
68 unsigned long flags;
69
70 shost = bfad_os_starget_to_shost(starget);
71 im_port = (struct bfad_im_port_s *) shost->hostdata[0];
72 bfad = im_port->bfad;
73 spin_lock_irqsave(&bfad->bfad_lock, flags);
74
75 itnim = bfad_os_get_itnim(im_port, starget->id);
76 if (itnim)
77 node_name = bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim);
78
79 fc_starget_node_name(starget) = bfa_os_htonll(node_name);
80 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
81}
82
83/**
84 * FC transport template entry, get SCSI target pwwn.
85 */
86void
87bfad_im_get_starget_port_name(struct scsi_target *starget)
88{
89 struct Scsi_Host *shost;
90 struct bfad_im_port_s *im_port;
91 struct bfad_s *bfad;
92 struct bfad_itnim_s *itnim = NULL;
93 u64 port_name = 0;
94 unsigned long flags;
95
96 shost = bfad_os_starget_to_shost(starget);
97 im_port = (struct bfad_im_port_s *) shost->hostdata[0];
98 bfad = im_port->bfad;
99 spin_lock_irqsave(&bfad->bfad_lock, flags);
100
101 itnim = bfad_os_get_itnim(im_port, starget->id);
102 if (itnim)
103 port_name = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim);
104
105 fc_starget_port_name(starget) = bfa_os_htonll(port_name);
106 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
107}
108
109/**
110 * FC transport template entry, get SCSI host port ID.
111 */
112void
113bfad_im_get_host_port_id(struct Scsi_Host *shost)
114{
115 struct bfad_im_port_s *im_port =
116 (struct bfad_im_port_s *) shost->hostdata[0];
117 struct bfad_port_s *port = im_port->port;
118
119 fc_host_port_id(shost) =
120 bfa_os_hton3b(bfa_fcs_port_get_fcid(port->fcs_port));
121}
122
123
124
125
126
127struct Scsi_Host *
128bfad_os_starget_to_shost(struct scsi_target *starget)
129{
130 return dev_to_shost(starget->dev.parent);
131}
132
133/**
134 * FC transport template entry, get SCSI host port type.
135 */
136static void
137bfad_im_get_host_port_type(struct Scsi_Host *shost)
138{
139 struct bfad_im_port_s *im_port =
140 (struct bfad_im_port_s *) shost->hostdata[0];
141 struct bfad_s *bfad = im_port->bfad;
142 struct bfa_pport_attr_s attr;
143
144 bfa_pport_get_attr(&bfad->bfa, &attr);
145
146 switch (attr.port_type) {
147 case BFA_PPORT_TYPE_NPORT:
148 fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
149 break;
150 case BFA_PPORT_TYPE_NLPORT:
151 fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
152 break;
153 case BFA_PPORT_TYPE_P2P:
154 fc_host_port_type(shost) = FC_PORTTYPE_PTP;
155 break;
156 case BFA_PPORT_TYPE_LPORT:
157 fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
158 break;
159 default:
160 fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
161 break;
162 }
163}
164
165/**
166 * FC transport template entry, get SCSI host port state.
167 */
168static void
169bfad_im_get_host_port_state(struct Scsi_Host *shost)
170{
171 struct bfad_im_port_s *im_port =
172 (struct bfad_im_port_s *) shost->hostdata[0];
173 struct bfad_s *bfad = im_port->bfad;
174 struct bfa_pport_attr_s attr;
175
176 bfa_pport_get_attr(&bfad->bfa, &attr);
177
178 switch (attr.port_state) {
179 case BFA_PPORT_ST_LINKDOWN:
180 fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
181 break;
182 case BFA_PPORT_ST_LINKUP:
183 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
184 break;
185 case BFA_PPORT_ST_UNINIT:
186 case BFA_PPORT_ST_ENABLING_QWAIT:
187 case BFA_PPORT_ST_ENABLING:
188 case BFA_PPORT_ST_DISABLING_QWAIT:
189 case BFA_PPORT_ST_DISABLING:
190 case BFA_PPORT_ST_DISABLED:
191 case BFA_PPORT_ST_STOPPED:
192 case BFA_PPORT_ST_IOCDOWN:
193 default:
194 fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
195 break;
196 }
197}
198
199/**
200 * FC transport template entry, get SCSI host active fc4s.
201 */
202static void
203bfad_im_get_host_active_fc4s(struct Scsi_Host *shost)
204{
205 struct bfad_im_port_s *im_port =
206 (struct bfad_im_port_s *) shost->hostdata[0];
207 struct bfad_port_s *port = im_port->port;
208
209 memset(fc_host_active_fc4s(shost), 0,
210 sizeof(fc_host_active_fc4s(shost)));
211
212 if (port->supported_fc4s &
213 (BFA_PORT_ROLE_FCP_IM | BFA_PORT_ROLE_FCP_TM))
214 fc_host_active_fc4s(shost)[2] = 1;
215
216 if (port->supported_fc4s & BFA_PORT_ROLE_FCP_IPFC)
217 fc_host_active_fc4s(shost)[3] = 0x20;
218
219 fc_host_active_fc4s(shost)[7] = 1;
220}
221
222/**
223 * FC transport template entry, get SCSI host link speed.
224 */
225static void
226bfad_im_get_host_speed(struct Scsi_Host *shost)
227{
228 struct bfad_im_port_s *im_port =
229 (struct bfad_im_port_s *) shost->hostdata[0];
230 struct bfad_s *bfad = im_port->bfad;
231 struct bfa_pport_attr_s attr;
232
233 bfa_pport_get_attr(&bfad->bfa, &attr);
234 switch (attr.speed) {
235 case BFA_PPORT_SPEED_8GBPS:
236 fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
237 break;
238 case BFA_PPORT_SPEED_4GBPS:
239 fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
240 break;
241 case BFA_PPORT_SPEED_2GBPS:
242 fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
243 break;
244 case BFA_PPORT_SPEED_1GBPS:
245 fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
246 break;
247 default:
248 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
249 break;
250 }
251}
252
253/**
254 * FC transport template entry, get SCSI host port type.
255 */
256static void
257bfad_im_get_host_fabric_name(struct Scsi_Host *shost)
258{
259 struct bfad_im_port_s *im_port =
260 (struct bfad_im_port_s *) shost->hostdata[0];
261 struct bfad_port_s *port = im_port->port;
262 wwn_t fabric_nwwn = 0;
263
264 fabric_nwwn = bfa_fcs_port_get_fabric_name(port->fcs_port);
265
266 fc_host_fabric_name(shost) = bfa_os_htonll(fabric_nwwn);
267
268}
269
270/**
271 * FC transport template entry, get BFAD statistics.
272 */
273static struct fc_host_statistics *
274bfad_im_get_stats(struct Scsi_Host *shost)
275{
276 struct bfad_im_port_s *im_port =
277 (struct bfad_im_port_s *) shost->hostdata[0];
278 struct bfad_s *bfad = im_port->bfad;
279 struct bfad_hal_comp fcomp;
280 struct fc_host_statistics *hstats;
281 bfa_status_t rc;
282 unsigned long flags;
283
284 hstats = &bfad->link_stats;
285 init_completion(&fcomp.comp);
286 spin_lock_irqsave(&bfad->bfad_lock, flags);
287 memset(hstats, 0, sizeof(struct fc_host_statistics));
288 rc = bfa_pport_get_stats(&bfad->bfa,
289 (union bfa_pport_stats_u *) hstats,
290 bfad_hcb_comp, &fcomp);
291 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
292 if (rc != BFA_STATUS_OK)
293 return NULL;
294
295 wait_for_completion(&fcomp.comp);
296
297 return hstats;
298}
299
300/**
301 * FC transport template entry, reset BFAD statistics.
302 */
303static void
304bfad_im_reset_stats(struct Scsi_Host *shost)
305{
306 struct bfad_im_port_s *im_port =
307 (struct bfad_im_port_s *) shost->hostdata[0];
308 struct bfad_s *bfad = im_port->bfad;
309 struct bfad_hal_comp fcomp;
310 unsigned long flags;
311 bfa_status_t rc;
312
313 init_completion(&fcomp.comp);
314 spin_lock_irqsave(&bfad->bfad_lock, flags);
315 rc = bfa_pport_clear_stats(&bfad->bfa, bfad_hcb_comp, &fcomp);
316 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
317
318 if (rc != BFA_STATUS_OK)
319 return;
320
321 wait_for_completion(&fcomp.comp);
322
323 return;
324}
325
326/**
327 * FC transport template entry, get rport loss timeout.
328 */
329static void
330bfad_im_get_rport_loss_tmo(struct fc_rport *rport)
331{
332 struct bfad_itnim_data_s *itnim_data = rport->dd_data;
333 struct bfad_itnim_s *itnim = itnim_data->itnim;
334 struct bfad_s *bfad = itnim->im->bfad;
335 unsigned long flags;
336
337 spin_lock_irqsave(&bfad->bfad_lock, flags);
338 rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa);
339 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
340}
341
342/**
343 * FC transport template entry, set rport loss timeout.
344 */
345static void
346bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
347{
348 struct bfad_itnim_data_s *itnim_data = rport->dd_data;
349 struct bfad_itnim_s *itnim = itnim_data->itnim;
350 struct bfad_s *bfad = itnim->im->bfad;
351 unsigned long flags;
352
353 if (timeout > 0) {
354 spin_lock_irqsave(&bfad->bfad_lock, flags);
355 bfa_fcpim_path_tov_set(&bfad->bfa, timeout);
356 rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa);
357 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
358 }
359
360}
361
362struct fc_function_template bfad_im_fc_function_template = {
363
364 /* Target dynamic attributes */
365 .get_starget_port_id = bfad_im_get_starget_port_id,
366 .show_starget_port_id = 1,
367 .get_starget_node_name = bfad_im_get_starget_node_name,
368 .show_starget_node_name = 1,
369 .get_starget_port_name = bfad_im_get_starget_port_name,
370 .show_starget_port_name = 1,
371
372 /* Host dynamic attribute */
373 .get_host_port_id = bfad_im_get_host_port_id,
374 .show_host_port_id = 1,
375
376 /* Host fixed attributes */
377 .show_host_node_name = 1,
378 .show_host_port_name = 1,
379 .show_host_supported_classes = 1,
380 .show_host_supported_fc4s = 1,
381 .show_host_supported_speeds = 1,
382 .show_host_maxframe_size = 1,
383
384 /* More host dynamic attributes */
385 .show_host_port_type = 1,
386 .get_host_port_type = bfad_im_get_host_port_type,
387 .show_host_port_state = 1,
388 .get_host_port_state = bfad_im_get_host_port_state,
389 .show_host_active_fc4s = 1,
390 .get_host_active_fc4s = bfad_im_get_host_active_fc4s,
391 .show_host_speed = 1,
392 .get_host_speed = bfad_im_get_host_speed,
393 .show_host_fabric_name = 1,
394 .get_host_fabric_name = bfad_im_get_host_fabric_name,
395
396 .show_host_symbolic_name = 1,
397
398 /* Statistics */
399 .get_fc_host_stats = bfad_im_get_stats,
400 .reset_fc_host_stats = bfad_im_reset_stats,
401
402 /* Allocation length for host specific data */
403 .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *),
404
405 /* Remote port fixed attributes */
406 .show_rport_maxframe_size = 1,
407 .show_rport_supported_classes = 1,
408 .show_rport_dev_loss_tmo = 1,
409 .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo,
410 .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo,
411};
412
413/**
414 * Scsi_Host_attrs SCSI host attributes
415 */
416static ssize_t
417bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr,
418 char *buf)
419{
420 struct Scsi_Host *shost = class_to_shost(dev);
421 struct bfad_im_port_s *im_port =
422 (struct bfad_im_port_s *) shost->hostdata[0];
423 struct bfad_s *bfad = im_port->bfad;
424 struct bfa_ioc_attr_s ioc_attr;
425
426 memset(&ioc_attr, 0, sizeof(ioc_attr));
427 bfa_get_attr(&bfad->bfa, &ioc_attr);
428 return snprintf(buf, PAGE_SIZE, "%s\n",
429 ioc_attr.adapter_attr.serial_num);
430}
431
432static ssize_t
433bfad_im_model_show(struct device *dev, struct device_attribute *attr,
434 char *buf)
435{
436 struct Scsi_Host *shost = class_to_shost(dev);
437 struct bfad_im_port_s *im_port =
438 (struct bfad_im_port_s *) shost->hostdata[0];
439 struct bfad_s *bfad = im_port->bfad;
440 struct bfa_ioc_attr_s ioc_attr;
441
442 memset(&ioc_attr, 0, sizeof(ioc_attr));
443 bfa_get_attr(&bfad->bfa, &ioc_attr);
444 return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.model);
445}
446
447static ssize_t
448bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr,
449 char *buf)
450{
451 struct Scsi_Host *shost = class_to_shost(dev);
452 struct bfad_im_port_s *im_port =
453 (struct bfad_im_port_s *) shost->hostdata[0];
454 struct bfad_s *bfad = im_port->bfad;
455 struct bfa_ioc_attr_s ioc_attr;
456
457 memset(&ioc_attr, 0, sizeof(ioc_attr));
458 bfa_get_attr(&bfad->bfa, &ioc_attr);
459 return snprintf(buf, PAGE_SIZE, "%s\n",
460 ioc_attr.adapter_attr.model_descr);
461}
462
463static ssize_t
464bfad_im_node_name_show(struct device *dev, struct device_attribute *attr,
465 char *buf)
466{
467 struct Scsi_Host *shost = class_to_shost(dev);
468 struct bfad_im_port_s *im_port =
469 (struct bfad_im_port_s *) shost->hostdata[0];
470 struct bfad_port_s *port = im_port->port;
471 u64 nwwn;
472
473 nwwn = bfa_fcs_port_get_nwwn(port->fcs_port);
474 return snprintf(buf, PAGE_SIZE, "0x%llx\n", bfa_os_htonll(nwwn));
475}
476
477static ssize_t
478bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr,
479 char *buf)
480{
481 struct Scsi_Host *shost = class_to_shost(dev);
482 struct bfad_im_port_s *im_port =
483 (struct bfad_im_port_s *) shost->hostdata[0];
484 struct bfad_s *bfad = im_port->bfad;
485 struct bfa_ioc_attr_s ioc_attr;
486
487 memset(&ioc_attr, 0, sizeof(ioc_attr));
488 bfa_get_attr(&bfad->bfa, &ioc_attr);
489
490 return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n",
491 ioc_attr.adapter_attr.model,
492 ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
493}
494
495static ssize_t
496bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr,
497 char *buf)
498{
499 struct Scsi_Host *shost = class_to_shost(dev);
500 struct bfad_im_port_s *im_port =
501 (struct bfad_im_port_s *) shost->hostdata[0];
502 struct bfad_s *bfad = im_port->bfad;
503 struct bfa_ioc_attr_s ioc_attr;
504
505 memset(&ioc_attr, 0, sizeof(ioc_attr));
506 bfa_get_attr(&bfad->bfa, &ioc_attr);
507 return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.hw_ver);
508}
509
510static ssize_t
511bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr,
512 char *buf)
513{
514 return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_VERSION);
515}
516
517static ssize_t
518bfad_im_optionrom_version_show(struct device *dev,
519 struct device_attribute *attr, char *buf)
520{
521 struct Scsi_Host *shost = class_to_shost(dev);
522 struct bfad_im_port_s *im_port =
523 (struct bfad_im_port_s *) shost->hostdata[0];
524 struct bfad_s *bfad = im_port->bfad;
525 struct bfa_ioc_attr_s ioc_attr;
526
527 memset(&ioc_attr, 0, sizeof(ioc_attr));
528 bfa_get_attr(&bfad->bfa, &ioc_attr);
529 return snprintf(buf, PAGE_SIZE, "%s\n",
530 ioc_attr.adapter_attr.optrom_ver);
531}
532
533static ssize_t
534bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr,
535 char *buf)
536{
537 struct Scsi_Host *shost = class_to_shost(dev);
538 struct bfad_im_port_s *im_port =
539 (struct bfad_im_port_s *) shost->hostdata[0];
540 struct bfad_s *bfad = im_port->bfad;
541 struct bfa_ioc_attr_s ioc_attr;
542
543 memset(&ioc_attr, 0, sizeof(ioc_attr));
544 bfa_get_attr(&bfad->bfa, &ioc_attr);
545 return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.fw_ver);
546}
547
548static ssize_t
549bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr,
550 char *buf)
551{
552 struct Scsi_Host *shost = class_to_shost(dev);
553 struct bfad_im_port_s *im_port =
554 (struct bfad_im_port_s *) shost->hostdata[0];
555 struct bfad_s *bfad = im_port->bfad;
556 struct bfa_ioc_attr_s ioc_attr;
557
558 memset(&ioc_attr, 0, sizeof(ioc_attr));
559 bfa_get_attr(&bfad->bfa, &ioc_attr);
560 return snprintf(buf, PAGE_SIZE, "%d\n", ioc_attr.adapter_attr.nports);
561}
562
563static ssize_t
564bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr,
565 char *buf)
566{
567 return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_NAME);
568}
569
570static ssize_t
571bfad_im_num_of_discovered_ports_show(struct device *dev,
572 struct device_attribute *attr, char *buf)
573{
574 struct Scsi_Host *shost = class_to_shost(dev);
575 struct bfad_im_port_s *im_port =
576 (struct bfad_im_port_s *) shost->hostdata[0];
577 struct bfad_port_s *port = im_port->port;
578 struct bfad_s *bfad = im_port->bfad;
579 int nrports = 2048;
580 wwn_t *rports = NULL;
581 unsigned long flags;
582
583 rports = kzalloc(sizeof(wwn_t) * nrports , GFP_ATOMIC);
584 if (rports == NULL)
585 return -ENOMEM;
586
587 spin_lock_irqsave(&bfad->bfad_lock, flags);
588 bfa_fcs_port_get_rports(port->fcs_port, rports, &nrports);
589 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
590 kfree(rports);
591
592 return snprintf(buf, PAGE_SIZE, "%d\n", nrports);
593}
594
595static DEVICE_ATTR(serial_number, S_IRUGO,
596 bfad_im_serial_num_show, NULL);
597static DEVICE_ATTR(model, S_IRUGO, bfad_im_model_show, NULL);
598static DEVICE_ATTR(model_description, S_IRUGO,
599 bfad_im_model_desc_show, NULL);
600static DEVICE_ATTR(node_name, S_IRUGO, bfad_im_node_name_show, NULL);
601static DEVICE_ATTR(symbolic_name, S_IRUGO,
602 bfad_im_symbolic_name_show, NULL);
603static DEVICE_ATTR(hardware_version, S_IRUGO,
604 bfad_im_hw_version_show, NULL);
605static DEVICE_ATTR(driver_version, S_IRUGO,
606 bfad_im_drv_version_show, NULL);
607static DEVICE_ATTR(option_rom_version, S_IRUGO,
608 bfad_im_optionrom_version_show, NULL);
609static DEVICE_ATTR(firmware_version, S_IRUGO,
610 bfad_im_fw_version_show, NULL);
611static DEVICE_ATTR(number_of_ports, S_IRUGO,
612 bfad_im_num_of_ports_show, NULL);
613static DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL);
614static DEVICE_ATTR(number_of_discovered_ports, S_IRUGO,
615 bfad_im_num_of_discovered_ports_show, NULL);
616
617struct device_attribute *bfad_im_host_attrs[] = {
618 &dev_attr_serial_number,
619 &dev_attr_model,
620 &dev_attr_model_description,
621 &dev_attr_node_name,
622 &dev_attr_symbolic_name,
623 &dev_attr_hardware_version,
624 &dev_attr_driver_version,
625 &dev_attr_option_rom_version,
626 &dev_attr_firmware_version,
627 &dev_attr_number_of_ports,
628 &dev_attr_driver_name,
629 &dev_attr_number_of_discovered_ports,
630 NULL,
631};
632
633struct device_attribute *bfad_im_vport_attrs[] = {
634 &dev_attr_serial_number,
635 &dev_attr_model,
636 &dev_attr_model_description,
637 &dev_attr_node_name,
638 &dev_attr_symbolic_name,
639 &dev_attr_hardware_version,
640 &dev_attr_driver_version,
641 &dev_attr_option_rom_version,
642 &dev_attr_firmware_version,
643 &dev_attr_number_of_ports,
644 &dev_attr_driver_name,
645 &dev_attr_number_of_discovered_ports,
646 NULL,
647};
648
649
diff --git a/drivers/scsi/bfa/bfad_attr.h b/drivers/scsi/bfa/bfad_attr.h
new file mode 100644
index 000000000000..4d3312da6a81
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_attr.h
@@ -0,0 +1,65 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFAD_ATTR_H__
19#define __BFAD_ATTR_H__
20/**
21 * bfad_attr.h VMware driver configuration interface module.
22 */
23
24/**
25 * FC_transport_template FC transport template
26 */
27
28struct Scsi_Host*
29bfad_os_dev_to_shost(struct scsi_target *starget);
30
31/**
32 * FC transport template entry, get SCSI target port ID.
33 */
34void
35bfad_im_get_starget_port_id(struct scsi_target *starget);
36
37/**
38 * FC transport template entry, get SCSI target nwwn.
39 */
40void
41bfad_im_get_starget_node_name(struct scsi_target *starget);
42
43/**
44 * FC transport template entry, get SCSI target pwwn.
45 */
46void
47bfad_im_get_starget_port_name(struct scsi_target *starget);
48
49/**
50 * FC transport template entry, get SCSI host port ID.
51 */
52void
53bfad_im_get_host_port_id(struct Scsi_Host *shost);
54
55/**
56 * FC transport template entry, issue a LIP.
57 */
58int
59bfad_im_issue_fc_host_lip(struct Scsi_Host *shost);
60
61struct Scsi_Host*
62bfad_os_starget_to_shost(struct scsi_target *starget);
63
64
65#endif /* __BFAD_ATTR_H__ */
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h
new file mode 100644
index 000000000000..172c81e25c1c
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_drv.h
@@ -0,0 +1,295 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * Contains base driver definitions.
20 */
21
22/**
23 * bfa_drv.h Linux driver data structures.
24 */
25
26#ifndef __BFAD_DRV_H__
27#define __BFAD_DRV_H__
28
29#include "bfa_os_inc.h"
30
31#include <bfa.h>
32#include <bfa_svc.h>
33#include <fcs/bfa_fcs.h>
34#include <defs/bfa_defs_pci.h>
35#include <defs/bfa_defs_port.h>
36#include <defs/bfa_defs_rport.h>
37#include <fcs/bfa_fcs_rport.h>
38#include <defs/bfa_defs_vport.h>
39#include <fcs/bfa_fcs_vport.h>
40
41#include <cs/bfa_plog.h>
42#include "aen/bfa_aen.h"
43#include <log/bfa_log_linux.h>
44
45#define BFAD_DRIVER_NAME "bfa"
46#ifdef BFA_DRIVER_VERSION
47#define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION
48#else
49#define BFAD_DRIVER_VERSION "2.0.0.0"
50#endif
51
52
53#define BFAD_IRQ_FLAGS IRQF_SHARED
54
55/*
56 * BFAD flags
57 */
58#define BFAD_MSIX_ON 0x00000001
59#define BFAD_HAL_INIT_DONE 0x00000002
60#define BFAD_DRV_INIT_DONE 0x00000004
61#define BFAD_CFG_PPORT_DONE 0x00000008
62#define BFAD_HAL_START_DONE 0x00000010
63#define BFAD_PORT_ONLINE 0x00000020
64#define BFAD_RPORT_ONLINE 0x00000040
65
66#define BFAD_PORT_DELETE 0x00000001
67
68/*
69 * BFAD related definition
70 */
71#define SCSI_SCAN_DELAY HZ
72#define BFAD_STOP_TIMEOUT 30
73#define BFAD_SUSPEND_TIMEOUT BFAD_STOP_TIMEOUT
74
75/*
76 * BFAD configuration parameter default values
77 */
78#define BFAD_LUN_QUEUE_DEPTH 32
79#define BFAD_IO_MAX_SGE SG_ALL
80
81#define bfad_isr_t irq_handler_t
82
83#define MAX_MSIX_ENTRY 22
84
85struct bfad_msix_s {
86 struct bfad_s *bfad;
87 struct msix_entry msix;
88};
89
90enum bfad_port_pvb_type {
91 BFAD_PORT_PHYS_BASE = 0,
92 BFAD_PORT_PHYS_VPORT = 1,
93 BFAD_PORT_VF_BASE = 2,
94 BFAD_PORT_VF_VPORT = 3,
95};
96
97/*
98 * PORT data structure
99 */
100struct bfad_port_s {
101 struct list_head list_entry;
102 struct bfad_s *bfad;
103 struct bfa_fcs_port_s *fcs_port;
104 u32 roles;
105 s32 flags;
106 u32 supported_fc4s;
107 u8 ipfc_flags;
108 enum bfad_port_pvb_type pvb_type;
109 struct bfad_im_port_s *im_port; /* IM specific data */
110 struct bfad_tm_port_s *tm_port; /* TM specific data */
111 struct bfad_ipfc_port_s *ipfc_port; /* IPFC specific data */
112};
113
114/*
115 * VPORT data structure
116 */
117struct bfad_vport_s {
118 struct bfad_port_s drv_port;
119 struct bfa_fcs_vport_s fcs_vport;
120 struct completion *comp_del;
121};
122
123/*
124 * VF data structure
125 */
126struct bfad_vf_s {
127 bfa_fcs_vf_t fcs_vf;
128 struct bfad_port_s base_port; /* base port for vf */
129 struct bfad_s *bfad;
130};
131
132struct bfad_cfg_param_s {
133 u32 rport_del_timeout;
134 u32 ioc_queue_depth;
135 u32 lun_queue_depth;
136 u32 io_max_sge;
137 u32 binding_method;
138};
139
140#define BFAD_AEN_MAX_APPS 8
141struct bfad_aen_file_s {
142 struct list_head qe;
143 struct bfad_s *bfad;
144 s32 ri;
145 s32 app_id;
146};
147
148/*
149 * BFAD (PCI function) data structure
150 */
151struct bfad_s {
152 struct list_head list_entry;
153 struct bfa_s bfa;
154 struct bfa_fcs_s bfa_fcs;
155 struct pci_dev *pcidev;
156 const char *pci_name;
157 struct bfa_pcidev_s hal_pcidev;
158 struct bfa_ioc_pci_attr_s pci_attr;
159 unsigned long pci_bar0_map;
160 void __iomem *pci_bar0_kva;
161 struct completion comp;
162 struct completion suspend;
163 struct completion disable_comp;
164 bfa_boolean_t disable_active;
165 struct bfad_port_s pport; /* physical port of the BFAD */
166 struct bfa_meminfo_s meminfo;
167 struct bfa_iocfc_cfg_s ioc_cfg;
168 u32 inst_no; /* BFAD instance number */
169 u32 bfad_flags;
170 spinlock_t bfad_lock;
171 struct bfad_cfg_param_s cfg_data;
172 struct bfad_msix_s msix_tab[MAX_MSIX_ENTRY];
173 int nvec;
174 char adapter_name[BFA_ADAPTER_SYM_NAME_LEN];
175 char port_name[BFA_ADAPTER_SYM_NAME_LEN];
176 struct timer_list hal_tmo;
177 unsigned long hs_start;
178 struct bfad_im_s *im; /* IM specific data */
179 struct bfad_tm_s *tm; /* TM specific data */
180 struct bfad_ipfc_s *ipfc; /* IPFC specific data */
181 struct bfa_log_mod_s log_data;
182 struct bfa_trc_mod_s *trcmod;
183 struct bfa_log_mod_s *logmod;
184 struct bfa_aen_s *aen;
185 struct bfa_aen_s aen_buf;
186 struct bfad_aen_file_s file_buf[BFAD_AEN_MAX_APPS];
187 struct list_head file_q;
188 struct list_head file_free_q;
189 struct bfa_plog_s plog_buf;
190 int ref_count;
191 bfa_boolean_t ipfc_enabled;
192 struct fc_host_statistics link_stats;
193
194 struct kobject *bfa_kobj;
195 struct kobject *ioc_kobj;
196 struct kobject *pport_kobj;
197 struct kobject *lport_kobj;
198};
199
200/*
201 * RPORT data structure
202 */
203struct bfad_rport_s {
204 struct bfa_fcs_rport_s fcs_rport;
205};
206
207struct bfad_buf_info {
208 void *virt;
209 dma_addr_t phys;
210 u32 size;
211};
212
213struct bfad_fcxp {
214 struct bfad_port_s *port;
215 struct bfa_rport_s *bfa_rport;
216 bfa_status_t req_status;
217 u16 tag;
218 u16 rsp_len;
219 u16 rsp_maxlen;
220 u8 use_ireqbuf;
221 u8 use_irspbuf;
222 u32 num_req_sgles;
223 u32 num_rsp_sgles;
224 struct fchs_s fchs;
225 void *reqbuf_info;
226 void *rspbuf_info;
227 struct bfa_sge_s *req_sge;
228 struct bfa_sge_s *rsp_sge;
229 fcxp_send_cb_t send_cbfn;
230 void *send_cbarg;
231 void *bfa_fcxp;
232 struct completion comp;
233};
234
235struct bfad_hal_comp {
236 bfa_status_t status;
237 struct completion comp;
238};
239
240/*
241 * Macro to obtain the immediate lower power
242 * of two for the integer.
243 */
244#define nextLowerInt(x) \
245do { \
246 int j; \
247 (*x)--; \
248 for (j = 1; j < (sizeof(int) * 8); j <<= 1) \
249 (*x) = (*x) | (*x) >> j; \
250 (*x)++; \
251 (*x) = (*x) >> 1; \
252} while (0)
253
254
255bfa_status_t bfad_vport_create(struct bfad_s *bfad, u16 vf_id,
256 struct bfa_port_cfg_s *port_cfg);
257bfa_status_t bfad_vf_create(struct bfad_s *bfad, u16 vf_id,
258 struct bfa_port_cfg_s *port_cfg);
259bfa_status_t bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role);
260bfa_status_t bfad_drv_init(struct bfad_s *bfad);
261void bfad_drv_start(struct bfad_s *bfad);
262void bfad_uncfg_pport(struct bfad_s *bfad);
263void bfad_drv_stop(struct bfad_s *bfad);
264void bfad_remove_intr(struct bfad_s *bfad);
265void bfad_hal_mem_release(struct bfad_s *bfad);
266void bfad_hcb_comp(void *arg, bfa_status_t status);
267
268int bfad_setup_intr(struct bfad_s *bfad);
269void bfad_remove_intr(struct bfad_s *bfad);
270
271void bfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg);
272bfa_status_t bfad_hal_mem_alloc(struct bfad_s *bfad);
273void bfad_bfa_tmo(unsigned long data);
274void bfad_init_timer(struct bfad_s *bfad);
275int bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad);
276void bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad);
277void bfad_fcs_port_cfg(struct bfad_s *bfad);
278void bfad_drv_uninit(struct bfad_s *bfad);
279void bfad_drv_log_level_set(struct bfad_s *bfad);
280bfa_status_t bfad_fc4_module_init(void);
281void bfad_fc4_module_exit(void);
282
283void bfad_pci_remove(struct pci_dev *pdev);
284int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid);
285void bfad_os_rport_online_wait(struct bfad_s *bfad);
286int bfad_os_get_linkup_delay(struct bfad_s *bfad);
287int bfad_install_msix_handler(struct bfad_s *bfad);
288
289extern struct idr bfad_im_port_index;
290extern struct list_head bfad_list;
291extern int bfa_lun_queue_depth;
292extern int bfad_supported_fc4s;
293extern int bfa_linkup_delay;
294
295#endif /* __BFAD_DRV_H__ */
diff --git a/drivers/scsi/bfa/bfad_fwimg.c b/drivers/scsi/bfa/bfad_fwimg.c
new file mode 100644
index 000000000000..b2f6949bc8d3
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_fwimg.c
@@ -0,0 +1,95 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfad_fwimg.c Linux driver PCI interface module.
20 */
21#include <bfa_os_inc.h>
22#include <bfad_drv.h>
23#include <bfad_im_compat.h>
24#include <defs/bfa_defs_version.h>
25#include <linux/errno.h>
26#include <linux/sched.h>
27#include <linux/init.h>
28#include <linux/fs.h>
29#include <asm/uaccess.h>
30#include <asm/fcntl.h>
31#include <linux/pci.h>
32#include <linux/firmware.h>
33#include <bfa_fwimg_priv.h>
34#include <bfa.h>
35
36u32 bfi_image_ct_size;
37u32 bfi_image_cb_size;
38u32 *bfi_image_ct;
39u32 *bfi_image_cb;
40
41
42#define BFAD_FW_FILE_CT "ctfw.bin"
43#define BFAD_FW_FILE_CB "cbfw.bin"
44
45u32 *
46bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
47 u32 *bfi_image_size, char *fw_name)
48{
49 const struct firmware *fw;
50
51 if (request_firmware(&fw, fw_name, &pdev->dev)) {
52 printk(KERN_ALERT "Can't locate firmware %s\n", fw_name);
53 goto error;
54 }
55
56 *bfi_image = vmalloc(fw->size);
57 if (NULL == *bfi_image) {
58 printk(KERN_ALERT "Fail to allocate buffer for fw image "
59 "size=%x!\n", (u32) fw->size);
60 goto error;
61 }
62
63 memcpy(*bfi_image, fw->data, fw->size);
64 *bfi_image_size = fw->size/sizeof(u32);
65
66 return(*bfi_image);
67
68error:
69 return(NULL);
70}
71
72u32 *
73bfad_get_firmware_buf(struct pci_dev *pdev)
74{
75 if (pdev->device == BFA_PCI_DEVICE_ID_CT) {
76 if (bfi_image_ct_size == 0)
77 bfad_read_firmware(pdev, &bfi_image_ct,
78 &bfi_image_ct_size, BFAD_FW_FILE_CT);
79 return(bfi_image_ct);
80 } else {
81 if (bfi_image_cb_size == 0)
82 bfad_read_firmware(pdev, &bfi_image_cb,
83 &bfi_image_cb_size, BFAD_FW_FILE_CB);
84 return(bfi_image_cb);
85 }
86}
87
88u32 *
89bfi_image_ct_get_chunk(u32 off)
90{ return (u32 *)(bfi_image_ct + off); }
91
92u32 *
93bfi_image_cb_get_chunk(u32 off)
94{ return (u32 *)(bfi_image_cb + off); }
95
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
new file mode 100644
index 000000000000..158c99243c08
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -0,0 +1,1230 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfad_im.c Linux driver IM module.
20 */
21
22#include "bfad_drv.h"
23#include "bfad_im.h"
24#include "bfad_trcmod.h"
25#include "bfa_cb_ioim_macros.h"
26#include <fcb/bfa_fcb_fcpim.h>
27
28BFA_TRC_FILE(LDRV, IM);
29
30DEFINE_IDR(bfad_im_port_index);
31struct scsi_transport_template *bfad_im_scsi_transport_template;
32static void bfad_im_itnim_work_handler(struct work_struct *work);
33static int bfad_im_queuecommand(struct scsi_cmnd *cmnd,
34 void (*done)(struct scsi_cmnd *));
35static int bfad_im_slave_alloc(struct scsi_device *sdev);
36
37void
38bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
39 enum bfi_ioim_status io_status, u8 scsi_status,
40 int sns_len, u8 *sns_info, s32 residue)
41{
42 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
43 struct bfad_s *bfad = drv;
44 struct bfad_itnim_data_s *itnim_data;
45 struct bfad_itnim_s *itnim;
46
47 switch (io_status) {
48 case BFI_IOIM_STS_OK:
49 bfa_trc(bfad, scsi_status);
50 cmnd->result = ScsiResult(DID_OK, scsi_status);
51 scsi_set_resid(cmnd, 0);
52
53 if (sns_len > 0) {
54 bfa_trc(bfad, sns_len);
55 if (sns_len > SCSI_SENSE_BUFFERSIZE)
56 sns_len = SCSI_SENSE_BUFFERSIZE;
57 memcpy(cmnd->sense_buffer, sns_info, sns_len);
58 }
59 if (residue > 0)
60 scsi_set_resid(cmnd, residue);
61 break;
62
63 case BFI_IOIM_STS_ABORTED:
64 case BFI_IOIM_STS_TIMEDOUT:
65 case BFI_IOIM_STS_PATHTOV:
66 default:
67 cmnd->result = ScsiResult(DID_ERROR, 0);
68 }
69
70 /* Unmap DMA, if host is NULL, it means a scsi passthru cmd */
71 if (cmnd->device->host != NULL)
72 scsi_dma_unmap(cmnd);
73
74 cmnd->host_scribble = NULL;
75 bfa_trc(bfad, cmnd->result);
76
77 itnim_data = cmnd->device->hostdata;
78 if (itnim_data) {
79 itnim = itnim_data->itnim;
80 if (!cmnd->result && itnim &&
81 (bfa_lun_queue_depth > cmnd->device->queue_depth)) {
82 /* Queue depth adjustment for good status completion */
83 bfad_os_ramp_up_qdepth(itnim, cmnd->device);
84 } else if (cmnd->result == SAM_STAT_TASK_SET_FULL && itnim) {
85 /* qfull handling */
86 bfad_os_handle_qfull(itnim, cmnd->device);
87 }
88 }
89
90 cmnd->scsi_done(cmnd);
91}
92
93void
94bfa_cb_ioim_good_comp(void *drv, struct bfad_ioim_s *dio)
95{
96 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
97 struct bfad_itnim_data_s *itnim_data;
98 struct bfad_itnim_s *itnim;
99
100 cmnd->result = ScsiResult(DID_OK, SCSI_STATUS_GOOD);
101
102 /* Unmap DMA, if host is NULL, it means a scsi passthru cmd */
103 if (cmnd->device->host != NULL)
104 scsi_dma_unmap(cmnd);
105
106 cmnd->host_scribble = NULL;
107
108 /* Queue depth adjustment */
109 if (bfa_lun_queue_depth > cmnd->device->queue_depth) {
110 itnim_data = cmnd->device->hostdata;
111 if (itnim_data) {
112 itnim = itnim_data->itnim;
113 if (itnim)
114 bfad_os_ramp_up_qdepth(itnim, cmnd->device);
115 }
116 }
117
118 cmnd->scsi_done(cmnd);
119}
120
121void
122bfa_cb_ioim_abort(void *drv, struct bfad_ioim_s *dio)
123{
124 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
125 struct bfad_s *bfad = drv;
126
127 cmnd->result = ScsiResult(DID_ERROR, 0);
128
129 /* Unmap DMA, if host is NULL, it means a scsi passthru cmd */
130 if (cmnd->device->host != NULL)
131 scsi_dma_unmap(cmnd);
132
133 bfa_trc(bfad, cmnd->result);
134 cmnd->host_scribble = NULL;
135}
136
137void
138bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
139 enum bfi_tskim_status tsk_status)
140{
141 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dtsk;
142 wait_queue_head_t *wq;
143
144 cmnd->SCp.Status |= tsk_status << 1;
145 set_bit(IO_DONE_BIT, (unsigned long *)&cmnd->SCp.Status);
146 wq = (wait_queue_head_t *) cmnd->SCp.ptr;
147 cmnd->SCp.ptr = NULL;
148
149 if (wq)
150 wake_up(wq);
151}
152
153void
154bfa_cb_ioim_resfree(void *drv)
155{
156}
157
158/**
159 * Scsi_Host_template SCSI host template
160 */
161/**
162 * Scsi_Host template entry, returns BFAD PCI info.
163 */
164static const char *
165bfad_im_info(struct Scsi_Host *shost)
166{
167 static char bfa_buf[256];
168 struct bfad_im_port_s *im_port =
169 (struct bfad_im_port_s *) shost->hostdata[0];
170 struct bfa_ioc_attr_s ioc_attr;
171 struct bfad_s *bfad = im_port->bfad;
172
173 memset(&ioc_attr, 0, sizeof(ioc_attr));
174 bfa_get_attr(&bfad->bfa, &ioc_attr);
175
176 memset(bfa_buf, 0, sizeof(bfa_buf));
177 snprintf(bfa_buf, sizeof(bfa_buf),
178 "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s",
179 ioc_attr.adapter_attr.model, bfad->pci_name,
180 BFAD_DRIVER_VERSION);
181 return bfa_buf;
182}
183
184/**
185 * Scsi_Host template entry, aborts the specified SCSI command.
186 *
187 * Returns: SUCCESS or FAILED.
188 */
189static int
190bfad_im_abort_handler(struct scsi_cmnd *cmnd)
191{
192 struct Scsi_Host *shost = cmnd->device->host;
193 struct bfad_im_port_s *im_port =
194 (struct bfad_im_port_s *) shost->hostdata[0];
195 struct bfad_s *bfad = im_port->bfad;
196 struct bfa_ioim_s *hal_io;
197 unsigned long flags;
198 u32 timeout;
199 int rc = FAILED;
200
201 spin_lock_irqsave(&bfad->bfad_lock, flags);
202 hal_io = (struct bfa_ioim_s *) cmnd->host_scribble;
203 if (!hal_io) {
204 /* IO has been completed, retrun success */
205 rc = SUCCESS;
206 goto out;
207 }
208 if (hal_io->dio != (struct bfad_ioim_s *) cmnd) {
209 rc = FAILED;
210 goto out;
211 }
212
213 bfa_trc(bfad, hal_io->iotag);
214 bfa_log(bfad->logmod, BFA_LOG_LINUX_SCSI_ABORT,
215 im_port->shost->host_no, cmnd, hal_io->iotag);
216 bfa_ioim_abort(hal_io);
217 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
218
219 /* Need to wait until the command get aborted */
220 timeout = 10;
221 while ((struct bfa_ioim_s *) cmnd->host_scribble == hal_io) {
222 set_current_state(TASK_UNINTERRUPTIBLE);
223 schedule_timeout(timeout);
224 if (timeout < 4 * HZ)
225 timeout *= 2;
226 }
227
228 cmnd->scsi_done(cmnd);
229 bfa_trc(bfad, hal_io->iotag);
230 bfa_log(bfad->logmod, BFA_LOG_LINUX_SCSI_ABORT_COMP,
231 im_port->shost->host_no, cmnd, hal_io->iotag);
232 return SUCCESS;
233out:
234 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
235 return rc;
236}
237
238static bfa_status_t
239bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd,
240 struct bfad_itnim_s *itnim)
241{
242 struct bfa_tskim_s *tskim;
243 struct bfa_itnim_s *bfa_itnim;
244 bfa_status_t rc = BFA_STATUS_OK;
245
246 bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
247 tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd);
248 if (!tskim) {
249 BFA_DEV_PRINTF(bfad, BFA_ERR,
250 "target reset, fail to allocate tskim\n");
251 rc = BFA_STATUS_FAILED;
252 goto out;
253 }
254
255 /*
256 * Set host_scribble to NULL to avoid aborting a task command if
257 * happens.
258 */
259 cmnd->host_scribble = NULL;
260 cmnd->SCp.Status = 0;
261 bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
262 bfa_tskim_start(tskim, bfa_itnim, (lun_t)0,
263 FCP_TM_TARGET_RESET, BFAD_TARGET_RESET_TMO);
264out:
265 return rc;
266}
267
268/**
269 * Scsi_Host template entry, resets a LUN and abort its all commands.
270 *
271 * Returns: SUCCESS or FAILED.
272 *
273 */
274static int
275bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
276{
277 struct Scsi_Host *shost = cmnd->device->host;
278 struct bfad_im_port_s *im_port =
279 (struct bfad_im_port_s *) shost->hostdata[0];
280 struct bfad_itnim_data_s *itnim_data = cmnd->device->hostdata;
281 struct bfad_s *bfad = im_port->bfad;
282 struct bfa_tskim_s *tskim;
283 struct bfad_itnim_s *itnim;
284 struct bfa_itnim_s *bfa_itnim;
285 DECLARE_WAIT_QUEUE_HEAD(wq);
286 int rc = SUCCESS;
287 unsigned long flags;
288 enum bfi_tskim_status task_status;
289
290 spin_lock_irqsave(&bfad->bfad_lock, flags);
291 itnim = itnim_data->itnim;
292 if (!itnim) {
293 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
294 rc = FAILED;
295 goto out;
296 }
297
298 tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd);
299 if (!tskim) {
300 BFA_DEV_PRINTF(bfad, BFA_ERR,
301 "LUN reset, fail to allocate tskim");
302 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
303 rc = FAILED;
304 goto out;
305 }
306
307 /**
308 * Set host_scribble to NULL to avoid aborting a task command
309 * if happens.
310 */
311 cmnd->host_scribble = NULL;
312 cmnd->SCp.ptr = (char *)&wq;
313 cmnd->SCp.Status = 0;
314 bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
315 bfa_tskim_start(tskim, bfa_itnim,
316 bfad_int_to_lun(cmnd->device->lun),
317 FCP_TM_LUN_RESET, BFAD_LUN_RESET_TMO);
318 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
319
320 wait_event(wq, test_bit(IO_DONE_BIT,
321 (unsigned long *)&cmnd->SCp.Status));
322
323 task_status = cmnd->SCp.Status >> 1;
324 if (task_status != BFI_TSKIM_STS_OK) {
325 BFA_DEV_PRINTF(bfad, BFA_ERR, "LUN reset failure, status: %d\n",
326 task_status);
327 rc = FAILED;
328 }
329
330out:
331 return rc;
332}
333
334/**
335 * Scsi_Host template entry, resets the bus and abort all commands.
336 */
337static int
338bfad_im_reset_bus_handler(struct scsi_cmnd *cmnd)
339{
340 struct Scsi_Host *shost = cmnd->device->host;
341 struct bfad_im_port_s *im_port =
342 (struct bfad_im_port_s *) shost->hostdata[0];
343 struct bfad_s *bfad = im_port->bfad;
344 struct bfad_itnim_s *itnim;
345 unsigned long flags;
346 u32 i, rc, err_cnt = 0;
347 DECLARE_WAIT_QUEUE_HEAD(wq);
348 enum bfi_tskim_status task_status;
349
350 spin_lock_irqsave(&bfad->bfad_lock, flags);
351 for (i = 0; i < MAX_FCP_TARGET; i++) {
352 itnim = bfad_os_get_itnim(im_port, i);
353 if (itnim) {
354 cmnd->SCp.ptr = (char *)&wq;
355 rc = bfad_im_target_reset_send(bfad, cmnd, itnim);
356 if (rc != BFA_STATUS_OK) {
357 err_cnt++;
358 continue;
359 }
360
361 /* wait target reset to complete */
362 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
363 wait_event(wq, test_bit(IO_DONE_BIT,
364 (unsigned long *)&cmnd->SCp.Status));
365 spin_lock_irqsave(&bfad->bfad_lock, flags);
366
367 task_status = cmnd->SCp.Status >> 1;
368 if (task_status != BFI_TSKIM_STS_OK) {
369 BFA_DEV_PRINTF(bfad, BFA_ERR,
370 "target reset failure,"
371 " status: %d\n", task_status);
372 err_cnt++;
373 }
374 }
375 }
376 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
377
378 if (err_cnt)
379 return FAILED;
380
381 return SUCCESS;
382}
383
384/**
385 * Scsi_Host template entry slave_destroy.
386 */
387static void
388bfad_im_slave_destroy(struct scsi_device *sdev)
389{
390 sdev->hostdata = NULL;
391 return;
392}
393
394/**
395 * BFA FCS itnim callbacks
396 */
397
398/**
399 * BFA FCS itnim alloc callback, after successful PRLI
400 * Context: Interrupt
401 */
402void
403bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim,
404 struct bfad_itnim_s **itnim_drv)
405{
406 *itnim_drv = kzalloc(sizeof(struct bfad_itnim_s), GFP_ATOMIC);
407 if (*itnim_drv == NULL)
408 return;
409
410 (*itnim_drv)->im = bfad->im;
411 *itnim = &(*itnim_drv)->fcs_itnim;
412 (*itnim_drv)->state = ITNIM_STATE_NONE;
413
414 /*
415 * Initiaze the itnim_work
416 */
417 INIT_WORK(&(*itnim_drv)->itnim_work, bfad_im_itnim_work_handler);
418 bfad->bfad_flags |= BFAD_RPORT_ONLINE;
419}
420
421/**
422 * BFA FCS itnim free callback.
423 * Context: Interrupt. bfad_lock is held
424 */
425void
426bfa_fcb_itnim_free(struct bfad_s *bfad, struct bfad_itnim_s *itnim_drv)
427{
428 struct bfad_port_s *port;
429 wwn_t wwpn;
430 u32 fcid;
431 char wwpn_str[32], fcid_str[16];
432
433 /* online to free state transtion should not happen */
434 bfa_assert(itnim_drv->state != ITNIM_STATE_ONLINE);
435
436 itnim_drv->queue_work = 1;
437 /* offline request is not yet done, use the same request to free */
438 if (itnim_drv->state == ITNIM_STATE_OFFLINE_PENDING)
439 itnim_drv->queue_work = 0;
440
441 itnim_drv->state = ITNIM_STATE_FREE;
442 port = bfa_fcs_itnim_get_drvport(&itnim_drv->fcs_itnim);
443 itnim_drv->im_port = port->im_port;
444 wwpn = bfa_fcs_itnim_get_pwwn(&itnim_drv->fcs_itnim);
445 fcid = bfa_fcs_itnim_get_fcid(&itnim_drv->fcs_itnim);
446 wwn2str(wwpn_str, wwpn);
447 fcid2str(fcid_str, fcid);
448 bfa_log(bfad->logmod, BFA_LOG_LINUX_ITNIM_FREE,
449 port->im_port->shost->host_no,
450 fcid_str, wwpn_str);
451 bfad_os_itnim_process(itnim_drv);
452}
453
454/**
455 * BFA FCS itnim online callback.
456 * Context: Interrupt. bfad_lock is held
457 */
458void
459bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv)
460{
461 struct bfad_port_s *port;
462
463 itnim_drv->bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim_drv->fcs_itnim);
464 port = bfa_fcs_itnim_get_drvport(&itnim_drv->fcs_itnim);
465 itnim_drv->state = ITNIM_STATE_ONLINE;
466 itnim_drv->queue_work = 1;
467 itnim_drv->im_port = port->im_port;
468 bfad_os_itnim_process(itnim_drv);
469}
470
471/**
472 * BFA FCS itnim offline callback.
473 * Context: Interrupt. bfad_lock is held
474 */
475void
476bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv)
477{
478 struct bfad_port_s *port;
479 struct bfad_s *bfad;
480
481 port = bfa_fcs_itnim_get_drvport(&itnim_drv->fcs_itnim);
482 bfad = port->bfad;
483 if ((bfad->pport.flags & BFAD_PORT_DELETE) ||
484 (port->flags & BFAD_PORT_DELETE)) {
485 itnim_drv->state = ITNIM_STATE_OFFLINE;
486 return;
487 }
488 itnim_drv->im_port = port->im_port;
489 itnim_drv->state = ITNIM_STATE_OFFLINE_PENDING;
490 itnim_drv->queue_work = 1;
491 bfad_os_itnim_process(itnim_drv);
492}
493
494/**
495 * BFA FCS itnim timeout callback.
496 * Context: Interrupt. bfad_lock is held
497 */
498void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim)
499{
500 itnim->state = ITNIM_STATE_TIMEOUT;
501}
502
503/**
504 * Path TOV processing begin notification -- dummy for linux
505 */
506void
507bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim)
508{
509}
510
511
512
513/**
514 * Allocate a Scsi_Host for a port.
515 */
516int
517bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
518{
519 int error = 1;
520
521 if (!idr_pre_get(&bfad_im_port_index, GFP_KERNEL)) {
522 printk(KERN_WARNING "idr_pre_get failure\n");
523 goto out;
524 }
525
526 error = idr_get_new(&bfad_im_port_index, im_port,
527 &im_port->idr_id);
528 if (error) {
529 printk(KERN_WARNING "idr_get_new failure\n");
530 goto out;
531 }
532
533 im_port->shost = bfad_os_scsi_host_alloc(im_port, bfad);
534 if (!im_port->shost) {
535 error = 1;
536 goto out_free_idr;
537 }
538
539 im_port->shost->hostdata[0] = (unsigned long)im_port;
540 im_port->shost->unique_id = im_port->idr_id;
541 im_port->shost->this_id = -1;
542 im_port->shost->max_id = MAX_FCP_TARGET;
543 im_port->shost->max_lun = MAX_FCP_LUN;
544 im_port->shost->max_cmd_len = 16;
545 im_port->shost->can_queue = bfad->cfg_data.ioc_queue_depth;
546 im_port->shost->transportt = bfad_im_scsi_transport_template;
547
548 error = bfad_os_scsi_add_host(im_port->shost, im_port, bfad);
549 if (error) {
550 printk(KERN_WARNING "bfad_os_scsi_add_host failure %d\n",
551 error);
552 goto out_fc_rel;
553 }
554
555 /* setup host fixed attribute if the lk supports */
556 bfad_os_fc_host_init(im_port);
557
558 return 0;
559
560out_fc_rel:
561 scsi_host_put(im_port->shost);
562out_free_idr:
563 idr_remove(&bfad_im_port_index, im_port->idr_id);
564out:
565 return error;
566}
567
568void
569bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
570{
571 unsigned long flags;
572
573 bfa_trc(bfad, bfad->inst_no);
574 bfa_log(bfad->logmod, BFA_LOG_LINUX_SCSI_HOST_FREE,
575 im_port->shost->host_no);
576
577 fc_remove_host(im_port->shost);
578
579 scsi_remove_host(im_port->shost);
580 scsi_host_put(im_port->shost);
581
582 spin_lock_irqsave(&bfad->bfad_lock, flags);
583 idr_remove(&bfad_im_port_index, im_port->idr_id);
584 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
585}
586
587static void
588bfad_im_port_delete_handler(struct work_struct *work)
589{
590 struct bfad_im_port_s *im_port =
591 container_of(work, struct bfad_im_port_s, port_delete_work);
592
593 bfad_im_scsi_host_free(im_port->bfad, im_port);
594 bfad_im_port_clean(im_port);
595 kfree(im_port);
596}
597
598bfa_status_t
599bfad_im_port_new(struct bfad_s *bfad, struct bfad_port_s *port)
600{
601 int rc = BFA_STATUS_OK;
602 struct bfad_im_port_s *im_port;
603
604 im_port = kzalloc(sizeof(struct bfad_im_port_s), GFP_ATOMIC);
605 if (im_port == NULL) {
606 rc = BFA_STATUS_ENOMEM;
607 goto ext;
608 }
609 port->im_port = im_port;
610 im_port->port = port;
611 im_port->bfad = bfad;
612
613 INIT_WORK(&im_port->port_delete_work, bfad_im_port_delete_handler);
614 INIT_LIST_HEAD(&im_port->itnim_mapped_list);
615 INIT_LIST_HEAD(&im_port->binding_list);
616
617ext:
618 return rc;
619}
620
621void
622bfad_im_port_delete(struct bfad_s *bfad, struct bfad_port_s *port)
623{
624 struct bfad_im_port_s *im_port = port->im_port;
625
626 queue_work(bfad->im->drv_workq,
627 &im_port->port_delete_work);
628}
629
630void
631bfad_im_port_clean(struct bfad_im_port_s *im_port)
632{
633 struct bfad_fcp_binding *bp, *bp_new;
634 unsigned long flags;
635 struct bfad_s *bfad = im_port->bfad;
636
637 spin_lock_irqsave(&bfad->bfad_lock, flags);
638 list_for_each_entry_safe(bp, bp_new, &im_port->binding_list,
639 list_entry) {
640 list_del(&bp->list_entry);
641 kfree(bp);
642 }
643
644 /* the itnim_mapped_list must be empty at this time */
645 bfa_assert(list_empty(&im_port->itnim_mapped_list));
646
647 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
648}
649
650void
651bfad_im_port_online(struct bfad_s *bfad, struct bfad_port_s *port)
652{
653}
654
655void
656bfad_im_port_offline(struct bfad_s *bfad, struct bfad_port_s *port)
657{
658}
659
660bfa_status_t
661bfad_im_probe(struct bfad_s *bfad)
662{
663 struct bfad_im_s *im;
664 bfa_status_t rc = BFA_STATUS_OK;
665
666 im = kzalloc(sizeof(struct bfad_im_s), GFP_KERNEL);
667 if (im == NULL) {
668 rc = BFA_STATUS_ENOMEM;
669 goto ext;
670 }
671
672 bfad->im = im;
673 im->bfad = bfad;
674
675 if (bfad_os_thread_workq(bfad) != BFA_STATUS_OK) {
676 kfree(im);
677 rc = BFA_STATUS_FAILED;
678 }
679
680ext:
681 return rc;
682}
683
684void
685bfad_im_probe_undo(struct bfad_s *bfad)
686{
687 if (bfad->im) {
688 bfad_os_destroy_workq(bfad->im);
689 kfree(bfad->im);
690 bfad->im = NULL;
691 }
692}
693
694
695
696
697int
698bfad_os_scsi_add_host(struct Scsi_Host *shost, struct bfad_im_port_s *im_port,
699 struct bfad_s *bfad)
700{
701 struct device *dev;
702
703 if (im_port->port->pvb_type == BFAD_PORT_PHYS_BASE)
704 dev = &bfad->pcidev->dev;
705 else
706 dev = &bfad->pport.im_port->shost->shost_gendev;
707
708 return scsi_add_host(shost, dev);
709}
710
711struct Scsi_Host *
712bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad)
713{
714 struct scsi_host_template *sht;
715
716 if (im_port->port->pvb_type == BFAD_PORT_PHYS_BASE)
717 sht = &bfad_im_scsi_host_template;
718 else
719 sht = &bfad_im_vport_template;
720
721 sht->sg_tablesize = bfad->cfg_data.io_max_sge;
722
723 return scsi_host_alloc(sht, sizeof(unsigned long));
724}
725
726void
727bfad_os_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
728{
729 flush_workqueue(bfad->im->drv_workq);
730 bfad_im_scsi_host_free(im_port->bfad, im_port);
731 bfad_im_port_clean(im_port);
732 kfree(im_port);
733}
734
735void
736bfad_os_destroy_workq(struct bfad_im_s *im)
737{
738 if (im && im->drv_workq) {
739 destroy_workqueue(im->drv_workq);
740 im->drv_workq = NULL;
741 }
742}
743
744bfa_status_t
745bfad_os_thread_workq(struct bfad_s *bfad)
746{
747 struct bfad_im_s *im = bfad->im;
748
749 bfa_trc(bfad, 0);
750 snprintf(im->drv_workq_name, BFAD_KOBJ_NAME_LEN, "bfad_wq_%d",
751 bfad->inst_no);
752 im->drv_workq = create_singlethread_workqueue(im->drv_workq_name);
753 if (!im->drv_workq)
754 return BFA_STATUS_FAILED;
755
756 return BFA_STATUS_OK;
757}
758
759/**
760 * Scsi_Host template entry.
761 *
762 * Description:
763 * OS entry point to adjust the queue_depths on a per-device basis.
764 * Called once per device during the bus scan.
765 * Return non-zero if fails.
766 */
767static int
768bfad_im_slave_configure(struct scsi_device *sdev)
769{
770 if (sdev->tagged_supported)
771 scsi_activate_tcq(sdev, bfa_lun_queue_depth);
772 else
773 scsi_deactivate_tcq(sdev, bfa_lun_queue_depth);
774
775 return 0;
776}
777
778struct scsi_host_template bfad_im_scsi_host_template = {
779 .module = THIS_MODULE,
780 .name = BFAD_DRIVER_NAME,
781 .info = bfad_im_info,
782 .queuecommand = bfad_im_queuecommand,
783 .eh_abort_handler = bfad_im_abort_handler,
784 .eh_device_reset_handler = bfad_im_reset_lun_handler,
785 .eh_bus_reset_handler = bfad_im_reset_bus_handler,
786
787 .slave_alloc = bfad_im_slave_alloc,
788 .slave_configure = bfad_im_slave_configure,
789 .slave_destroy = bfad_im_slave_destroy,
790
791 .this_id = -1,
792 .sg_tablesize = BFAD_IO_MAX_SGE,
793 .cmd_per_lun = 3,
794 .use_clustering = ENABLE_CLUSTERING,
795 .shost_attrs = bfad_im_host_attrs,
796 .max_sectors = 0xFFFF,
797};
798
799struct scsi_host_template bfad_im_vport_template = {
800 .module = THIS_MODULE,
801 .name = BFAD_DRIVER_NAME,
802 .info = bfad_im_info,
803 .queuecommand = bfad_im_queuecommand,
804 .eh_abort_handler = bfad_im_abort_handler,
805 .eh_device_reset_handler = bfad_im_reset_lun_handler,
806 .eh_bus_reset_handler = bfad_im_reset_bus_handler,
807
808 .slave_alloc = bfad_im_slave_alloc,
809 .slave_configure = bfad_im_slave_configure,
810 .slave_destroy = bfad_im_slave_destroy,
811
812 .this_id = -1,
813 .sg_tablesize = BFAD_IO_MAX_SGE,
814 .cmd_per_lun = 3,
815 .use_clustering = ENABLE_CLUSTERING,
816 .shost_attrs = bfad_im_vport_attrs,
817 .max_sectors = 0xFFFF,
818};
819
820void
821bfad_im_probe_post(struct bfad_im_s *im)
822{
823 flush_workqueue(im->drv_workq);
824}
825
826bfa_status_t
827bfad_im_module_init(void)
828{
829 bfad_im_scsi_transport_template =
830 fc_attach_transport(&bfad_im_fc_function_template);
831 if (!bfad_im_scsi_transport_template)
832 return BFA_STATUS_ENOMEM;
833
834 return BFA_STATUS_OK;
835}
836
837void
838bfad_im_module_exit(void)
839{
840 if (bfad_im_scsi_transport_template)
841 fc_release_transport(bfad_im_scsi_transport_template);
842}
843
844void
845bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv)
846{
847 struct bfad_im_s *im = itnim_drv->im;
848
849 if (itnim_drv->queue_work)
850 queue_work(im->drv_workq, &itnim_drv->itnim_work);
851}
852
853void
854bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
855{
856 struct scsi_device *tmp_sdev;
857
858 if (((jiffies - itnim->last_ramp_up_time) >
859 BFA_QUEUE_FULL_RAMP_UP_TIME * HZ) &&
860 ((jiffies - itnim->last_queue_full_time) >
861 BFA_QUEUE_FULL_RAMP_UP_TIME * HZ)) {
862 shost_for_each_device(tmp_sdev, sdev->host) {
863 if (bfa_lun_queue_depth > tmp_sdev->queue_depth) {
864 if (tmp_sdev->id != sdev->id)
865 continue;
866 if (tmp_sdev->ordered_tags)
867 scsi_adjust_queue_depth(tmp_sdev,
868 MSG_ORDERED_TAG,
869 tmp_sdev->queue_depth + 1);
870 else
871 scsi_adjust_queue_depth(tmp_sdev,
872 MSG_SIMPLE_TAG,
873 tmp_sdev->queue_depth + 1);
874
875 itnim->last_ramp_up_time = jiffies;
876 }
877 }
878 }
879}
880
881void
882bfad_os_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
883{
884 struct scsi_device *tmp_sdev;
885
886 itnim->last_queue_full_time = jiffies;
887
888 shost_for_each_device(tmp_sdev, sdev->host) {
889 if (tmp_sdev->id != sdev->id)
890 continue;
891 scsi_track_queue_full(tmp_sdev, tmp_sdev->queue_depth - 1);
892 }
893}
894
895
896
897
898struct bfad_itnim_s *
899bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id)
900{
901 struct bfad_itnim_s *itnim = NULL;
902
903 /* Search the mapped list for this target ID */
904 list_for_each_entry(itnim, &im_port->itnim_mapped_list, list_entry) {
905 if (id == itnim->scsi_tgt_id)
906 return itnim;
907 }
908
909 return NULL;
910}
911
912/**
913 * Scsi_Host template entry slave_alloc
914 */
915static int
916bfad_im_slave_alloc(struct scsi_device *sdev)
917{
918 struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
919
920 if (!rport || fc_remote_port_chkready(rport))
921 return -ENXIO;
922
923 sdev->hostdata = rport->dd_data;
924
925 return 0;
926}
927
928void
929bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
930{
931 struct Scsi_Host *host = im_port->shost;
932 struct bfad_s *bfad = im_port->bfad;
933 struct bfad_port_s *port = im_port->port;
934 union attr {
935 struct bfa_pport_attr_s pattr;
936 struct bfa_ioc_attr_s ioc_attr;
937 } attr;
938
939 fc_host_node_name(host) =
940 bfa_os_htonll((bfa_fcs_port_get_nwwn(port->fcs_port)));
941 fc_host_port_name(host) =
942 bfa_os_htonll((bfa_fcs_port_get_pwwn(port->fcs_port)));
943
944 fc_host_supported_classes(host) = FC_COS_CLASS3;
945
946 memset(fc_host_supported_fc4s(host), 0,
947 sizeof(fc_host_supported_fc4s(host)));
948 if (bfad_supported_fc4s & (BFA_PORT_ROLE_FCP_IM | BFA_PORT_ROLE_FCP_TM))
949 /* For FCP type 0x08 */
950 fc_host_supported_fc4s(host)[2] = 1;
951 if (bfad_supported_fc4s | BFA_PORT_ROLE_FCP_IPFC)
952 /* For LLC/SNAP type 0x05 */
953 fc_host_supported_fc4s(host)[3] = 0x20;
954 /* For fibre channel services type 0x20 */
955 fc_host_supported_fc4s(host)[7] = 1;
956
957 memset(&attr.ioc_attr, 0, sizeof(attr.ioc_attr));
958 bfa_get_attr(&bfad->bfa, &attr.ioc_attr);
959 sprintf(fc_host_symbolic_name(host), "Brocade %s FV%s DV%s",
960 attr.ioc_attr.adapter_attr.model,
961 attr.ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
962
963 fc_host_supported_speeds(host) = 0;
964 fc_host_supported_speeds(host) |=
965 FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT |
966 FC_PORTSPEED_1GBIT;
967
968 memset(&attr.pattr, 0, sizeof(attr.pattr));
969 bfa_pport_get_attr(&bfad->bfa, &attr.pattr);
970 fc_host_maxframe_size(host) = attr.pattr.pport_cfg.maxfrsize;
971}
972
973static void
974bfad_im_fc_rport_add(struct bfad_im_port_s *im_port, struct bfad_itnim_s *itnim)
975{
976 struct fc_rport_identifiers rport_ids;
977 struct fc_rport *fc_rport;
978 struct bfad_itnim_data_s *itnim_data;
979
980 rport_ids.node_name =
981 bfa_os_htonll(bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim));
982 rport_ids.port_name =
983 bfa_os_htonll(bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim));
984 rport_ids.port_id =
985 bfa_os_hton3b(bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim));
986 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
987
988 itnim->fc_rport = fc_rport =
989 fc_remote_port_add(im_port->shost, 0, &rport_ids);
990
991 if (!fc_rport)
992 return;
993
994 fc_rport->maxframe_size =
995 bfa_fcs_itnim_get_maxfrsize(&itnim->fcs_itnim);
996 fc_rport->supported_classes = bfa_fcs_itnim_get_cos(&itnim->fcs_itnim);
997
998 itnim_data = fc_rport->dd_data;
999 itnim_data->itnim = itnim;
1000
1001 rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
1002
1003 if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN)
1004 fc_remote_port_rolechg(fc_rport, rport_ids.roles);
1005
1006 if ((fc_rport->scsi_target_id != -1)
1007 && (fc_rport->scsi_target_id < MAX_FCP_TARGET))
1008 itnim->scsi_tgt_id = fc_rport->scsi_target_id;
1009
1010 return;
1011}
1012
1013/**
1014 * Work queue handler using FC transport service
1015* Context: kernel
1016 */
1017static void
1018bfad_im_itnim_work_handler(struct work_struct *work)
1019{
1020 struct bfad_itnim_s *itnim = container_of(work, struct bfad_itnim_s,
1021 itnim_work);
1022 struct bfad_im_s *im = itnim->im;
1023 struct bfad_s *bfad = im->bfad;
1024 struct bfad_im_port_s *im_port;
1025 unsigned long flags;
1026 struct fc_rport *fc_rport;
1027 wwn_t wwpn;
1028 u32 fcid;
1029 char wwpn_str[32], fcid_str[16];
1030
1031 spin_lock_irqsave(&bfad->bfad_lock, flags);
1032 im_port = itnim->im_port;
1033 bfa_trc(bfad, itnim->state);
1034 switch (itnim->state) {
1035 case ITNIM_STATE_ONLINE:
1036 if (!itnim->fc_rport) {
1037 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1038 bfad_im_fc_rport_add(im_port, itnim);
1039 spin_lock_irqsave(&bfad->bfad_lock, flags);
1040 wwpn = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim);
1041 fcid = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim);
1042 wwn2str(wwpn_str, wwpn);
1043 fcid2str(fcid_str, fcid);
1044 list_add_tail(&itnim->list_entry,
1045 &im_port->itnim_mapped_list);
1046 bfa_log(bfad->logmod, BFA_LOG_LINUX_ITNIM_ONLINE,
1047 im_port->shost->host_no,
1048 itnim->scsi_tgt_id,
1049 fcid_str, wwpn_str);
1050 } else {
1051 printk(KERN_WARNING
1052 "%s: itnim %llx is already in online state\n",
1053 __FUNCTION__,
1054 bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim));
1055 }
1056
1057 break;
1058 case ITNIM_STATE_OFFLINE_PENDING:
1059 itnim->state = ITNIM_STATE_OFFLINE;
1060 if (itnim->fc_rport) {
1061 fc_rport = itnim->fc_rport;
1062 ((struct bfad_itnim_data_s *)
1063 fc_rport->dd_data)->itnim = NULL;
1064 itnim->fc_rport = NULL;
1065 if (!(im_port->port->flags & BFAD_PORT_DELETE)) {
1066 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1067 fc_rport->dev_loss_tmo =
1068 bfa_fcpim_path_tov_get(&bfad->bfa) + 1;
1069 fc_remote_port_delete(fc_rport);
1070 spin_lock_irqsave(&bfad->bfad_lock, flags);
1071 }
1072 wwpn = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim);
1073 fcid = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim);
1074 wwn2str(wwpn_str, wwpn);
1075 fcid2str(fcid_str, fcid);
1076 list_del(&itnim->list_entry);
1077 bfa_log(bfad->logmod, BFA_LOG_LINUX_ITNIM_OFFLINE,
1078 im_port->shost->host_no,
1079 itnim->scsi_tgt_id,
1080 fcid_str, wwpn_str);
1081 }
1082 break;
1083 case ITNIM_STATE_FREE:
1084 if (itnim->fc_rport) {
1085 fc_rport = itnim->fc_rport;
1086 ((struct bfad_itnim_data_s *)
1087 fc_rport->dd_data)->itnim = NULL;
1088 itnim->fc_rport = NULL;
1089 if (!(im_port->port->flags & BFAD_PORT_DELETE)) {
1090 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1091 fc_rport->dev_loss_tmo =
1092 bfa_fcpim_path_tov_get(&bfad->bfa) + 1;
1093 fc_remote_port_delete(fc_rport);
1094 spin_lock_irqsave(&bfad->bfad_lock, flags);
1095 }
1096 list_del(&itnim->list_entry);
1097 }
1098
1099 kfree(itnim);
1100 break;
1101 default:
1102 bfa_assert(0);
1103 break;
1104 }
1105
1106 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1107}
1108
1109/**
1110 * Scsi_Host template entry, queue a SCSI command to the BFAD.
1111 */
1112static int
1113bfad_im_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
1114{
1115 struct bfad_im_port_s *im_port =
1116 (struct bfad_im_port_s *) cmnd->device->host->hostdata[0];
1117 struct bfad_s *bfad = im_port->bfad;
1118 struct bfad_itnim_data_s *itnim_data = cmnd->device->hostdata;
1119 struct bfad_itnim_s *itnim;
1120 struct bfa_ioim_s *hal_io;
1121 unsigned long flags;
1122 int rc;
1123 s16 sg_cnt = 0;
1124 struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
1125
1126 rc = fc_remote_port_chkready(rport);
1127 if (rc) {
1128 cmnd->result = rc;
1129 done(cmnd);
1130 return 0;
1131 }
1132
1133 sg_cnt = scsi_dma_map(cmnd);
1134
1135 if (sg_cnt < 0)
1136 return SCSI_MLQUEUE_HOST_BUSY;
1137
1138 cmnd->scsi_done = done;
1139
1140 spin_lock_irqsave(&bfad->bfad_lock, flags);
1141 if (!(bfad->bfad_flags & BFAD_HAL_START_DONE)) {
1142 printk(KERN_WARNING
1143 "bfad%d, queuecommand %p %x failed, BFA stopped\n",
1144 bfad->inst_no, cmnd, cmnd->cmnd[0]);
1145 cmnd->result = ScsiResult(DID_NO_CONNECT, 0);
1146 goto out_fail_cmd;
1147 }
1148
1149 itnim = itnim_data->itnim;
1150 if (!itnim) {
1151 cmnd->result = ScsiResult(DID_IMM_RETRY, 0);
1152 goto out_fail_cmd;
1153 }
1154
1155 hal_io = bfa_ioim_alloc(&bfad->bfa, (struct bfad_ioim_s *) cmnd,
1156 itnim->bfa_itnim, sg_cnt);
1157 if (!hal_io) {
1158 printk(KERN_WARNING "hal_io failure\n");
1159 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1160 scsi_dma_unmap(cmnd);
1161 return SCSI_MLQUEUE_HOST_BUSY;
1162 }
1163
1164 cmnd->host_scribble = (char *)hal_io;
1165 bfa_trc_fp(bfad, hal_io->iotag);
1166 bfa_ioim_start(hal_io);
1167 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1168
1169 return 0;
1170
1171out_fail_cmd:
1172 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1173 scsi_dma_unmap(cmnd);
1174 if (done)
1175 done(cmnd);
1176
1177 return 0;
1178}
1179
1180void
1181bfad_os_rport_online_wait(struct bfad_s *bfad)
1182{
1183 int i;
1184 int rport_delay = 10;
1185
1186 for (i = 0; !(bfad->bfad_flags & BFAD_PORT_ONLINE)
1187 && i < bfa_linkup_delay; i++)
1188 schedule_timeout_uninterruptible(HZ);
1189
1190 if (bfad->bfad_flags & BFAD_PORT_ONLINE) {
1191 rport_delay = rport_delay < bfa_linkup_delay ?
1192 rport_delay : bfa_linkup_delay;
1193 for (i = 0; !(bfad->bfad_flags & BFAD_RPORT_ONLINE)
1194 && i < rport_delay; i++)
1195 schedule_timeout_uninterruptible(HZ);
1196
1197 if (rport_delay > 0 && (bfad->bfad_flags & BFAD_RPORT_ONLINE))
1198 schedule_timeout_uninterruptible(rport_delay * HZ);
1199 }
1200}
1201
1202int
1203bfad_os_get_linkup_delay(struct bfad_s *bfad)
1204{
1205
1206 u8 nwwns = 0;
1207 wwn_t *wwns;
1208 int ldelay;
1209
1210 /*
1211 * Querying for the boot target port wwns
1212 * -- read from boot information in flash.
1213 * If nwwns > 0 => boot over SAN and set bfa_linkup_delay = 30
1214 * else => local boot machine set bfa_linkup_delay = 10
1215 */
1216
1217 bfa_iocfc_get_bootwwns(&bfad->bfa, &nwwns, &wwns);
1218
1219 if (nwwns > 0) {
1220 /* If boot over SAN; linkup_delay = 30sec */
1221 ldelay = 30;
1222 } else {
1223 /* If local boot; linkup_delay = 10sec */
1224 ldelay = 0;
1225 }
1226
1227 return ldelay;
1228}
1229
1230
diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h
new file mode 100644
index 000000000000..189a5b29e21a
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_im.h
@@ -0,0 +1,150 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFAD_IM_H__
19#define __BFAD_IM_H__
20
21#include "fcs/bfa_fcs_fcpim.h"
22#include "bfad_im_compat.h"
23
24#define FCPI_NAME " fcpim"
25
26void bfad_flags_set(struct bfad_s *bfad, u32 flags);
27bfa_status_t bfad_im_module_init(void);
28void bfad_im_module_exit(void);
29bfa_status_t bfad_im_probe(struct bfad_s *bfad);
30void bfad_im_probe_undo(struct bfad_s *bfad);
31void bfad_im_probe_post(struct bfad_im_s *im);
32bfa_status_t bfad_im_port_new(struct bfad_s *bfad, struct bfad_port_s *port);
33void bfad_im_port_delete(struct bfad_s *bfad, struct bfad_port_s *port);
34void bfad_im_port_online(struct bfad_s *bfad, struct bfad_port_s *port);
35void bfad_im_port_offline(struct bfad_s *bfad, struct bfad_port_s *port);
36void bfad_im_port_clean(struct bfad_im_port_s *im_port);
37int bfad_im_scsi_host_alloc(struct bfad_s *bfad,
38 struct bfad_im_port_s *im_port);
39void bfad_im_scsi_host_free(struct bfad_s *bfad,
40 struct bfad_im_port_s *im_port);
41
42#define MAX_FCP_TARGET 1024
43#define MAX_FCP_LUN 16384
44#define BFAD_TARGET_RESET_TMO 60
45#define BFAD_LUN_RESET_TMO 60
46#define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
47#define BFA_QUEUE_FULL_RAMP_UP_TIME 120
48#define BFAD_KOBJ_NAME_LEN 20
49
50/*
51 * itnim flags
52 */
53#define ITNIM_MAPPED 0x00000001
54
55#define SCSI_TASK_MGMT 0x00000001
56#define IO_DONE_BIT 0
57
58struct bfad_itnim_data_s {
59 struct bfad_itnim_s *itnim;
60};
61
62struct bfad_im_port_s {
63 struct bfad_s *bfad;
64 struct bfad_port_s *port;
65 struct work_struct port_delete_work;
66 int idr_id;
67 u16 cur_scsi_id;
68 struct list_head binding_list;
69 struct Scsi_Host *shost;
70 struct list_head itnim_mapped_list;
71};
72
73enum bfad_itnim_state {
74 ITNIM_STATE_NONE,
75 ITNIM_STATE_ONLINE,
76 ITNIM_STATE_OFFLINE_PENDING,
77 ITNIM_STATE_OFFLINE,
78 ITNIM_STATE_TIMEOUT,
79 ITNIM_STATE_FREE,
80};
81
82/*
83 * Per itnim data structure
84 */
85struct bfad_itnim_s {
86 struct list_head list_entry;
87 struct bfa_fcs_itnim_s fcs_itnim;
88 struct work_struct itnim_work;
89 u32 flags;
90 enum bfad_itnim_state state;
91 struct bfad_im_s *im;
92 struct bfad_im_port_s *im_port;
93 struct bfad_rport_s *drv_rport;
94 struct fc_rport *fc_rport;
95 struct bfa_itnim_s *bfa_itnim;
96 u16 scsi_tgt_id;
97 u16 queue_work;
98 unsigned long last_ramp_up_time;
99 unsigned long last_queue_full_time;
100};
101
102enum bfad_binding_type {
103 FCP_PWWN_BINDING = 0x1,
104 FCP_NWWN_BINDING = 0x2,
105 FCP_FCID_BINDING = 0x3,
106};
107
108struct bfad_fcp_binding {
109 struct list_head list_entry;
110 enum bfad_binding_type binding_type;
111 u16 scsi_target_id;
112 u32 fc_id;
113 wwn_t nwwn;
114 wwn_t pwwn;
115};
116
117struct bfad_im_s {
118 struct bfad_s *bfad;
119 struct workqueue_struct *drv_workq;
120 char drv_workq_name[BFAD_KOBJ_NAME_LEN];
121};
122
123struct Scsi_Host *bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port,
124 struct bfad_s *);
125bfa_status_t bfad_os_thread_workq(struct bfad_s *bfad);
126void bfad_os_destroy_workq(struct bfad_im_s *im);
127void bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv);
128void bfad_os_fc_host_init(struct bfad_im_port_s *im_port);
129void bfad_os_init_work(struct bfad_im_port_s *im_port);
130void bfad_os_scsi_host_free(struct bfad_s *bfad,
131 struct bfad_im_port_s *im_port);
132void bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim,
133 struct scsi_device *sdev);
134void bfad_os_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev);
135struct bfad_itnim_s *bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id);
136int bfad_os_scsi_add_host(struct Scsi_Host *shost,
137 struct bfad_im_port_s *im_port, struct bfad_s *bfad);
138
139/*
140 * scsi_host_template entries
141 */
142void bfad_im_itnim_unmap(struct bfad_im_port_s *im_port,
143 struct bfad_itnim_s *itnim);
144
145extern struct scsi_host_template bfad_im_scsi_host_template;
146extern struct scsi_host_template bfad_im_vport_template;
147extern struct fc_function_template bfad_im_fc_function_template;
148extern struct scsi_transport_template *bfad_im_scsi_transport_template;
149
150#endif
diff --git a/drivers/scsi/bfa/bfad_im_compat.h b/drivers/scsi/bfa/bfad_im_compat.h
new file mode 100644
index 000000000000..1d3e74ec338c
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_im_compat.h
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFAD_IM_COMPAT_H__
19#define __BFAD_IM_COMPAT_H__
20
21extern u32 *bfi_image_buf;
22extern u32 bfi_image_size;
23
24extern struct device_attribute *bfad_im_host_attrs[];
25extern struct device_attribute *bfad_im_vport_attrs[];
26
27u32 *bfad_get_firmware_buf(struct pci_dev *pdev);
28u32 *bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
29 u32 *bfi_image_size, char *fw_name);
30
31static inline u32 *
32bfad_load_fwimg(struct pci_dev *pdev)
33{
34 return(bfad_get_firmware_buf(pdev));
35}
36
37static inline void
38bfad_free_fwimg(void)
39{
40 if (bfi_image_ct_size && bfi_image_ct)
41 vfree(bfi_image_ct);
42 if (bfi_image_cb_size && bfi_image_cb)
43 vfree(bfi_image_cb);
44}
45
46#endif
diff --git a/drivers/scsi/bfa/bfad_intr.c b/drivers/scsi/bfa/bfad_intr.c
new file mode 100644
index 000000000000..f104e029cac9
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_intr.c
@@ -0,0 +1,214 @@
1/*
2 * Copyright (c) 2005-2009 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 "bfad_drv.h"
19#include "bfad_trcmod.h"
20
21BFA_TRC_FILE(LDRV, INTR);
22
23/**
24 * bfa_isr BFA driver interrupt functions
25 */
26irqreturn_t bfad_intx(int irq, void *dev_id);
27static int msix_disable;
28module_param(msix_disable, int, S_IRUGO | S_IWUSR);
29/**
30 * Line based interrupt handler.
31 */
32irqreturn_t
33bfad_intx(int irq, void *dev_id)
34{
35 struct bfad_s *bfad = dev_id;
36 struct list_head doneq;
37 unsigned long flags;
38 bfa_boolean_t rc;
39
40 spin_lock_irqsave(&bfad->bfad_lock, flags);
41 rc = bfa_intx(&bfad->bfa);
42 if (!rc) {
43 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
44 return IRQ_NONE;
45 }
46
47 bfa_comp_deq(&bfad->bfa, &doneq);
48 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
49
50 if (!list_empty(&doneq)) {
51 bfa_comp_process(&bfad->bfa, &doneq);
52
53 spin_lock_irqsave(&bfad->bfad_lock, flags);
54 bfa_comp_free(&bfad->bfa, &doneq);
55 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
56 bfa_trc_fp(bfad, irq);
57 }
58
59 return IRQ_HANDLED;
60
61}
62
63static irqreturn_t
64bfad_msix(int irq, void *dev_id)
65{
66 struct bfad_msix_s *vec = dev_id;
67 struct bfad_s *bfad = vec->bfad;
68 struct list_head doneq;
69 unsigned long flags;
70
71 spin_lock_irqsave(&bfad->bfad_lock, flags);
72
73 bfa_msix(&bfad->bfa, vec->msix.entry);
74 bfa_comp_deq(&bfad->bfa, &doneq);
75 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
76
77 if (!list_empty(&doneq)) {
78 bfa_comp_process(&bfad->bfa, &doneq);
79
80 spin_lock_irqsave(&bfad->bfad_lock, flags);
81 bfa_comp_free(&bfad->bfa, &doneq);
82 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
83 }
84
85 return IRQ_HANDLED;
86}
87
88/**
89 * Initialize the MSIX entry table.
90 */
91static void
92bfad_init_msix_entry(struct bfad_s *bfad, struct msix_entry *msix_entries,
93 int mask, int max_bit)
94{
95 int i;
96 int match = 0x00000001;
97
98 for (i = 0, bfad->nvec = 0; i < MAX_MSIX_ENTRY; i++) {
99 if (mask & match) {
100 bfad->msix_tab[bfad->nvec].msix.entry = i;
101 bfad->msix_tab[bfad->nvec].bfad = bfad;
102 msix_entries[bfad->nvec].entry = i;
103 bfad->nvec++;
104 }
105
106 match <<= 1;
107 }
108
109}
110
111int
112bfad_install_msix_handler(struct bfad_s *bfad)
113{
114 int i, error = 0;
115
116 for (i = 0; i < bfad->nvec; i++) {
117 error = request_irq(bfad->msix_tab[i].msix.vector,
118 (irq_handler_t) bfad_msix, 0,
119 BFAD_DRIVER_NAME, &bfad->msix_tab[i]);
120 bfa_trc(bfad, i);
121 bfa_trc(bfad, bfad->msix_tab[i].msix.vector);
122 if (error) {
123 int j;
124
125 for (j = 0; j < i; j++)
126 free_irq(bfad->msix_tab[j].msix.vector,
127 &bfad->msix_tab[j]);
128
129 return 1;
130 }
131 }
132
133 return 0;
134}
135
136/**
137 * Setup MSIX based interrupt.
138 */
139int
140bfad_setup_intr(struct bfad_s *bfad)
141{
142 int error = 0;
143 u32 mask = 0, i, num_bit = 0, max_bit = 0;
144 struct msix_entry msix_entries[MAX_MSIX_ENTRY];
145
146 /* Call BFA to get the msix map for this PCI function. */
147 bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit);
148
149 /* Set up the msix entry table */
150 bfad_init_msix_entry(bfad, msix_entries, mask, max_bit);
151
152 if (!msix_disable) {
153 error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec);
154 if (error) {
155 /*
156 * Only error number of vector is available.
157 * We don't have a mechanism to map multiple
158 * interrupts into one vector, so even if we
159 * can try to request less vectors, we don't
160 * know how to associate interrupt events to
161 * vectors. Linux doesn't dupicate vectors
162 * in the MSIX table for this case.
163 */
164
165 printk(KERN_WARNING "bfad%d: "
166 "pci_enable_msix failed (%d),"
167 " use line based.\n", bfad->inst_no, error);
168
169 goto line_based;
170 }
171
172 /* Save the vectors */
173 for (i = 0; i < bfad->nvec; i++) {
174 bfa_trc(bfad, msix_entries[i].vector);
175 bfad->msix_tab[i].msix.vector = msix_entries[i].vector;
176 }
177
178 bfa_msix_init(&bfad->bfa, bfad->nvec);
179
180 bfad->bfad_flags |= BFAD_MSIX_ON;
181
182 return error;
183 }
184
185line_based:
186 error = 0;
187 if (request_irq
188 (bfad->pcidev->irq, (irq_handler_t) bfad_intx, BFAD_IRQ_FLAGS,
189 BFAD_DRIVER_NAME, bfad) != 0) {
190 /* Enable interrupt handler failed */
191 return 1;
192 }
193
194 return error;
195}
196
197void
198bfad_remove_intr(struct bfad_s *bfad)
199{
200 int i;
201
202 if (bfad->bfad_flags & BFAD_MSIX_ON) {
203 for (i = 0; i < bfad->nvec; i++)
204 free_irq(bfad->msix_tab[i].msix.vector,
205 &bfad->msix_tab[i]);
206
207 pci_disable_msix(bfad->pcidev);
208 bfad->bfad_flags &= ~BFAD_MSIX_ON;
209 } else {
210 free_irq(bfad->pcidev->irq, bfad);
211 }
212}
213
214
diff --git a/drivers/scsi/bfa/bfad_ipfc.h b/drivers/scsi/bfa/bfad_ipfc.h
new file mode 100644
index 000000000000..718bc5227671
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_ipfc.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DRV_IPFC_H__
18#define __BFA_DRV_IPFC_H__
19
20
21#define IPFC_NAME ""
22
23#define bfad_ipfc_module_init(x) do {} while (0)
24#define bfad_ipfc_module_exit(x) do {} while (0)
25#define bfad_ipfc_probe(x) do {} while (0)
26#define bfad_ipfc_probe_undo(x) do {} while (0)
27#define bfad_ipfc_port_config(x, y) BFA_STATUS_OK
28#define bfad_ipfc_port_unconfig(x, y) do {} while (0)
29
30#define bfad_ipfc_probe_post(x) do {} while (0)
31#define bfad_ipfc_port_new(x, y, z) BFA_STATUS_OK
32#define bfad_ipfc_port_delete(x, y) do {} while (0)
33#define bfad_ipfc_port_online(x, y) do {} while (0)
34#define bfad_ipfc_port_offline(x, y) do {} while (0)
35
36#define bfad_ip_get_attr(x) BFA_STATUS_FAILED
37#define bfad_ip_reset_drv_stats(x) BFA_STATUS_FAILED
38#define bfad_ip_get_drv_stats(x, y) BFA_STATUS_FAILED
39#define bfad_ip_enable_ipfc(x, y, z) BFA_STATUS_FAILED
40
41
42#endif
diff --git a/drivers/scsi/bfa/bfad_os.c b/drivers/scsi/bfa/bfad_os.c
new file mode 100644
index 000000000000..faf47b4f1a38
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_os.c
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfad_os.c Linux driver OS specific calls.
20 */
21
22#include "bfa_os_inc.h"
23#include "bfad_drv.h"
24
25void
26bfa_os_gettimeofday(struct bfa_timeval_s *tv)
27{
28 struct timeval tmp_tv;
29
30 do_gettimeofday(&tmp_tv);
31 tv->tv_sec = (u32) tmp_tv.tv_sec;
32 tv->tv_usec = (u32) tmp_tv.tv_usec;
33}
34
35void
36bfa_os_printf(struct bfa_log_mod_s *log_mod, u32 msg_id,
37 const char *fmt, ...)
38{
39 va_list ap;
40 #define BFA_STRING_256 256
41 char tmp[BFA_STRING_256];
42
43 va_start(ap, fmt);
44 vsprintf(tmp, fmt, ap);
45 va_end(ap);
46
47 printk(tmp);
48}
49
50
diff --git a/drivers/scsi/bfa/bfad_tm.h b/drivers/scsi/bfa/bfad_tm.h
new file mode 100644
index 000000000000..4901b1b7df02
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_tm.h
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) 2005-2009 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/*
19 * Brocade Fibre Channel HBA Linux Target Mode Driver
20 */
21
22/**
23 * tm/dummy/bfad_tm.h BFA callback dummy header file for BFA Linux target mode PCI interface module.
24 */
25
26#ifndef __BFAD_TM_H__
27#define __BFAD_TM_H__
28
29#include <defs/bfa_defs_status.h>
30
31#define FCPT_NAME ""
32
33/*
34 * Called from base Linux driver on (De)Init events
35 */
36
37/* attach tgt template with scst */
38#define bfad_tm_module_init() do {} while (0)
39
40/* detach/release tgt template */
41#define bfad_tm_module_exit() do {} while (0)
42
43#define bfad_tm_probe(x) do {} while (0)
44#define bfad_tm_probe_undo(x) do {} while (0)
45#define bfad_tm_probe_post(x) do {} while (0)
46
47/*
48 * Called by base Linux driver but triggered by BFA FCS on config events
49 */
50#define bfad_tm_port_new(x, y) BFA_STATUS_OK
51#define bfad_tm_port_delete(x, y) do {} while (0)
52
53/*
54 * Called by base Linux driver but triggered by BFA FCS on PLOGI/O events
55 */
56#define bfad_tm_port_online(x, y) do {} while (0)
57#define bfad_tm_port_offline(x, y) do {} while (0)
58
59#endif
diff --git a/drivers/scsi/bfa/bfad_trcmod.h b/drivers/scsi/bfa/bfad_trcmod.h
new file mode 100644
index 000000000000..2827b2acd041
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_trcmod.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfad_trcmod.h Linux driver trace modules
20 */
21
22
23#ifndef __BFAD_TRCMOD_H__
24#define __BFAD_TRCMOD_H__
25
26#include <cs/bfa_trc.h>
27
28/*
29 * !!! Only append to the enums defined here to avoid any versioning
30 * !!! needed between trace utility and driver version
31 */
32enum {
33 /* 2.6 Driver */
34 BFA_TRC_LDRV_BFAD = 1,
35 BFA_TRC_LDRV_BFAD_2_6 = 2,
36 BFA_TRC_LDRV_BFAD_2_6_9 = 3,
37 BFA_TRC_LDRV_BFAD_2_6_10 = 4,
38 BFA_TRC_LDRV_INTR = 5,
39 BFA_TRC_LDRV_IOCTL = 6,
40 BFA_TRC_LDRV_OS = 7,
41 BFA_TRC_LDRV_IM = 8,
42 BFA_TRC_LDRV_IM_2_6 = 9,
43 BFA_TRC_LDRV_IM_2_6_9 = 10,
44 BFA_TRC_LDRV_IM_2_6_10 = 11,
45 BFA_TRC_LDRV_TM = 12,
46 BFA_TRC_LDRV_IPFC = 13,
47 BFA_TRC_LDRV_IM_2_4 = 14,
48 BFA_TRC_LDRV_IM_VMW = 15,
49 BFA_TRC_LDRV_IM_LT_2_6_10 = 16,
50};
51
52#endif /* __BFAD_TRCMOD_H__ */
diff --git a/drivers/scsi/bfa/fab.c b/drivers/scsi/bfa/fab.c
new file mode 100644
index 000000000000..7e3a4d5d7bb4
--- /dev/null
+++ b/drivers/scsi/bfa/fab.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19#include <bfa_svc.h>
20#include "fcs_lport.h"
21#include "fcs_rport.h"
22#include "lport_priv.h"
23
24/**
25 * fab.c port fab implementation.
26 */
27
28/**
29 * bfa_fcs_port_fab_public port fab public functions
30 */
31
32/**
33 * Called by port to initialize fabric services of the base port.
34 */
35void
36bfa_fcs_port_fab_init(struct bfa_fcs_port_s *port)
37{
38 bfa_fcs_port_ns_init(port);
39 bfa_fcs_port_scn_init(port);
40 bfa_fcs_port_ms_init(port);
41}
42
43/**
44 * Called by port to notify transition to online state.
45 */
46void
47bfa_fcs_port_fab_online(struct bfa_fcs_port_s *port)
48{
49 bfa_fcs_port_ns_online(port);
50 bfa_fcs_port_scn_online(port);
51}
52
53/**
54 * Called by port to notify transition to offline state.
55 */
56void
57bfa_fcs_port_fab_offline(struct bfa_fcs_port_s *port)
58{
59 bfa_fcs_port_ns_offline(port);
60 bfa_fcs_port_scn_offline(port);
61 bfa_fcs_port_ms_offline(port);
62}
diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c
new file mode 100644
index 000000000000..a8b14c47b009
--- /dev/null
+++ b/drivers/scsi/bfa/fabric.c
@@ -0,0 +1,1278 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * fabric.c Fabric module implementation.
20 */
21
22#include "fcs_fabric.h"
23#include "fcs_lport.h"
24#include "fcs_vport.h"
25#include "fcs_trcmod.h"
26#include "fcs_fcxp.h"
27#include "fcs_auth.h"
28#include "fcs.h"
29#include "fcbuild.h"
30#include <log/bfa_log_fcs.h>
31#include <aen/bfa_aen_port.h>
32#include <bfa_svc.h>
33
34BFA_TRC_FILE(FCS, FABRIC);
35
36#define BFA_FCS_FABRIC_RETRY_DELAY (2000) /* Milliseconds */
37#define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */
38
39#define bfa_fcs_fabric_set_opertype(__fabric) do { \
40 if (bfa_pport_get_topology((__fabric)->fcs->bfa) \
41 == BFA_PPORT_TOPOLOGY_P2P) \
42 (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT; \
43 else \
44 (__fabric)->oper_type = BFA_PPORT_TYPE_NLPORT; \
45} while (0)
46
47/*
48 * forward declarations
49 */
50static void bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric);
51static void bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric);
52static void bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric);
53static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric);
54static void bfa_fcs_fabric_delay(void *cbarg);
55static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric);
56static void bfa_fcs_fabric_delete_comp(void *cbarg);
57static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric,
58 struct fchs_s *fchs, u16 len);
59static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
60 struct fchs_s *fchs, u16 len);
61static void bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric);
62static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
63 struct bfa_fcxp_s *fcxp,
64 void *cbarg, bfa_status_t status,
65 u32 rsp_len,
66 u32 resid_len,
67 struct fchs_s *rspfchs);
68/**
69 * fcs_fabric_sm fabric state machine functions
70 */
71
72/**
73 * Fabric state machine events
74 */
75enum bfa_fcs_fabric_event {
76 BFA_FCS_FABRIC_SM_CREATE = 1, /* fabric create from driver */
77 BFA_FCS_FABRIC_SM_DELETE = 2, /* fabric delete from driver */
78 BFA_FCS_FABRIC_SM_LINK_DOWN = 3, /* link down from port */
79 BFA_FCS_FABRIC_SM_LINK_UP = 4, /* link up from port */
80 BFA_FCS_FABRIC_SM_CONT_OP = 5, /* continue op from flogi/auth */
81 BFA_FCS_FABRIC_SM_RETRY_OP = 6, /* continue op from flogi/auth */
82 BFA_FCS_FABRIC_SM_NO_FABRIC = 7, /* no fabric from flogi/auth
83 */
84 BFA_FCS_FABRIC_SM_PERF_EVFP = 8, /* perform EVFP from
85 *flogi/auth */
86 BFA_FCS_FABRIC_SM_ISOLATE = 9, /* isolate from EVFP processing */
87 BFA_FCS_FABRIC_SM_NO_TAGGING = 10,/* no VFT tagging from EVFP */
88 BFA_FCS_FABRIC_SM_DELAYED = 11, /* timeout delay event */
89 BFA_FCS_FABRIC_SM_AUTH_FAILED = 12, /* authentication failed */
90 BFA_FCS_FABRIC_SM_AUTH_SUCCESS = 13, /* authentication successful
91 */
92 BFA_FCS_FABRIC_SM_DELCOMP = 14, /* all vports deleted event */
93 BFA_FCS_FABRIC_SM_LOOPBACK = 15, /* Received our own FLOGI */
94 BFA_FCS_FABRIC_SM_START = 16, /* fabric delete from driver */
95};
96
97static void bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
98 enum bfa_fcs_fabric_event event);
99static void bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
100 enum bfa_fcs_fabric_event event);
101static void bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
102 enum bfa_fcs_fabric_event event);
103static void bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
104 enum bfa_fcs_fabric_event event);
105static void bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
106 enum bfa_fcs_fabric_event event);
107static void bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
108 enum bfa_fcs_fabric_event event);
109static void bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
110 enum bfa_fcs_fabric_event event);
111static void bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
112 enum bfa_fcs_fabric_event event);
113static void bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
114 enum bfa_fcs_fabric_event event);
115static void bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
116 enum bfa_fcs_fabric_event event);
117static void bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
118 enum bfa_fcs_fabric_event event);
119static void bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
120 enum bfa_fcs_fabric_event event);
121static void bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
122 enum bfa_fcs_fabric_event event);
123static void bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
124 enum bfa_fcs_fabric_event event);
125/**
126 * Beginning state before fabric creation.
127 */
128static void
129bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
130 enum bfa_fcs_fabric_event event)
131{
132 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
133 bfa_trc(fabric->fcs, event);
134
135 switch (event) {
136 case BFA_FCS_FABRIC_SM_CREATE:
137 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
138 bfa_fcs_fabric_init(fabric);
139 bfa_fcs_lport_init(&fabric->bport, fabric->fcs, FC_VF_ID_NULL,
140 &fabric->bport.port_cfg, NULL);
141 break;
142
143 case BFA_FCS_FABRIC_SM_LINK_UP:
144 case BFA_FCS_FABRIC_SM_LINK_DOWN:
145 break;
146
147 default:
148 bfa_sm_fault(fabric->fcs, event);
149 }
150}
151
152/**
153 * Beginning state before fabric creation.
154 */
155static void
156bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
157 enum bfa_fcs_fabric_event event)
158{
159 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
160 bfa_trc(fabric->fcs, event);
161
162 switch (event) {
163 case BFA_FCS_FABRIC_SM_START:
164 if (bfa_pport_is_linkup(fabric->fcs->bfa)) {
165 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
166 bfa_fcs_fabric_login(fabric);
167 } else
168 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
169 break;
170
171 case BFA_FCS_FABRIC_SM_LINK_UP:
172 case BFA_FCS_FABRIC_SM_LINK_DOWN:
173 break;
174
175 case BFA_FCS_FABRIC_SM_DELETE:
176 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
177 bfa_fcs_modexit_comp(fabric->fcs);
178 break;
179
180 default:
181 bfa_sm_fault(fabric->fcs, event);
182 }
183}
184
185/**
186 * Link is down, awaiting LINK UP event from port. This is also the
187 * first state at fabric creation.
188 */
189static void
190bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
191 enum bfa_fcs_fabric_event event)
192{
193 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
194 bfa_trc(fabric->fcs, event);
195
196 switch (event) {
197 case BFA_FCS_FABRIC_SM_LINK_UP:
198 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
199 bfa_fcs_fabric_login(fabric);
200 break;
201
202 case BFA_FCS_FABRIC_SM_RETRY_OP:
203 break;
204
205 case BFA_FCS_FABRIC_SM_DELETE:
206 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
207 bfa_fcs_fabric_delete(fabric);
208 break;
209
210 default:
211 bfa_sm_fault(fabric->fcs, event);
212 }
213}
214
215/**
216 * FLOGI is in progress, awaiting FLOGI reply.
217 */
218static void
219bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
220 enum bfa_fcs_fabric_event event)
221{
222 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
223 bfa_trc(fabric->fcs, event);
224
225 switch (event) {
226 case BFA_FCS_FABRIC_SM_CONT_OP:
227
228 bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
229 fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
230
231 if (fabric->auth_reqd && fabric->is_auth) {
232 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth);
233 bfa_trc(fabric->fcs, event);
234 } else {
235 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
236 bfa_fcs_fabric_notify_online(fabric);
237 }
238 break;
239
240 case BFA_FCS_FABRIC_SM_RETRY_OP:
241 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi_retry);
242 bfa_timer_start(fabric->fcs->bfa, &fabric->delay_timer,
243 bfa_fcs_fabric_delay, fabric,
244 BFA_FCS_FABRIC_RETRY_DELAY);
245 break;
246
247 case BFA_FCS_FABRIC_SM_LOOPBACK:
248 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_loopback);
249 bfa_lps_discard(fabric->lps);
250 bfa_fcs_fabric_set_opertype(fabric);
251 break;
252
253 case BFA_FCS_FABRIC_SM_NO_FABRIC:
254 fabric->fab_type = BFA_FCS_FABRIC_N2N;
255 bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
256 bfa_fcs_fabric_notify_online(fabric);
257 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
258 break;
259
260 case BFA_FCS_FABRIC_SM_LINK_DOWN:
261 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
262 bfa_lps_discard(fabric->lps);
263 break;
264
265 case BFA_FCS_FABRIC_SM_DELETE:
266 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
267 bfa_lps_discard(fabric->lps);
268 bfa_fcs_fabric_delete(fabric);
269 break;
270
271 default:
272 bfa_sm_fault(fabric->fcs, event);
273 }
274}
275
276
277static void
278bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
279 enum bfa_fcs_fabric_event event)
280{
281 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
282 bfa_trc(fabric->fcs, event);
283
284 switch (event) {
285 case BFA_FCS_FABRIC_SM_DELAYED:
286 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
287 bfa_fcs_fabric_login(fabric);
288 break;
289
290 case BFA_FCS_FABRIC_SM_LINK_DOWN:
291 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
292 bfa_timer_stop(&fabric->delay_timer);
293 break;
294
295 case BFA_FCS_FABRIC_SM_DELETE:
296 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
297 bfa_timer_stop(&fabric->delay_timer);
298 bfa_fcs_fabric_delete(fabric);
299 break;
300
301 default:
302 bfa_sm_fault(fabric->fcs, event);
303 }
304}
305
306/**
307 * Authentication is in progress, awaiting authentication results.
308 */
309static void
310bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
311 enum bfa_fcs_fabric_event event)
312{
313 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
314 bfa_trc(fabric->fcs, event);
315
316 switch (event) {
317 case BFA_FCS_FABRIC_SM_AUTH_FAILED:
318 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
319 bfa_lps_discard(fabric->lps);
320 break;
321
322 case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
323 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
324 bfa_fcs_fabric_notify_online(fabric);
325 break;
326
327 case BFA_FCS_FABRIC_SM_PERF_EVFP:
328 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp);
329 break;
330
331 case BFA_FCS_FABRIC_SM_LINK_DOWN:
332 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
333 bfa_lps_discard(fabric->lps);
334 break;
335
336 case BFA_FCS_FABRIC_SM_DELETE:
337 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
338 bfa_fcs_fabric_delete(fabric);
339 break;
340
341 default:
342 bfa_sm_fault(fabric->fcs, event);
343 }
344}
345
346/**
347 * Authentication failed
348 */
349static void
350bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
351 enum bfa_fcs_fabric_event event)
352{
353 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
354 bfa_trc(fabric->fcs, event);
355
356 switch (event) {
357 case BFA_FCS_FABRIC_SM_LINK_DOWN:
358 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
359 bfa_fcs_fabric_notify_offline(fabric);
360 break;
361
362 case BFA_FCS_FABRIC_SM_DELETE:
363 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
364 bfa_fcs_fabric_delete(fabric);
365 break;
366
367 default:
368 bfa_sm_fault(fabric->fcs, event);
369 }
370}
371
372/**
373 * Port is in loopback mode.
374 */
375static void
376bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
377 enum bfa_fcs_fabric_event event)
378{
379 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
380 bfa_trc(fabric->fcs, event);
381
382 switch (event) {
383 case BFA_FCS_FABRIC_SM_LINK_DOWN:
384 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
385 bfa_fcs_fabric_notify_offline(fabric);
386 break;
387
388 case BFA_FCS_FABRIC_SM_DELETE:
389 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
390 bfa_fcs_fabric_delete(fabric);
391 break;
392
393 default:
394 bfa_sm_fault(fabric->fcs, event);
395 }
396}
397
398/**
399 * There is no attached fabric - private loop or NPort-to-NPort topology.
400 */
401static void
402bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
403 enum bfa_fcs_fabric_event event)
404{
405 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
406 bfa_trc(fabric->fcs, event);
407
408 switch (event) {
409 case BFA_FCS_FABRIC_SM_LINK_DOWN:
410 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
411 bfa_lps_discard(fabric->lps);
412 bfa_fcs_fabric_notify_offline(fabric);
413 break;
414
415 case BFA_FCS_FABRIC_SM_DELETE:
416 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
417 bfa_fcs_fabric_delete(fabric);
418 break;
419
420 case BFA_FCS_FABRIC_SM_NO_FABRIC:
421 bfa_trc(fabric->fcs, fabric->bb_credit);
422 bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
423 break;
424
425 default:
426 bfa_sm_fault(fabric->fcs, event);
427 }
428}
429
430/**
431 * Fabric is online - normal operating state.
432 */
433static void
434bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
435 enum bfa_fcs_fabric_event event)
436{
437 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
438 bfa_trc(fabric->fcs, event);
439
440 switch (event) {
441 case BFA_FCS_FABRIC_SM_LINK_DOWN:
442 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
443 bfa_lps_discard(fabric->lps);
444 bfa_fcs_fabric_notify_offline(fabric);
445 break;
446
447 case BFA_FCS_FABRIC_SM_DELETE:
448 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
449 bfa_fcs_fabric_delete(fabric);
450 break;
451
452 case BFA_FCS_FABRIC_SM_AUTH_FAILED:
453 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
454 bfa_lps_discard(fabric->lps);
455 break;
456
457 case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
458 break;
459
460 default:
461 bfa_sm_fault(fabric->fcs, event);
462 }
463}
464
465/**
466 * Exchanging virtual fabric parameters.
467 */
468static void
469bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
470 enum bfa_fcs_fabric_event event)
471{
472 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
473 bfa_trc(fabric->fcs, event);
474
475 switch (event) {
476 case BFA_FCS_FABRIC_SM_CONT_OP:
477 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp_done);
478 break;
479
480 case BFA_FCS_FABRIC_SM_ISOLATE:
481 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_isolated);
482 break;
483
484 default:
485 bfa_sm_fault(fabric->fcs, event);
486 }
487}
488
489/**
490 * EVFP exchange complete and VFT tagging is enabled.
491 */
492static void
493bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
494 enum bfa_fcs_fabric_event event)
495{
496 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
497 bfa_trc(fabric->fcs, event);
498}
499
500/**
501 * Port is isolated after EVFP exchange due to VF_ID mismatch (N and F).
502 */
503static void
504bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
505 enum bfa_fcs_fabric_event event)
506{
507 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
508 bfa_trc(fabric->fcs, event);
509
510 bfa_log(fabric->fcs->logm, BFA_LOG_FCS_FABRIC_ISOLATED,
511 fabric->bport.port_cfg.pwwn, fabric->fcs->port_vfid,
512 fabric->event_arg.swp_vfid);
513}
514
515/**
516 * Fabric is being deleted, awaiting vport delete completions.
517 */
518static void
519bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
520 enum bfa_fcs_fabric_event event)
521{
522 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
523 bfa_trc(fabric->fcs, event);
524
525 switch (event) {
526 case BFA_FCS_FABRIC_SM_DELCOMP:
527 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
528 bfa_fcs_modexit_comp(fabric->fcs);
529 break;
530
531 case BFA_FCS_FABRIC_SM_LINK_UP:
532 break;
533
534 case BFA_FCS_FABRIC_SM_LINK_DOWN:
535 bfa_fcs_fabric_notify_offline(fabric);
536 break;
537
538 default:
539 bfa_sm_fault(fabric->fcs, event);
540 }
541}
542
543
544
545/**
546 * fcs_fabric_private fabric private functions
547 */
548
549static void
550bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric)
551{
552 struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg;
553
554 port_cfg->roles = BFA_PORT_ROLE_FCP_IM;
555 port_cfg->nwwn = bfa_ioc_get_nwwn(&fabric->fcs->bfa->ioc);
556 port_cfg->pwwn = bfa_ioc_get_pwwn(&fabric->fcs->bfa->ioc);
557}
558
559/**
560 * Port Symbolic Name Creation for base port.
561 */
562void
563bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
564{
565 struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg;
566 struct bfa_adapter_attr_s adapter_attr;
567 struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
568
569 bfa_os_memset((void *)&adapter_attr, 0,
570 sizeof(struct bfa_adapter_attr_s));
571 bfa_ioc_get_adapter_attr(&fabric->fcs->bfa->ioc, &adapter_attr);
572
573 /*
574 * Model name/number
575 */
576 strncpy((char *)&port_cfg->sym_name, adapter_attr.model,
577 BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
578 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
579 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
580
581 /*
582 * Driver Version
583 */
584 strncat((char *)&port_cfg->sym_name, (char *)driver_info->version,
585 BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
586 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
587 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
588
589 /*
590 * Host machine name
591 */
592 strncat((char *)&port_cfg->sym_name,
593 (char *)driver_info->host_machine_name,
594 BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
595 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
596 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
597
598 /*
599 * Host OS Info :
600 * If OS Patch Info is not there, do not truncate any bytes from the
601 * OS name string and instead copy the entire OS info string (64 bytes).
602 */
603 if (driver_info->host_os_patch[0] == '\0') {
604 strncat((char *)&port_cfg->sym_name,
605 (char *)driver_info->host_os_name, BFA_FCS_OS_STR_LEN);
606 strncat((char *)&port_cfg->sym_name,
607 BFA_FCS_PORT_SYMBNAME_SEPARATOR,
608 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
609 } else {
610 strncat((char *)&port_cfg->sym_name,
611 (char *)driver_info->host_os_name,
612 BFA_FCS_PORT_SYMBNAME_OSINFO_SZ);
613 strncat((char *)&port_cfg->sym_name,
614 BFA_FCS_PORT_SYMBNAME_SEPARATOR,
615 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
616
617 /*
618 * Append host OS Patch Info
619 */
620 strncat((char *)&port_cfg->sym_name,
621 (char *)driver_info->host_os_patch,
622 BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ);
623 }
624
625 /*
626 * null terminate
627 */
628 port_cfg->sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
629}
630
631/**
632 * bfa lps login completion callback
633 */
634void
635bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
636{
637 struct bfa_fcs_fabric_s *fabric = uarg;
638
639 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
640 bfa_trc(fabric->fcs, status);
641
642 switch (status) {
643 case BFA_STATUS_OK:
644 fabric->stats.flogi_accepts++;
645 break;
646
647 case BFA_STATUS_INVALID_MAC:
648 /*
649 * Only for CNA
650 */
651 fabric->stats.flogi_acc_err++;
652 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
653
654 return;
655
656 case BFA_STATUS_EPROTOCOL:
657 switch (bfa_lps_get_extstatus(fabric->lps)) {
658 case BFA_EPROTO_BAD_ACCEPT:
659 fabric->stats.flogi_acc_err++;
660 break;
661
662 case BFA_EPROTO_UNKNOWN_RSP:
663 fabric->stats.flogi_unknown_rsp++;
664 break;
665
666 default:
667 break;
668 }
669 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
670
671 return;
672
673 case BFA_STATUS_FABRIC_RJT:
674 fabric->stats.flogi_rejects++;
675 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
676 return;
677
678 default:
679 fabric->stats.flogi_rsp_err++;
680 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
681 return;
682 }
683
684 fabric->bb_credit = bfa_lps_get_peer_bbcredit(fabric->lps);
685 bfa_trc(fabric->fcs, fabric->bb_credit);
686
687 if (!bfa_lps_is_brcd_fabric(fabric->lps))
688 fabric->fabric_name = bfa_lps_get_peer_nwwn(fabric->lps);
689
690 /*
691 * Check port type. It should be 1 = F-port.
692 */
693 if (bfa_lps_is_fport(fabric->lps)) {
694 fabric->bport.pid = bfa_lps_get_pid(fabric->lps);
695 fabric->is_npiv = bfa_lps_is_npiv_en(fabric->lps);
696 fabric->is_auth = bfa_lps_is_authreq(fabric->lps);
697 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CONT_OP);
698 } else {
699 /*
700 * Nport-2-Nport direct attached
701 */
702 fabric->bport.port_topo.pn2n.rem_port_wwn =
703 bfa_lps_get_peer_pwwn(fabric->lps);
704 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
705 }
706
707 bfa_trc(fabric->fcs, fabric->bport.pid);
708 bfa_trc(fabric->fcs, fabric->is_npiv);
709 bfa_trc(fabric->fcs, fabric->is_auth);
710}
711
712/**
713 * Allocate and send FLOGI.
714 */
715static void
716bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
717{
718 struct bfa_s *bfa = fabric->fcs->bfa;
719 struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg;
720 u8 alpa = 0;
721
722 if (bfa_pport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP)
723 alpa = bfa_pport_get_myalpa(bfa);
724
725 bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_pport_get_maxfrsize(bfa),
726 pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
727
728 fabric->stats.flogi_sent++;
729}
730
731static void
732bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric)
733{
734 struct bfa_fcs_vport_s *vport;
735 struct list_head *qe, *qen;
736
737 bfa_trc(fabric->fcs, fabric->fabric_name);
738
739 bfa_fcs_fabric_set_opertype(fabric);
740 fabric->stats.fabric_onlines++;
741
742 /**
743 * notify online event to base and then virtual ports
744 */
745 bfa_fcs_port_online(&fabric->bport);
746
747 list_for_each_safe(qe, qen, &fabric->vport_q) {
748 vport = (struct bfa_fcs_vport_s *)qe;
749 bfa_fcs_vport_online(vport);
750 }
751}
752
753static void
754bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric)
755{
756 struct bfa_fcs_vport_s *vport;
757 struct list_head *qe, *qen;
758
759 bfa_trc(fabric->fcs, fabric->fabric_name);
760 fabric->stats.fabric_offlines++;
761
762 /**
763 * notify offline event first to vports and then base port.
764 */
765 list_for_each_safe(qe, qen, &fabric->vport_q) {
766 vport = (struct bfa_fcs_vport_s *)qe;
767 bfa_fcs_vport_offline(vport);
768 }
769
770 bfa_fcs_port_offline(&fabric->bport);
771
772 fabric->fabric_name = 0;
773 fabric->fabric_ip_addr[0] = 0;
774}
775
776static void
777bfa_fcs_fabric_delay(void *cbarg)
778{
779 struct bfa_fcs_fabric_s *fabric = cbarg;
780
781 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELAYED);
782}
783
784/**
785 * Delete all vports and wait for vport delete completions.
786 */
787static void
788bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric)
789{
790 struct bfa_fcs_vport_s *vport;
791 struct list_head *qe, *qen;
792
793 list_for_each_safe(qe, qen, &fabric->vport_q) {
794 vport = (struct bfa_fcs_vport_s *)qe;
795 bfa_fcs_vport_delete(vport);
796 }
797
798 bfa_fcs_port_delete(&fabric->bport);
799 bfa_wc_wait(&fabric->wc);
800}
801
802static void
803bfa_fcs_fabric_delete_comp(void *cbarg)
804{
805 struct bfa_fcs_fabric_s *fabric = cbarg;
806
807 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELCOMP);
808}
809
810
811
812/**
813 * fcs_fabric_public fabric public functions
814 */
815
816/**
817 * Module initialization
818 */
819void
820bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
821{
822 struct bfa_fcs_fabric_s *fabric;
823
824 fabric = &fcs->fabric;
825 bfa_os_memset(fabric, 0, sizeof(struct bfa_fcs_fabric_s));
826
827 /**
828 * Initialize base fabric.
829 */
830 fabric->fcs = fcs;
831 INIT_LIST_HEAD(&fabric->vport_q);
832 INIT_LIST_HEAD(&fabric->vf_q);
833 fabric->lps = bfa_lps_alloc(fcs->bfa);
834 bfa_assert(fabric->lps);
835
836 /**
837 * Initialize fabric delete completion handler. Fabric deletion is complete
838 * when the last vport delete is complete.
839 */
840 bfa_wc_init(&fabric->wc, bfa_fcs_fabric_delete_comp, fabric);
841 bfa_wc_up(&fabric->wc); /* For the base port */
842
843 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
844 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CREATE);
845 bfa_trc(fcs, 0);
846}
847
848/**
849 * Module cleanup
850 */
851void
852bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs)
853{
854 struct bfa_fcs_fabric_s *fabric;
855
856 bfa_trc(fcs, 0);
857
858 /**
859 * Cleanup base fabric.
860 */
861 fabric = &fcs->fabric;
862 bfa_lps_delete(fabric->lps);
863 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELETE);
864}
865
866/**
867 * Fabric module start -- kick starts FCS actions
868 */
869void
870bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs)
871{
872 struct bfa_fcs_fabric_s *fabric;
873
874 bfa_trc(fcs, 0);
875 fabric = &fcs->fabric;
876 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START);
877}
878
879/**
880 * Suspend fabric activity as part of driver suspend.
881 */
882void
883bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs)
884{
885}
886
887bfa_boolean_t
888bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric)
889{
890 return (bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback));
891}
892
893enum bfa_pport_type
894bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric)
895{
896 return fabric->oper_type;
897}
898
899/**
900 * Link up notification from BFA physical port module.
901 */
902void
903bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric)
904{
905 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
906 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_UP);
907}
908
909/**
910 * Link down notification from BFA physical port module.
911 */
912void
913bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric)
914{
915 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
916 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN);
917}
918
919/**
920 * A child vport is being created in the fabric.
921 *
922 * Call from vport module at vport creation. A list of base port and vports
923 * belonging to a fabric is maintained to propagate link events.
924 *
925 * param[in] fabric - Fabric instance. This can be a base fabric or vf.
926 * param[in] vport - Vport being created.
927 *
928 * @return None (always succeeds)
929 */
930void
931bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
932 struct bfa_fcs_vport_s *vport)
933{
934 /**
935 * - add vport to fabric's vport_q
936 */
937 bfa_trc(fabric->fcs, fabric->vf_id);
938
939 list_add_tail(&vport->qe, &fabric->vport_q);
940 fabric->num_vports++;
941 bfa_wc_up(&fabric->wc);
942}
943
944/**
945 * A child vport is being deleted from fabric.
946 *
947 * Vport is being deleted.
948 */
949void
950bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
951 struct bfa_fcs_vport_s *vport)
952{
953 list_del(&vport->qe);
954 fabric->num_vports--;
955 bfa_wc_down(&fabric->wc);
956}
957
958/**
959 * Base port is deleted.
960 */
961void
962bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric)
963{
964 bfa_wc_down(&fabric->wc);
965}
966
967/**
968 * Check if fabric is online.
969 *
970 * param[in] fabric - Fabric instance. This can be a base fabric or vf.
971 *
972 * @return TRUE/FALSE
973 */
974int
975bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric)
976{
977 return (bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_online));
978}
979
980
981bfa_status_t
982bfa_fcs_fabric_addvf(struct bfa_fcs_fabric_s *vf, struct bfa_fcs_s *fcs,
983 struct bfa_port_cfg_s *port_cfg,
984 struct bfad_vf_s *vf_drv)
985{
986 bfa_sm_set_state(vf, bfa_fcs_fabric_sm_uninit);
987 return BFA_STATUS_OK;
988}
989
990/**
991 * Lookup for a vport withing a fabric given its pwwn
992 */
993struct bfa_fcs_vport_s *
994bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
995{
996 struct bfa_fcs_vport_s *vport;
997 struct list_head *qe;
998
999 list_for_each(qe, &fabric->vport_q) {
1000 vport = (struct bfa_fcs_vport_s *)qe;
1001 if (bfa_fcs_port_get_pwwn(&vport->lport) == pwwn)
1002 return vport;
1003 }
1004
1005 return NULL;
1006}
1007
1008/**
1009 * In a given fabric, return the number of lports.
1010 *
1011 * param[in] fabric - Fabric instance. This can be a base fabric or vf.
1012 *
1013* @return : 1 or more.
1014 */
1015u16
1016bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric)
1017{
1018 return (fabric->num_vports);
1019}
1020
1021/**
1022 * Unsolicited frame receive handling.
1023 */
1024void
1025bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1026 u16 len)
1027{
1028 u32 pid = fchs->d_id;
1029 struct bfa_fcs_vport_s *vport;
1030 struct list_head *qe;
1031 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1032 struct fc_logi_s *flogi = (struct fc_logi_s *) els_cmd;
1033
1034 bfa_trc(fabric->fcs, len);
1035 bfa_trc(fabric->fcs, pid);
1036
1037 /**
1038 * Look for our own FLOGI frames being looped back. This means an
1039 * external loopback cable is in place. Our own FLOGI frames are
1040 * sometimes looped back when switch port gets temporarily bypassed.
1041 */
1042 if ((pid == bfa_os_ntoh3b(FC_FABRIC_PORT))
1043 && (els_cmd->els_code == FC_ELS_FLOGI)
1044 && (flogi->port_name == bfa_fcs_port_get_pwwn(&fabric->bport))) {
1045 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK);
1046 return;
1047 }
1048
1049 /**
1050 * FLOGI/EVFP exchanges should be consumed by base fabric.
1051 */
1052 if (fchs->d_id == bfa_os_hton3b(FC_FABRIC_PORT)) {
1053 bfa_trc(fabric->fcs, pid);
1054 bfa_fcs_fabric_process_uf(fabric, fchs, len);
1055 return;
1056 }
1057
1058 if (fabric->bport.pid == pid) {
1059 /**
1060 * All authentication frames should be routed to auth
1061 */
1062 bfa_trc(fabric->fcs, els_cmd->els_code);
1063 if (els_cmd->els_code == FC_ELS_AUTH) {
1064 bfa_trc(fabric->fcs, els_cmd->els_code);
1065 fabric->auth.response = (u8 *) els_cmd;
1066 return;
1067 }
1068
1069 bfa_trc(fabric->fcs, *(u8 *) ((u8 *) fchs));
1070 bfa_fcs_port_uf_recv(&fabric->bport, fchs, len);
1071 return;
1072 }
1073
1074 /**
1075 * look for a matching local port ID
1076 */
1077 list_for_each(qe, &fabric->vport_q) {
1078 vport = (struct bfa_fcs_vport_s *)qe;
1079 if (vport->lport.pid == pid) {
1080 bfa_fcs_port_uf_recv(&vport->lport, fchs, len);
1081 return;
1082 }
1083 }
1084 bfa_trc(fabric->fcs, els_cmd->els_code);
1085 bfa_fcs_port_uf_recv(&fabric->bport, fchs, len);
1086}
1087
1088/**
1089 * Unsolicited frames to be processed by fabric.
1090 */
1091static void
1092bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1093 u16 len)
1094{
1095 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1096
1097 bfa_trc(fabric->fcs, els_cmd->els_code);
1098
1099 switch (els_cmd->els_code) {
1100 case FC_ELS_FLOGI:
1101 bfa_fcs_fabric_process_flogi(fabric, fchs, len);
1102 break;
1103
1104 default:
1105 /*
1106 * need to generate a LS_RJT
1107 */
1108 break;
1109 }
1110}
1111
1112/**
1113 * Process incoming FLOGI
1114 */
1115static void
1116bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
1117 struct fchs_s *fchs, u16 len)
1118{
1119 struct fc_logi_s *flogi = (struct fc_logi_s *) (fchs + 1);
1120 struct bfa_fcs_port_s *bport = &fabric->bport;
1121
1122 bfa_trc(fabric->fcs, fchs->s_id);
1123
1124 fabric->stats.flogi_rcvd++;
1125 /*
1126 * Check port type. It should be 0 = n-port.
1127 */
1128 if (flogi->csp.port_type) {
1129 /*
1130 * @todo: may need to send a LS_RJT
1131 */
1132 bfa_trc(fabric->fcs, flogi->port_name);
1133 fabric->stats.flogi_rejected++;
1134 return;
1135 }
1136
1137 fabric->bb_credit = bfa_os_ntohs(flogi->csp.bbcred);
1138 bport->port_topo.pn2n.rem_port_wwn = flogi->port_name;
1139 bport->port_topo.pn2n.reply_oxid = fchs->ox_id;
1140
1141 /*
1142 * Send a Flogi Acc
1143 */
1144 bfa_fcs_fabric_send_flogi_acc(fabric);
1145 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
1146}
1147
1148static void
1149bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
1150{
1151 struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg;
1152 struct bfa_fcs_port_n2n_s *n2n_port = &fabric->bport.port_topo.pn2n;
1153 struct bfa_s *bfa = fabric->fcs->bfa;
1154 struct bfa_fcxp_s *fcxp;
1155 u16 reqlen;
1156 struct fchs_s fchs;
1157
1158 fcxp = bfa_fcs_fcxp_alloc(fabric->fcs);
1159 /**
1160 * Do not expect this failure -- expect remote node to retry
1161 */
1162 if (!fcxp)
1163 return;
1164
1165 reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1166 bfa_os_hton3b(FC_FABRIC_PORT),
1167 n2n_port->reply_oxid, pcfg->pwwn,
1168 pcfg->nwwn, bfa_pport_get_maxfrsize(bfa),
1169 bfa_pport_get_rx_bbcredit(bfa));
1170
1171 bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps),
1172 BFA_FALSE, FC_CLASS_3, reqlen, &fchs,
1173 bfa_fcs_fabric_flogiacc_comp, fabric,
1174 FC_MAX_PDUSZ, 0); /* Timeout 0 indicates no
1175 * response expected
1176 */
1177}
1178
1179/**
1180 * Flogi Acc completion callback.
1181 */
1182static void
1183bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1184 bfa_status_t status, u32 rsp_len,
1185 u32 resid_len, struct fchs_s *rspfchs)
1186{
1187 struct bfa_fcs_fabric_s *fabric = cbarg;
1188
1189 bfa_trc(fabric->fcs, status);
1190}
1191
1192/*
1193 *
1194 * @param[in] fabric - fabric
1195 * @param[in] result - 1
1196 *
1197 * @return - none
1198 */
1199void
1200bfa_fcs_auth_finished(struct bfa_fcs_fabric_s *fabric, enum auth_status status)
1201{
1202 bfa_trc(fabric->fcs, status);
1203
1204 if (status == FC_AUTH_STATE_SUCCESS)
1205 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_AUTH_SUCCESS);
1206 else
1207 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_AUTH_FAILED);
1208}
1209
1210/**
1211 * Send AEN notification
1212 */
1213static void
1214bfa_fcs_fabric_aen_post(struct bfa_fcs_port_s *port,
1215 enum bfa_port_aen_event event)
1216{
1217 union bfa_aen_data_u aen_data;
1218 struct bfa_log_mod_s *logmod = port->fcs->logm;
1219 wwn_t pwwn = bfa_fcs_port_get_pwwn(port);
1220 wwn_t fwwn = bfa_fcs_port_get_fabric_name(port);
1221 char pwwn_ptr[BFA_STRING_32];
1222 char fwwn_ptr[BFA_STRING_32];
1223
1224 wwn2str(pwwn_ptr, pwwn);
1225 wwn2str(fwwn_ptr, fwwn);
1226
1227 switch (event) {
1228 case BFA_PORT_AEN_FABRIC_NAME_CHANGE:
1229 bfa_log(logmod, BFA_AEN_PORT_FABRIC_NAME_CHANGE, pwwn_ptr,
1230 fwwn_ptr);
1231 break;
1232 default:
1233 break;
1234 }
1235
1236 aen_data.port.pwwn = pwwn;
1237 aen_data.port.fwwn = fwwn;
1238}
1239
1240/*
1241 *
1242 * @param[in] fabric - fabric
1243 * @param[in] wwn_t - new fabric name
1244 *
1245 * @return - none
1246 */
1247void
1248bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
1249 wwn_t fabric_name)
1250{
1251 bfa_trc(fabric->fcs, fabric_name);
1252
1253 if (fabric->fabric_name == 0) {
1254 /*
1255 * With BRCD switches, we don't get Fabric Name in FLOGI.
1256 * Don't generate a fabric name change event in this case.
1257 */
1258 fabric->fabric_name = fabric_name;
1259 } else {
1260 fabric->fabric_name = fabric_name;
1261 /*
1262 * Generate a Event
1263 */
1264 bfa_fcs_fabric_aen_post(&fabric->bport,
1265 BFA_PORT_AEN_FABRIC_NAME_CHANGE);
1266 }
1267
1268}
1269
1270/**
1271 * Not used by FCS.
1272 */
1273void
1274bfa_cb_lps_flogo_comp(void *bfad, void *uarg)
1275{
1276}
1277
1278
diff --git a/drivers/scsi/bfa/fcbuild.c b/drivers/scsi/bfa/fcbuild.c
new file mode 100644
index 000000000000..d174706b9caa
--- /dev/null
+++ b/drivers/scsi/bfa/fcbuild.c
@@ -0,0 +1,1449 @@
1/*
2 * Copyright (c) 2005-2009 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 * fcbuild.c - FC link service frame building and parsing routines
19 */
20
21#include <bfa_os_inc.h>
22#include "fcbuild.h"
23
24/*
25 * static build functions
26 */
27static void fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
28 u16 ox_id);
29static void fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
30 u16 ox_id);
31static struct fchs_s fc_els_req_tmpl;
32static struct fchs_s fc_els_rsp_tmpl;
33static struct fchs_s fc_bls_req_tmpl;
34static struct fchs_s fc_bls_rsp_tmpl;
35static struct fc_ba_acc_s ba_acc_tmpl;
36static struct fc_logi_s plogi_tmpl;
37static struct fc_prli_s prli_tmpl;
38static struct fc_rrq_s rrq_tmpl;
39static struct fchs_s fcp_fchs_tmpl;
40
41void
42fcbuild_init(void)
43{
44 /*
45 * fc_els_req_tmpl
46 */
47 fc_els_req_tmpl.routing = FC_RTG_EXT_LINK;
48 fc_els_req_tmpl.cat_info = FC_CAT_LD_REQUEST;
49 fc_els_req_tmpl.type = FC_TYPE_ELS;
50 fc_els_req_tmpl.f_ctl =
51 bfa_os_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
52 FCTL_SI_XFER);
53 fc_els_req_tmpl.rx_id = FC_RXID_ANY;
54
55 /*
56 * fc_els_rsp_tmpl
57 */
58 fc_els_rsp_tmpl.routing = FC_RTG_EXT_LINK;
59 fc_els_rsp_tmpl.cat_info = FC_CAT_LD_REPLY;
60 fc_els_rsp_tmpl.type = FC_TYPE_ELS;
61 fc_els_rsp_tmpl.f_ctl =
62 bfa_os_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
63 FCTL_END_SEQ | FCTL_SI_XFER);
64 fc_els_rsp_tmpl.rx_id = FC_RXID_ANY;
65
66 /*
67 * fc_bls_req_tmpl
68 */
69 fc_bls_req_tmpl.routing = FC_RTG_BASIC_LINK;
70 fc_bls_req_tmpl.type = FC_TYPE_BLS;
71 fc_bls_req_tmpl.f_ctl = bfa_os_hton3b(FCTL_END_SEQ | FCTL_SI_XFER);
72 fc_bls_req_tmpl.rx_id = FC_RXID_ANY;
73
74 /*
75 * fc_bls_rsp_tmpl
76 */
77 fc_bls_rsp_tmpl.routing = FC_RTG_BASIC_LINK;
78 fc_bls_rsp_tmpl.cat_info = FC_CAT_BA_ACC;
79 fc_bls_rsp_tmpl.type = FC_TYPE_BLS;
80 fc_bls_rsp_tmpl.f_ctl =
81 bfa_os_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
82 FCTL_END_SEQ | FCTL_SI_XFER);
83 fc_bls_rsp_tmpl.rx_id = FC_RXID_ANY;
84
85 /*
86 * ba_acc_tmpl
87 */
88 ba_acc_tmpl.seq_id_valid = 0;
89 ba_acc_tmpl.low_seq_cnt = 0;
90 ba_acc_tmpl.high_seq_cnt = 0xFFFF;
91
92 /*
93 * plogi_tmpl
94 */
95 plogi_tmpl.csp.verhi = FC_PH_VER_PH_3;
96 plogi_tmpl.csp.verlo = FC_PH_VER_4_3;
97 plogi_tmpl.csp.bbcred = bfa_os_htons(0x0004);
98 plogi_tmpl.csp.ciro = 0x1;
99 plogi_tmpl.csp.cisc = 0x0;
100 plogi_tmpl.csp.altbbcred = 0x0;
101 plogi_tmpl.csp.conseq = bfa_os_htons(0x00FF);
102 plogi_tmpl.csp.ro_bitmap = bfa_os_htons(0x0002);
103 plogi_tmpl.csp.e_d_tov = bfa_os_htonl(2000);
104
105 plogi_tmpl.class3.class_valid = 1;
106 plogi_tmpl.class3.sequential = 1;
107 plogi_tmpl.class3.conseq = 0xFF;
108 plogi_tmpl.class3.ospx = 1;
109
110 /*
111 * prli_tmpl
112 */
113 prli_tmpl.command = FC_ELS_PRLI;
114 prli_tmpl.pglen = 0x10;
115 prli_tmpl.pagebytes = bfa_os_htons(0x0014);
116 prli_tmpl.parampage.type = FC_TYPE_FCP;
117 prli_tmpl.parampage.imagepair = 1;
118 prli_tmpl.parampage.servparams.rxrdisab = 1;
119
120 /*
121 * rrq_tmpl
122 */
123 rrq_tmpl.els_cmd.els_code = FC_ELS_RRQ;
124
125 /*
126 * fcp_fchs_tmpl
127 */
128 fcp_fchs_tmpl.routing = FC_RTG_FC4_DEV_DATA;
129 fcp_fchs_tmpl.cat_info = FC_CAT_UNSOLICIT_CMD;
130 fcp_fchs_tmpl.type = FC_TYPE_FCP;
131 fcp_fchs_tmpl.f_ctl =
132 bfa_os_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER);
133 fcp_fchs_tmpl.seq_id = 1;
134 fcp_fchs_tmpl.rx_id = FC_RXID_ANY;
135}
136
137static void
138fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
139 u32 ox_id)
140{
141 bfa_os_memset(fchs, 0, sizeof(struct fchs_s));
142
143 fchs->routing = FC_RTG_FC4_DEV_DATA;
144 fchs->cat_info = FC_CAT_UNSOLICIT_CTRL;
145 fchs->type = FC_TYPE_SERVICES;
146 fchs->f_ctl =
147 bfa_os_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
148 FCTL_SI_XFER);
149 fchs->rx_id = FC_RXID_ANY;
150 fchs->d_id = (d_id);
151 fchs->s_id = (s_id);
152 fchs->ox_id = bfa_os_htons(ox_id);
153
154 /**
155 * @todo no need to set ox_id for request
156 * no need to set rx_id for response
157 */
158}
159
160void
161fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
162 u16 ox_id)
163{
164 bfa_os_memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s));
165 fchs->d_id = (d_id);
166 fchs->s_id = (s_id);
167 fchs->ox_id = bfa_os_htons(ox_id);
168}
169
170static void
171fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
172 u16 ox_id)
173{
174 bfa_os_memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s));
175 fchs->d_id = d_id;
176 fchs->s_id = s_id;
177 fchs->ox_id = ox_id;
178}
179
180enum fc_parse_status
181fc_els_rsp_parse(struct fchs_s *fchs, int len)
182{
183 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
184 struct fc_ls_rjt_s *ls_rjt = (struct fc_ls_rjt_s *) els_cmd;
185
186 len = len;
187
188 switch (els_cmd->els_code) {
189 case FC_ELS_LS_RJT:
190 if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
191 return (FC_PARSE_BUSY);
192 else
193 return (FC_PARSE_FAILURE);
194
195 case FC_ELS_ACC:
196 return (FC_PARSE_OK);
197 }
198 return (FC_PARSE_OK);
199}
200
201static void
202fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
203 u16 ox_id)
204{
205 bfa_os_memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s));
206 fchs->d_id = d_id;
207 fchs->s_id = s_id;
208 fchs->ox_id = ox_id;
209}
210
211static u16
212fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
213 u16 ox_id, wwn_t port_name, wwn_t node_name,
214 u16 pdu_size, u8 els_code)
215{
216 struct fc_logi_s *plogi = (struct fc_logi_s *) (pld);
217
218 bfa_os_memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s));
219
220 plogi->els_cmd.els_code = els_code;
221 if (els_code == FC_ELS_PLOGI)
222 fc_els_req_build(fchs, d_id, s_id, ox_id);
223 else
224 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
225
226 plogi->csp.rxsz = plogi->class3.rxsz = bfa_os_htons(pdu_size);
227
228 bfa_os_memcpy(&plogi->port_name, &port_name, sizeof(wwn_t));
229 bfa_os_memcpy(&plogi->node_name, &node_name, sizeof(wwn_t));
230
231 return (sizeof(struct fc_logi_s));
232}
233
234u16
235fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
236 u16 ox_id, wwn_t port_name, wwn_t node_name,
237 u16 pdu_size, u8 set_npiv, u8 set_auth,
238 u16 local_bb_credits)
239{
240 u32 d_id = bfa_os_hton3b(FC_FABRIC_PORT);
241 u32 *vvl_info;
242
243 bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
244
245 flogi->els_cmd.els_code = FC_ELS_FLOGI;
246 fc_els_req_build(fchs, d_id, s_id, ox_id);
247
248 flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size);
249 flogi->port_name = port_name;
250 flogi->node_name = node_name;
251
252 /*
253 * Set the NPIV Capability Bit ( word 1, bit 31) of Common
254 * Service Parameters.
255 */
256 flogi->csp.ciro = set_npiv;
257
258 /* set AUTH capability */
259 flogi->csp.security = set_auth;
260
261 flogi->csp.bbcred = bfa_os_htons(local_bb_credits);
262
263 /* Set brcd token in VVL */
264 vvl_info = (u32 *)&flogi->vvl[0];
265
266 /* set the flag to indicate the presence of VVL */
267 flogi->csp.npiv_supp = 1; /* @todo. field name is not correct */
268 vvl_info[0] = bfa_os_htonl(FLOGI_VVL_BRCD);
269
270 return (sizeof(struct fc_logi_s));
271}
272
273u16
274fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
275 u16 ox_id, wwn_t port_name, wwn_t node_name,
276 u16 pdu_size, u16 local_bb_credits)
277{
278 u32 d_id = 0;
279
280 bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
281 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
282
283 flogi->els_cmd.els_code = FC_ELS_ACC;
284 flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size);
285 flogi->port_name = port_name;
286 flogi->node_name = node_name;
287
288 flogi->csp.bbcred = bfa_os_htons(local_bb_credits);
289
290 return (sizeof(struct fc_logi_s));
291}
292
293u16
294fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
295 u16 ox_id, wwn_t port_name, wwn_t node_name,
296 u16 pdu_size)
297{
298 u32 d_id = bfa_os_hton3b(FC_FABRIC_PORT);
299
300 bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
301
302 flogi->els_cmd.els_code = FC_ELS_FDISC;
303 fc_els_req_build(fchs, d_id, s_id, ox_id);
304
305 flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size);
306 flogi->port_name = port_name;
307 flogi->node_name = node_name;
308
309 return (sizeof(struct fc_logi_s));
310}
311
312u16
313fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
314 u16 ox_id, wwn_t port_name, wwn_t node_name,
315 u16 pdu_size)
316{
317 return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
318 node_name, pdu_size, FC_ELS_PLOGI);
319}
320
321u16
322fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
323 u16 ox_id, wwn_t port_name, wwn_t node_name,
324 u16 pdu_size)
325{
326 return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
327 node_name, pdu_size, FC_ELS_ACC);
328}
329
330enum fc_parse_status
331fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
332{
333 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
334 struct fc_logi_s *plogi;
335 struct fc_ls_rjt_s *ls_rjt;
336
337 switch (els_cmd->els_code) {
338 case FC_ELS_LS_RJT:
339 ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1);
340 if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
341 return (FC_PARSE_BUSY);
342 else
343 return (FC_PARSE_FAILURE);
344 case FC_ELS_ACC:
345 plogi = (struct fc_logi_s *) (fchs + 1);
346 if (len < sizeof(struct fc_logi_s))
347 return (FC_PARSE_FAILURE);
348
349 if (!wwn_is_equal(plogi->port_name, port_name))
350 return (FC_PARSE_FAILURE);
351
352 if (!plogi->class3.class_valid)
353 return (FC_PARSE_FAILURE);
354
355 if (bfa_os_ntohs(plogi->class3.rxsz) < (FC_MIN_PDUSZ))
356 return (FC_PARSE_FAILURE);
357
358 return (FC_PARSE_OK);
359 default:
360 return (FC_PARSE_FAILURE);
361 }
362}
363
364enum fc_parse_status
365fc_plogi_parse(struct fchs_s *fchs)
366{
367 struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1);
368
369 if (plogi->class3.class_valid != 1)
370 return FC_PARSE_FAILURE;
371
372 if ((bfa_os_ntohs(plogi->class3.rxsz) < FC_MIN_PDUSZ)
373 || (bfa_os_ntohs(plogi->class3.rxsz) > FC_MAX_PDUSZ)
374 || (plogi->class3.rxsz == 0))
375 return (FC_PARSE_FAILURE);
376
377 return FC_PARSE_OK;
378}
379
380u16
381fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
382 u16 ox_id)
383{
384 struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
385
386 fc_els_req_build(fchs, d_id, s_id, ox_id);
387 bfa_os_memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
388
389 prli->command = FC_ELS_PRLI;
390 prli->parampage.servparams.initiator = 1;
391 prli->parampage.servparams.retry = 1;
392 prli->parampage.servparams.rec_support = 1;
393 prli->parampage.servparams.task_retry_id = 0;
394 prli->parampage.servparams.confirm = 1;
395
396 return (sizeof(struct fc_prli_s));
397}
398
399u16
400fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
401 u16 ox_id, enum bfa_port_role role)
402{
403 struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
404
405 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
406 bfa_os_memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
407
408 prli->command = FC_ELS_ACC;
409
410 if ((role & BFA_PORT_ROLE_FCP_TM) == BFA_PORT_ROLE_FCP_TM)
411 prli->parampage.servparams.target = 1;
412 else
413 prli->parampage.servparams.initiator = 1;
414
415 prli->parampage.rspcode = FC_PRLI_ACC_XQTD;
416
417 return (sizeof(struct fc_prli_s));
418}
419
420enum fc_parse_status
421fc_prli_rsp_parse(struct fc_prli_s *prli, int len)
422{
423 if (len < sizeof(struct fc_prli_s))
424 return (FC_PARSE_FAILURE);
425
426 if (prli->command != FC_ELS_ACC)
427 return (FC_PARSE_FAILURE);
428
429 if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD)
430 && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG))
431 return (FC_PARSE_FAILURE);
432
433 if (prli->parampage.servparams.target != 1)
434 return (FC_PARSE_FAILURE);
435
436 return (FC_PARSE_OK);
437}
438
439enum fc_parse_status
440fc_prli_parse(struct fc_prli_s *prli)
441{
442 if (prli->parampage.type != FC_TYPE_FCP)
443 return (FC_PARSE_FAILURE);
444
445 if (!prli->parampage.imagepair)
446 return (FC_PARSE_FAILURE);
447
448 if (!prli->parampage.servparams.initiator)
449 return (FC_PARSE_FAILURE);
450
451 return (FC_PARSE_OK);
452}
453
454u16
455fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id,
456 u32 s_id, u16 ox_id, wwn_t port_name)
457{
458 fc_els_req_build(fchs, d_id, s_id, ox_id);
459
460 memset(logo, '\0', sizeof(struct fc_logo_s));
461 logo->els_cmd.els_code = FC_ELS_LOGO;
462 logo->nport_id = (s_id);
463 logo->orig_port_name = port_name;
464
465 return (sizeof(struct fc_logo_s));
466}
467
468static u16
469fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
470 u32 s_id, u16 ox_id, wwn_t port_name,
471 wwn_t node_name, u8 els_code)
472{
473 memset(adisc, '\0', sizeof(struct fc_adisc_s));
474
475 adisc->els_cmd.els_code = els_code;
476
477 if (els_code == FC_ELS_ADISC)
478 fc_els_req_build(fchs, d_id, s_id, ox_id);
479 else
480 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
481
482 adisc->orig_HA = 0;
483 adisc->orig_port_name = port_name;
484 adisc->orig_node_name = node_name;
485 adisc->nport_id = (s_id);
486
487 return (sizeof(struct fc_adisc_s));
488}
489
490u16
491fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
492 u32 s_id, u16 ox_id, wwn_t port_name,
493 wwn_t node_name)
494{
495 return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
496 node_name, FC_ELS_ADISC);
497}
498
499u16
500fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
501 u32 s_id, u16 ox_id, wwn_t port_name,
502 wwn_t node_name)
503{
504 return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
505 node_name, FC_ELS_ACC);
506}
507
508enum fc_parse_status
509fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, wwn_t port_name,
510 wwn_t node_name)
511{
512
513 if (len < sizeof(struct fc_adisc_s))
514 return (FC_PARSE_FAILURE);
515
516 if (adisc->els_cmd.els_code != FC_ELS_ACC)
517 return (FC_PARSE_FAILURE);
518
519 if (!wwn_is_equal(adisc->orig_port_name, port_name))
520 return (FC_PARSE_FAILURE);
521
522 return (FC_PARSE_OK);
523}
524
525enum fc_parse_status
526fc_adisc_parse(struct fchs_s *fchs, void *pld, u32 host_dap,
527 wwn_t node_name, wwn_t port_name)
528{
529 struct fc_adisc_s *adisc = (struct fc_adisc_s *) pld;
530
531 if (adisc->els_cmd.els_code != FC_ELS_ACC)
532 return (FC_PARSE_FAILURE);
533
534 if ((adisc->nport_id == (host_dap))
535 && wwn_is_equal(adisc->orig_port_name, port_name)
536 && wwn_is_equal(adisc->orig_node_name, node_name))
537 return (FC_PARSE_OK);
538
539 return (FC_PARSE_FAILURE);
540}
541
542enum fc_parse_status
543fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name)
544{
545 struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
546
547 if (pdisc->class3.class_valid != 1)
548 return FC_PARSE_FAILURE;
549
550 if ((bfa_os_ntohs(pdisc->class3.rxsz) <
551 (FC_MIN_PDUSZ - sizeof(struct fchs_s)))
552 || (pdisc->class3.rxsz == 0))
553 return (FC_PARSE_FAILURE);
554
555 if (!wwn_is_equal(pdisc->port_name, port_name))
556 return (FC_PARSE_FAILURE);
557
558 if (!wwn_is_equal(pdisc->node_name, node_name))
559 return (FC_PARSE_FAILURE);
560
561 return FC_PARSE_OK;
562}
563
564u16
565fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
566{
567 bfa_os_memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s));
568 fchs->cat_info = FC_CAT_ABTS;
569 fchs->d_id = (d_id);
570 fchs->s_id = (s_id);
571 fchs->ox_id = bfa_os_htons(ox_id);
572
573 return (sizeof(struct fchs_s));
574}
575
576enum fc_parse_status
577fc_abts_rsp_parse(struct fchs_s *fchs, int len)
578{
579 if ((fchs->cat_info == FC_CAT_BA_ACC)
580 || (fchs->cat_info == FC_CAT_BA_RJT))
581 return (FC_PARSE_OK);
582
583 return (FC_PARSE_FAILURE);
584}
585
586u16
587fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id,
588 u32 s_id, u16 ox_id, u16 rrq_oxid)
589{
590 fc_els_req_build(fchs, d_id, s_id, ox_id);
591
592 /*
593 * build rrq payload
594 */
595 bfa_os_memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s));
596 rrq->s_id = (s_id);
597 rrq->ox_id = bfa_os_htons(rrq_oxid);
598 rrq->rx_id = FC_RXID_ANY;
599
600 return (sizeof(struct fc_rrq_s));
601}
602
603u16
604fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
605 u16 ox_id)
606{
607 struct fc_els_cmd_s *acc = pld;
608
609 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
610
611 memset(acc, 0, sizeof(struct fc_els_cmd_s));
612 acc->els_code = FC_ELS_ACC;
613
614 return (sizeof(struct fc_els_cmd_s));
615}
616
617u16
618fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id,
619 u32 s_id, u16 ox_id, u8 reason_code,
620 u8 reason_code_expl)
621{
622 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
623 memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s));
624
625 ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT;
626 ls_rjt->reason_code = reason_code;
627 ls_rjt->reason_code_expl = reason_code_expl;
628 ls_rjt->vendor_unique = 0x00;
629
630 return (sizeof(struct fc_ls_rjt_s));
631}
632
633u16
634fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
635 u32 s_id, u16 ox_id, u16 rx_id)
636{
637 fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
638
639 bfa_os_memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s));
640
641 fchs->rx_id = rx_id;
642
643 ba_acc->ox_id = fchs->ox_id;
644 ba_acc->rx_id = fchs->rx_id;
645
646 return (sizeof(struct fc_ba_acc_s));
647}
648
649u16
650fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd,
651 u32 d_id, u32 s_id, u16 ox_id)
652{
653 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
654 memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
655 els_cmd->els_code = FC_ELS_ACC;
656
657 return (sizeof(struct fc_els_cmd_s));
658}
659
660int
661fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code)
662{
663 int num_pages = 0;
664 struct fc_prlo_s *prlo;
665 struct fc_tprlo_s *tprlo;
666
667 if (els_code == FC_ELS_PRLO) {
668 prlo = (struct fc_prlo_s *) (fc_frame + 1);
669 num_pages = (bfa_os_ntohs(prlo->payload_len) - 4) / 16;
670 } else {
671 tprlo = (struct fc_tprlo_s *) (fc_frame + 1);
672 num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16;
673 }
674 return num_pages;
675}
676
677u16
678fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
679 u32 d_id, u32 s_id, u16 ox_id,
680 int num_pages)
681{
682 int page;
683
684 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
685
686 memset(tprlo_acc, 0, (num_pages * 16) + 4);
687 tprlo_acc->command = FC_ELS_ACC;
688
689 tprlo_acc->page_len = 0x10;
690 tprlo_acc->payload_len = bfa_os_htons((num_pages * 16) + 4);
691
692 for (page = 0; page < num_pages; page++) {
693 tprlo_acc->tprlo_acc_params[page].opa_valid = 0;
694 tprlo_acc->tprlo_acc_params[page].rpa_valid = 0;
695 tprlo_acc->tprlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
696 tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0;
697 tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0;
698 }
699 return (bfa_os_ntohs(tprlo_acc->payload_len));
700}
701
702u16
703fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc,
704 u32 d_id, u32 s_id, u16 ox_id,
705 int num_pages)
706{
707 int page;
708
709 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
710
711 memset(prlo_acc, 0, (num_pages * 16) + 4);
712 prlo_acc->command = FC_ELS_ACC;
713 prlo_acc->page_len = 0x10;
714 prlo_acc->payload_len = bfa_os_htons((num_pages * 16) + 4);
715
716 for (page = 0; page < num_pages; page++) {
717 prlo_acc->prlo_acc_params[page].opa_valid = 0;
718 prlo_acc->prlo_acc_params[page].rpa_valid = 0;
719 prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
720 prlo_acc->prlo_acc_params[page].orig_process_assc = 0;
721 prlo_acc->prlo_acc_params[page].resp_process_assc = 0;
722 }
723
724 return (bfa_os_ntohs(prlo_acc->payload_len));
725}
726
727u16
728fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id,
729 u32 s_id, u16 ox_id, u32 data_format)
730{
731 fc_els_req_build(fchs, d_id, s_id, ox_id);
732
733 memset(rnid, 0, sizeof(struct fc_rnid_cmd_s));
734
735 rnid->els_cmd.els_code = FC_ELS_RNID;
736 rnid->node_id_data_format = data_format;
737
738 return (sizeof(struct fc_rnid_cmd_s));
739}
740
741u16
742fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc,
743 u32 d_id, u32 s_id, u16 ox_id,
744 u32 data_format,
745 struct fc_rnid_common_id_data_s *common_id_data,
746 struct fc_rnid_general_topology_data_s *gen_topo_data)
747{
748 memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s));
749
750 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
751
752 rnid_acc->els_cmd.els_code = FC_ELS_ACC;
753 rnid_acc->node_id_data_format = data_format;
754 rnid_acc->common_id_data_length =
755 sizeof(struct fc_rnid_common_id_data_s);
756 rnid_acc->common_id_data = *common_id_data;
757
758 if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
759 rnid_acc->specific_id_data_length =
760 sizeof(struct fc_rnid_general_topology_data_s);
761 bfa_os_assign(rnid_acc->gen_topology_data, *gen_topo_data);
762 return (sizeof(struct fc_rnid_acc_s));
763 } else {
764 return (sizeof(struct fc_rnid_acc_s) -
765 sizeof(struct fc_rnid_general_topology_data_s));
766 }
767
768}
769
770u16
771fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id,
772 u32 s_id, u16 ox_id)
773{
774 fc_els_req_build(fchs, d_id, s_id, ox_id);
775
776 memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s));
777
778 rpsc->els_cmd.els_code = FC_ELS_RPSC;
779 return (sizeof(struct fc_rpsc_cmd_s));
780}
781
782u16
783fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2,
784 u32 d_id, u32 s_id, u32 *pid_list,
785 u16 npids)
786{
787 u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_os_hton3b(d_id));
788 int i = 0;
789
790 fc_els_req_build(fchs, bfa_os_hton3b(dctlr_id), s_id, 0);
791
792 memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s));
793
794 rpsc2->els_cmd.els_code = FC_ELS_RPSC;
795 rpsc2->token = bfa_os_htonl(FC_BRCD_TOKEN);
796 rpsc2->num_pids = bfa_os_htons(npids);
797 for (i = 0; i < npids; i++)
798 rpsc2->pid_list[i].pid = pid_list[i];
799
800 return (sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) *
801 (sizeof(u32))));
802}
803
804u16
805fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
806 u32 d_id, u32 s_id, u16 ox_id,
807 struct fc_rpsc_speed_info_s *oper_speed)
808{
809 memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s));
810
811 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
812
813 rpsc_acc->command = FC_ELS_ACC;
814 rpsc_acc->num_entries = bfa_os_htons(1);
815
816 rpsc_acc->speed_info[0].port_speed_cap =
817 bfa_os_htons(oper_speed->port_speed_cap);
818
819 rpsc_acc->speed_info[0].port_op_speed =
820 bfa_os_htons(oper_speed->port_op_speed);
821
822 return (sizeof(struct fc_rpsc_acc_s));
823
824}
825
826/*
827 * TBD -
828 * . get rid of unnecessary memsets
829 */
830
831u16
832fc_logo_rsp_parse(struct fchs_s *fchs, int len)
833{
834 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
835
836 len = len;
837 if (els_cmd->els_code != FC_ELS_ACC)
838 return FC_PARSE_FAILURE;
839
840 return FC_PARSE_OK;
841}
842
843u16
844fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
845 u16 ox_id, wwn_t port_name, wwn_t node_name,
846 u16 pdu_size)
847{
848 struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
849
850 bfa_os_memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s));
851
852 pdisc->els_cmd.els_code = FC_ELS_PDISC;
853 fc_els_req_build(fchs, d_id, s_id, ox_id);
854
855 pdisc->csp.rxsz = pdisc->class3.rxsz = bfa_os_htons(pdu_size);
856 pdisc->port_name = port_name;
857 pdisc->node_name = node_name;
858
859 return (sizeof(struct fc_logi_s));
860}
861
862u16
863fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
864{
865 struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
866
867 if (len < sizeof(struct fc_logi_s))
868 return (FC_PARSE_LEN_INVAL);
869
870 if (pdisc->els_cmd.els_code != FC_ELS_ACC)
871 return (FC_PARSE_ACC_INVAL);
872
873 if (!wwn_is_equal(pdisc->port_name, port_name))
874 return (FC_PARSE_PWWN_NOT_EQUAL);
875
876 if (!pdisc->class3.class_valid)
877 return (FC_PARSE_NWWN_NOT_EQUAL);
878
879 if (bfa_os_ntohs(pdisc->class3.rxsz) < (FC_MIN_PDUSZ))
880 return (FC_PARSE_RXSZ_INVAL);
881
882 return (FC_PARSE_OK);
883}
884
885u16
886fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
887 int num_pages)
888{
889 struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1);
890 int page;
891
892 fc_els_req_build(fchs, d_id, s_id, ox_id);
893 memset(prlo, 0, (num_pages * 16) + 4);
894 prlo->command = FC_ELS_PRLO;
895 prlo->page_len = 0x10;
896 prlo->payload_len = bfa_os_htons((num_pages * 16) + 4);
897
898 for (page = 0; page < num_pages; page++) {
899 prlo->prlo_params[page].type = FC_TYPE_FCP;
900 prlo->prlo_params[page].opa_valid = 0;
901 prlo->prlo_params[page].rpa_valid = 0;
902 prlo->prlo_params[page].orig_process_assc = 0;
903 prlo->prlo_params[page].resp_process_assc = 0;
904 }
905
906 return (bfa_os_ntohs(prlo->payload_len));
907}
908
909u16
910fc_prlo_rsp_parse(struct fchs_s *fchs, int len)
911{
912 struct fc_prlo_acc_s *prlo = (struct fc_prlo_acc_s *) (fchs + 1);
913 int num_pages = 0;
914 int page = 0;
915
916 len = len;
917
918 if (prlo->command != FC_ELS_ACC)
919 return (FC_PARSE_FAILURE);
920
921 num_pages = ((bfa_os_ntohs(prlo->payload_len)) - 4) / 16;
922
923 for (page = 0; page < num_pages; page++) {
924 if (prlo->prlo_acc_params[page].type != FC_TYPE_FCP)
925 return FC_PARSE_FAILURE;
926
927 if (prlo->prlo_acc_params[page].opa_valid != 0)
928 return FC_PARSE_FAILURE;
929
930 if (prlo->prlo_acc_params[page].rpa_valid != 0)
931 return FC_PARSE_FAILURE;
932
933 if (prlo->prlo_acc_params[page].orig_process_assc != 0)
934 return FC_PARSE_FAILURE;
935
936 if (prlo->prlo_acc_params[page].resp_process_assc != 0)
937 return FC_PARSE_FAILURE;
938 }
939 return (FC_PARSE_OK);
940
941}
942
943u16
944fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
945 u16 ox_id, int num_pages,
946 enum fc_tprlo_type tprlo_type, u32 tpr_id)
947{
948 struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1);
949 int page;
950
951 fc_els_req_build(fchs, d_id, s_id, ox_id);
952 memset(tprlo, 0, (num_pages * 16) + 4);
953 tprlo->command = FC_ELS_TPRLO;
954 tprlo->page_len = 0x10;
955 tprlo->payload_len = bfa_os_htons((num_pages * 16) + 4);
956
957 for (page = 0; page < num_pages; page++) {
958 tprlo->tprlo_params[page].type = FC_TYPE_FCP;
959 tprlo->tprlo_params[page].opa_valid = 0;
960 tprlo->tprlo_params[page].rpa_valid = 0;
961 tprlo->tprlo_params[page].orig_process_assc = 0;
962 tprlo->tprlo_params[page].resp_process_assc = 0;
963 if (tprlo_type == FC_GLOBAL_LOGO) {
964 tprlo->tprlo_params[page].global_process_logout = 1;
965 } else if (tprlo_type == FC_TPR_LOGO) {
966 tprlo->tprlo_params[page].tpo_nport_valid = 1;
967 tprlo->tprlo_params[page].tpo_nport_id = (tpr_id);
968 }
969 }
970
971 return (bfa_os_ntohs(tprlo->payload_len));
972}
973
974u16
975fc_tprlo_rsp_parse(struct fchs_s *fchs, int len)
976{
977 struct fc_tprlo_acc_s *tprlo = (struct fc_tprlo_acc_s *) (fchs + 1);
978 int num_pages = 0;
979 int page = 0;
980
981 len = len;
982
983 if (tprlo->command != FC_ELS_ACC)
984 return (FC_PARSE_ACC_INVAL);
985
986 num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16;
987
988 for (page = 0; page < num_pages; page++) {
989 if (tprlo->tprlo_acc_params[page].type != FC_TYPE_FCP)
990 return (FC_PARSE_NOT_FCP);
991 if (tprlo->tprlo_acc_params[page].opa_valid != 0)
992 return (FC_PARSE_OPAFLAG_INVAL);
993 if (tprlo->tprlo_acc_params[page].rpa_valid != 0)
994 return (FC_PARSE_RPAFLAG_INVAL);
995 if (tprlo->tprlo_acc_params[page].orig_process_assc != 0)
996 return (FC_PARSE_OPA_INVAL);
997 if (tprlo->tprlo_acc_params[page].resp_process_assc != 0)
998 return (FC_PARSE_RPA_INVAL);
999 }
1000 return (FC_PARSE_OK);
1001}
1002
1003enum fc_parse_status
1004fc_rrq_rsp_parse(struct fchs_s *fchs, int len)
1005{
1006 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1007
1008 len = len;
1009 if (els_cmd->els_code != FC_ELS_ACC)
1010 return FC_PARSE_FAILURE;
1011
1012 return FC_PARSE_OK;
1013}
1014
1015u16
1016fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
1017 u16 ox_id, u32 reason_code,
1018 u32 reason_expl)
1019{
1020 struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1);
1021
1022 fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
1023
1024 fchs->cat_info = FC_CAT_BA_RJT;
1025 ba_rjt->reason_code = reason_code;
1026 ba_rjt->reason_expl = reason_expl;
1027 return (sizeof(struct fc_ba_rjt_s));
1028}
1029
1030static void
1031fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
1032{
1033 bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s));
1034 cthdr->rev_id = CT_GS3_REVISION;
1035 cthdr->gs_type = CT_GSTYPE_DIRSERVICE;
1036 cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER;
1037 cthdr->cmd_rsp_code = bfa_os_htons(cmd_code);
1038}
1039
1040static void
1041fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
1042{
1043 bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s));
1044 cthdr->rev_id = CT_GS3_REVISION;
1045 cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
1046 cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER;
1047 cthdr->cmd_rsp_code = bfa_os_htons(cmd_code);
1048}
1049
1050static void
1051fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code,
1052 u8 sub_type)
1053{
1054 bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s));
1055 cthdr->rev_id = CT_GS3_REVISION;
1056 cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
1057 cthdr->gs_sub_type = sub_type;
1058 cthdr->cmd_rsp_code = bfa_os_htons(cmd_code);
1059}
1060
1061u16
1062fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1063 wwn_t port_name)
1064{
1065
1066 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1067 struct fcgs_gidpn_req_s *gidpn =
1068 (struct fcgs_gidpn_req_s *) (cthdr + 1);
1069 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1070
1071 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1072 fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN);
1073
1074 bfa_os_memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s));
1075 gidpn->port_name = port_name;
1076 return (sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s));
1077}
1078
1079u16
1080fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1081 u32 port_id)
1082{
1083
1084 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1085 fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1);
1086 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1087
1088 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1089 fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID);
1090
1091 bfa_os_memset(gpnid, 0, sizeof(fcgs_gpnid_req_t));
1092 gpnid->dap = port_id;
1093 return (sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s));
1094}
1095
1096u16
1097fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1098 u32 port_id)
1099{
1100
1101 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1102 fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1);
1103 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1104
1105 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1106 fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID);
1107
1108 bfa_os_memset(gnnid, 0, sizeof(fcgs_gnnid_req_t));
1109 gnnid->dap = port_id;
1110 return (sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s));
1111}
1112
1113u16
1114fc_ct_rsp_parse(struct ct_hdr_s *cthdr)
1115{
1116 if (bfa_os_ntohs(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) {
1117 if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY)
1118 return FC_PARSE_BUSY;
1119 else
1120 return FC_PARSE_FAILURE;
1121 }
1122
1123 return FC_PARSE_OK;
1124}
1125
1126u16
1127fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr, u8 set_br_reg,
1128 u32 s_id, u16 ox_id)
1129{
1130 u32 d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER);
1131
1132 fc_els_req_build(fchs, d_id, s_id, ox_id);
1133
1134 bfa_os_memset(scr, 0, sizeof(struct fc_scr_s));
1135 scr->command = FC_ELS_SCR;
1136 scr->reg_func = FC_SCR_REG_FUNC_FULL;
1137 if (set_br_reg)
1138 scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE;
1139
1140 return (sizeof(struct fc_scr_s));
1141}
1142
1143u16
1144fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn, u32 s_id,
1145 u16 ox_id)
1146{
1147 u32 d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER);
1148 u16 payldlen;
1149
1150 fc_els_req_build(fchs, d_id, s_id, ox_id);
1151 rscn->command = FC_ELS_RSCN;
1152 rscn->pagelen = sizeof(rscn->event[0]);
1153
1154 payldlen = sizeof(u32) + rscn->pagelen;
1155 rscn->payldlen = bfa_os_htons(payldlen);
1156
1157 rscn->event[0].format = FC_RSCN_FORMAT_PORTID;
1158 rscn->event[0].portid = s_id;
1159
1160 return (sizeof(struct fc_rscn_pl_s));
1161}
1162
1163u16
1164fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1165 enum bfa_port_role roles)
1166{
1167 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1168 struct fcgs_rftid_req_s *rftid =
1169 (struct fcgs_rftid_req_s *) (cthdr + 1);
1170 u32 type_value, d_id = bfa_os_hton3b(FC_NAME_SERVER);
1171 u8 index;
1172
1173 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1174 fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
1175
1176 bfa_os_memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
1177
1178 rftid->dap = s_id;
1179
1180 /* By default, FCP FC4 Type is registered */
1181 index = FC_TYPE_FCP >> 5;
1182 type_value = 1 << (FC_TYPE_FCP % 32);
1183 rftid->fc4_type[index] = bfa_os_htonl(type_value);
1184
1185 if (roles & BFA_PORT_ROLE_FCP_IPFC) {
1186 index = FC_TYPE_IP >> 5;
1187 type_value = 1 << (FC_TYPE_IP % 32);
1188 rftid->fc4_type[index] |= bfa_os_htonl(type_value);
1189 }
1190
1191 return (sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s));
1192}
1193
1194u16
1195fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id,
1196 u16 ox_id, u8 *fc4_bitmap,
1197 u32 bitmap_size)
1198{
1199 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1200 struct fcgs_rftid_req_s *rftid =
1201 (struct fcgs_rftid_req_s *) (cthdr + 1);
1202 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1203
1204 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1205 fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
1206
1207 bfa_os_memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
1208
1209 rftid->dap = s_id;
1210 bfa_os_memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap,
1211 (bitmap_size < 32 ? bitmap_size : 32));
1212
1213 return (sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s));
1214}
1215
1216u16
1217fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1218 u8 fc4_type, u8 fc4_ftrs)
1219{
1220 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1221 struct fcgs_rffid_req_s *rffid =
1222 (struct fcgs_rffid_req_s *) (cthdr + 1);
1223 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1224
1225 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1226 fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID);
1227
1228 bfa_os_memset(rffid, 0, sizeof(struct fcgs_rffid_req_s));
1229
1230 rffid->dap = s_id;
1231 rffid->fc4ftr_bits = fc4_ftrs;
1232 rffid->fc4_type = fc4_type;
1233
1234 return (sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s));
1235}
1236
1237u16
1238fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1239 u8 *name)
1240{
1241
1242 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1243 struct fcgs_rspnid_req_s *rspnid =
1244 (struct fcgs_rspnid_req_s *) (cthdr + 1);
1245 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1246
1247 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1248 fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID);
1249
1250 bfa_os_memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s));
1251
1252 rspnid->dap = s_id;
1253 rspnid->spn_len = (u8) strlen((char *)name);
1254 strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len);
1255
1256 return (sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s));
1257}
1258
1259u16
1260fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id,
1261 u8 fc4_type)
1262{
1263
1264 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1265 struct fcgs_gidft_req_s *gidft =
1266 (struct fcgs_gidft_req_s *) (cthdr + 1);
1267 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1268
1269 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1270
1271 fc_gs_cthdr_build(cthdr, s_id, GS_GID_FT);
1272
1273 bfa_os_memset(gidft, 0, sizeof(struct fcgs_gidft_req_s));
1274 gidft->fc4_type = fc4_type;
1275 gidft->domain_id = 0;
1276 gidft->area_id = 0;
1277
1278 return (sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s));
1279}
1280
1281u16
1282fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1283 wwn_t port_name)
1284{
1285 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1286 struct fcgs_rpnid_req_s *rpnid =
1287 (struct fcgs_rpnid_req_s *) (cthdr + 1);
1288 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1289
1290 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1291 fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID);
1292
1293 bfa_os_memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s));
1294 rpnid->port_id = port_id;
1295 rpnid->port_name = port_name;
1296
1297 return (sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s));
1298}
1299
1300u16
1301fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1302 wwn_t node_name)
1303{
1304 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1305 struct fcgs_rnnid_req_s *rnnid =
1306 (struct fcgs_rnnid_req_s *) (cthdr + 1);
1307 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1308
1309 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1310 fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID);
1311
1312 bfa_os_memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s));
1313 rnnid->port_id = port_id;
1314 rnnid->node_name = node_name;
1315
1316 return (sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s));
1317}
1318
1319u16
1320fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1321 u32 cos)
1322{
1323 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1324 struct fcgs_rcsid_req_s *rcsid =
1325 (struct fcgs_rcsid_req_s *) (cthdr + 1);
1326 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1327
1328 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1329 fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID);
1330
1331 bfa_os_memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s));
1332 rcsid->port_id = port_id;
1333 rcsid->cos = cos;
1334
1335 return (sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s));
1336}
1337
1338u16
1339fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1340 u8 port_type)
1341{
1342 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1343 struct fcgs_rptid_req_s *rptid =
1344 (struct fcgs_rptid_req_s *) (cthdr + 1);
1345 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1346
1347 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1348 fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID);
1349
1350 bfa_os_memset(rptid, 0, sizeof(struct fcgs_rptid_req_s));
1351 rptid->port_id = port_id;
1352 rptid->port_type = port_type;
1353
1354 return (sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s));
1355}
1356
1357u16
1358fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id)
1359{
1360 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1361 struct fcgs_ganxt_req_s *ganxt =
1362 (struct fcgs_ganxt_req_s *) (cthdr + 1);
1363 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1364
1365 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1366 fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT);
1367
1368 bfa_os_memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s));
1369 ganxt->port_id = port_id;
1370
1371 return (sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s));
1372}
1373
1374/*
1375 * Builds fc hdr and ct hdr for FDMI requests.
1376 */
1377u16
1378fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id,
1379 u16 cmd_code)
1380{
1381
1382 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1383 u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER);
1384
1385 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1386 fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code);
1387
1388 return (sizeof(struct ct_hdr_s));
1389}
1390
1391/*
1392 * Given a FC4 Type, this function returns a fc4 type bitmask
1393 */
1394void
1395fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask)
1396{
1397 u8 index;
1398 u32 *ptr = (u32 *) bit_mask;
1399 u32 type_value;
1400
1401 /*
1402 * @todo : Check for bitmask size
1403 */
1404
1405 index = fc4_type >> 5;
1406 type_value = 1 << (fc4_type % 32);
1407 ptr[index] = bfa_os_htonl(type_value);
1408
1409}
1410
1411/*
1412 * GMAL Request
1413 */
1414u16
1415fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
1416{
1417 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1418 fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1);
1419 u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER);
1420
1421 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1422 fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD,
1423 CT_GSSUBTYPE_CFGSERVER);
1424
1425 bfa_os_memset(gmal, 0, sizeof(fcgs_gmal_req_t));
1426 gmal->wwn = wwn;
1427
1428 return (sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t));
1429}
1430
1431/*
1432 * GFN (Get Fabric Name) Request
1433 */
1434u16
1435fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
1436{
1437 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1438 fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1);
1439 u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER);
1440
1441 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1442 fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD,
1443 CT_GSSUBTYPE_CFGSERVER);
1444
1445 bfa_os_memset(gfn, 0, sizeof(fcgs_gfn_req_t));
1446 gfn->wwn = wwn;
1447
1448 return (sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t));
1449}
diff --git a/drivers/scsi/bfa/fcbuild.h b/drivers/scsi/bfa/fcbuild.h
new file mode 100644
index 000000000000..4d248424f7b3
--- /dev/null
+++ b/drivers/scsi/bfa/fcbuild.h
@@ -0,0 +1,273 @@
1/*
2 * Copyright (c) 2005-2009 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 * fcbuild.h - FC link service frame building and parsing routines
19 */
20
21#ifndef __FCBUILD_H__
22#define __FCBUILD_H__
23
24#include <bfa_os_inc.h>
25#include <protocol/fc.h>
26#include <protocol/fcp.h>
27#include <protocol/ct.h>
28#include <defs/bfa_defs_port.h>
29#include <defs/bfa_defs_pport.h>
30
31/*
32 * Utility Macros/functions
33 */
34
35#define fcif_sof_set(_ifhdr, _sof) (_ifhdr)->sof = FC_ ## _sof
36#define fcif_eof_set(_ifhdr, _eof) (_ifhdr)->eof = FC_ ## _eof
37
38#define wwn_is_equal(_wwn1, _wwn2) \
39 (memcmp(&(_wwn1), &(_wwn2), sizeof(wwn_t)) == 0)
40
41#define fc_roundup(_l, _s) (((_l) + ((_s) - 1)) & ~((_s) - 1))
42
43/*
44 * Given the fc response length, this routine will return
45 * the length of the actual payload bytes following the CT header.
46 *
47 * Assumes the input response length does not include the crc, eof, etc.
48 */
49static inline u32
50fc_get_ctresp_pyld_len(u32 resp_len)
51{
52 return (resp_len - sizeof(struct ct_hdr_s));
53}
54
55/*
56 * Convert bfa speed to rpsc speed value.
57 */
58static inline enum bfa_pport_speed
59fc_rpsc_operspeed_to_bfa_speed(enum fc_rpsc_op_speed_s speed)
60{
61 switch (speed) {
62
63 case RPSC_OP_SPEED_1G:
64 return BFA_PPORT_SPEED_1GBPS;
65
66 case RPSC_OP_SPEED_2G:
67 return BFA_PPORT_SPEED_2GBPS;
68
69 case RPSC_OP_SPEED_4G:
70 return BFA_PPORT_SPEED_4GBPS;
71
72 case RPSC_OP_SPEED_8G:
73 return BFA_PPORT_SPEED_8GBPS;
74
75 default:
76 return BFA_PPORT_SPEED_UNKNOWN;
77 }
78}
79
80/*
81 * Convert RPSC speed to bfa speed value.
82 */
83static inline enum fc_rpsc_op_speed_s
84fc_bfa_speed_to_rpsc_operspeed(enum bfa_pport_speed op_speed)
85{
86 switch (op_speed) {
87
88 case BFA_PPORT_SPEED_1GBPS:
89 return RPSC_OP_SPEED_1G;
90
91 case BFA_PPORT_SPEED_2GBPS:
92 return RPSC_OP_SPEED_2G;
93
94 case BFA_PPORT_SPEED_4GBPS:
95 return RPSC_OP_SPEED_4G;
96
97 case BFA_PPORT_SPEED_8GBPS:
98 return RPSC_OP_SPEED_8G;
99
100 default:
101 return RPSC_OP_SPEED_NOT_EST;
102 }
103}
104enum fc_parse_status {
105 FC_PARSE_OK = 0,
106 FC_PARSE_FAILURE = 1,
107 FC_PARSE_BUSY = 2,
108 FC_PARSE_LEN_INVAL,
109 FC_PARSE_ACC_INVAL,
110 FC_PARSE_PWWN_NOT_EQUAL,
111 FC_PARSE_NWWN_NOT_EQUAL,
112 FC_PARSE_RXSZ_INVAL,
113 FC_PARSE_NOT_FCP,
114 FC_PARSE_OPAFLAG_INVAL,
115 FC_PARSE_RPAFLAG_INVAL,
116 FC_PARSE_OPA_INVAL,
117 FC_PARSE_RPA_INVAL,
118
119};
120
121struct fc_templates_s {
122 struct fchs_s fc_els_req;
123 struct fchs_s fc_bls_req;
124 struct fc_logi_s plogi;
125 struct fc_rrq_s rrq;
126};
127
128void fcbuild_init(void);
129
130u16 fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi,
131 u32 s_id, u16 ox_id, wwn_t port_name,
132 wwn_t node_name, u16 pdu_size, u8 set_npiv,
133 u8 set_auth, u16 local_bb_credits);
134u16 fc_fdisc_build(struct fchs_s *buf, struct fc_logi_s *flogi,
135 u32 s_id, u16 ox_id, wwn_t port_name,
136 wwn_t node_name, u16 pdu_size);
137u16 fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi,
138 u32 s_id, u16 ox_id, wwn_t port_name,
139 wwn_t node_name, u16 pdu_size,
140 u16 local_bb_credits);
141u16 fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id,
142 u32 s_id, u16 ox_id, wwn_t port_name,
143 wwn_t node_name, u16 pdu_size);
144enum fc_parse_status fc_plogi_parse(struct fchs_s *fchs);
145u16 fc_abts_build(struct fchs_s *buf, u32 d_id, u32 s_id,
146 u16 ox_id);
147enum fc_parse_status fc_abts_rsp_parse(struct fchs_s *buf, int len);
148u16 fc_rrq_build(struct fchs_s *buf, struct fc_rrq_s *rrq, u32 d_id,
149 u32 s_id, u16 ox_id, u16 rrq_oxid);
150enum fc_parse_status fc_rrq_rsp_parse(struct fchs_s *buf, int len);
151u16 fc_rspnid_build(struct fchs_s *fchs, void *pld, u32 s_id,
152 u16 ox_id, u8 *name);
153u16 fc_rftid_build(struct fchs_s *fchs, void *pld, u32 s_id,
154 u16 ox_id, enum bfa_port_role role);
155u16 fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id,
156 u16 ox_id, u8 *fc4_bitmap,
157 u32 bitmap_size);
158u16 fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id,
159 u16 ox_id, u8 fc4_type, u8 fc4_ftrs);
160u16 fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id,
161 u16 ox_id, wwn_t port_name);
162u16 fc_gpnid_build(struct fchs_s *fchs, void *pld, u32 s_id,
163 u16 ox_id, u32 port_id);
164u16 fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr,
165 u8 set_br_reg, u32 s_id, u16 ox_id);
166u16 fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id,
167 u32 s_id, u16 ox_id,
168 wwn_t port_name, wwn_t node_name, u16 pdu_size);
169
170u16 fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc,
171 u32 d_id, u32 s_id, u16 ox_id,
172 wwn_t port_name, wwn_t node_name);
173enum fc_parse_status fc_adisc_parse(struct fchs_s *fchs, void *pld,
174 u32 host_dap,
175 wwn_t node_name, wwn_t port_name);
176enum fc_parse_status fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len,
177 wwn_t port_name, wwn_t node_name);
178u16 fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc,
179 u32 d_id, u32 s_id, u16 ox_id,
180 wwn_t port_name, wwn_t node_name);
181u16 fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt,
182 u32 d_id, u32 s_id, u16 ox_id,
183 u8 reason_code, u8 reason_code_expl);
184u16 fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd,
185 u32 d_id, u32 s_id, u16 ox_id);
186u16 fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id,
187 u32 s_id, u16 ox_id);
188enum fc_parse_status fc_prli_rsp_parse(struct fc_prli_s *prli, int len);
189
190u16 fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id,
191 u32 s_id, u16 ox_id,
192 enum bfa_port_role role);
193u16 fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid,
194 u32 d_id, u32 s_id, u16 ox_id,
195 u32 data_format);
196u16 fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc,
197 u32 d_id, u32 s_id, u16 ox_id,
198 u32 data_format,
199 struct fc_rnid_common_id_data_s *common_id_data,
200 struct fc_rnid_general_topology_data_s *
201 gen_topo_data);
202u16 fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rps2c,
203 u32 d_id, u32 s_id,
204 u32 *pid_list, u16 npids);
205u16 fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc,
206 u32 d_id, u32 s_id, u16 ox_id);
207u16 fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
208 u32 d_id, u32 s_id, u16 ox_id,
209 struct fc_rpsc_speed_info_s *oper_speed);
210u16 fc_gid_ft_build(struct fchs_s *fchs, void *pld, u32 s_id,
211 u8 fc4_type);
212u16 fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id,
213 u32 port_id, wwn_t port_name);
214u16 fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id,
215 u32 port_id, wwn_t node_name);
216u16 fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id,
217 u32 port_id, u32 cos);
218u16 fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id,
219 u32 port_id, u8 port_type);
220u16 fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id,
221 u32 port_id);
222u16 fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo,
223 u32 d_id, u32 s_id, u16 ox_id,
224 wwn_t port_name);
225u16 fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id,
226 u32 s_id, u16 ox_id);
227u16 fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id,
228 u16 cmd_code);
229u16 fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id,
230 wwn_t wwn);
231u16 fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id,
232 wwn_t wwn);
233void fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask);
234void fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
235 u16 ox_id);
236enum fc_parse_status fc_els_rsp_parse(struct fchs_s *fchs, int len);
237enum fc_parse_status fc_plogi_rsp_parse(struct fchs_s *fchs, int len,
238 wwn_t port_name);
239enum fc_parse_status fc_prli_parse(struct fc_prli_s *prli);
240enum fc_parse_status fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name,
241 wwn_t port_name);
242u16 fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc,
243 u32 d_id, u32 s_id, u16 ox_id,
244 u16 rx_id);
245int fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code);
246u16 fc_tprlo_acc_build(struct fchs_s *fchs,
247 struct fc_tprlo_acc_s *tprlo_acc,
248 u32 d_id, u32 s_id, u16 ox_id,
249 int num_pages);
250u16 fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc,
251 u32 d_id, u32 s_id, u16 ox_id,
252 int num_pages);
253u16 fc_logo_rsp_parse(struct fchs_s *fchs, int len);
254u16 fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
255 u16 ox_id, wwn_t port_name, wwn_t node_name,
256 u16 pdu_size);
257u16 fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name);
258u16 fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
259 u16 ox_id, int num_pages);
260u16 fc_prlo_rsp_parse(struct fchs_s *fchs, int len);
261u16 fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
262 u16 ox_id, int num_pages,
263 enum fc_tprlo_type tprlo_type, u32 tpr_id);
264u16 fc_tprlo_rsp_parse(struct fchs_s *fchs, int len);
265u16 fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
266 u16 ox_id, u32 reason_code,
267 u32 reason_expl);
268u16 fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id,
269 u16 ox_id, u32 port_id);
270u16 fc_ct_rsp_parse(struct ct_hdr_s *cthdr);
271u16 fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn,
272 u32 s_id, u16 ox_id);
273#endif
diff --git a/drivers/scsi/bfa/fcpim.c b/drivers/scsi/bfa/fcpim.c
new file mode 100644
index 000000000000..8ce5d8934677
--- /dev/null
+++ b/drivers/scsi/bfa/fcpim.c
@@ -0,0 +1,844 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * fcpim.c - FCP initiator mode i-t nexus state machine
20 */
21
22#include <bfa.h>
23#include <bfa_svc.h>
24#include "fcs_fcpim.h"
25#include "fcs_rport.h"
26#include "fcs_lport.h"
27#include "fcs_trcmod.h"
28#include "fcs_fcxp.h"
29#include "fcs.h"
30#include <fcs/bfa_fcs_fcpim.h>
31#include <fcb/bfa_fcb_fcpim.h>
32#include <aen/bfa_aen_itnim.h>
33
34BFA_TRC_FILE(FCS, FCPIM);
35
36/*
37 * forward declarations
38 */
39static void bfa_fcs_itnim_timeout(void *arg);
40static void bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim);
41static void bfa_fcs_itnim_send_prli(void *itnim_cbarg,
42 struct bfa_fcxp_s *fcxp_alloced);
43static void bfa_fcs_itnim_prli_response(void *fcsarg,
44 struct bfa_fcxp_s *fcxp,
45 void *cbarg,
46 bfa_status_t req_status,
47 u32 rsp_len,
48 u32 resid_len,
49 struct fchs_s *rsp_fchs);
50static void bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
51 enum bfa_itnim_aen_event event);
52
53/**
54 * fcs_itnim_sm FCS itnim state machine events
55 */
56
57enum bfa_fcs_itnim_event {
58 BFA_FCS_ITNIM_SM_ONLINE = 1, /* rport online event */
59 BFA_FCS_ITNIM_SM_OFFLINE = 2, /* rport offline */
60 BFA_FCS_ITNIM_SM_FRMSENT = 3, /* prli frame is sent */
61 BFA_FCS_ITNIM_SM_RSP_OK = 4, /* good response */
62 BFA_FCS_ITNIM_SM_RSP_ERROR = 5, /* error response */
63 BFA_FCS_ITNIM_SM_TIMEOUT = 6, /* delay timeout */
64 BFA_FCS_ITNIM_SM_HCB_OFFLINE = 7, /* BFA online callback */
65 BFA_FCS_ITNIM_SM_HCB_ONLINE = 8, /* BFA offline callback */
66 BFA_FCS_ITNIM_SM_INITIATOR = 9, /* rport is initiator */
67 BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */
68 BFA_FCS_ITNIM_SM_PRLO = 11, /* delete event from rport */
69};
70
71static void bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
72 enum bfa_fcs_itnim_event event);
73static void bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
74 enum bfa_fcs_itnim_event event);
75static void bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
76 enum bfa_fcs_itnim_event event);
77static void bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
78 enum bfa_fcs_itnim_event event);
79static void bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
80 enum bfa_fcs_itnim_event event);
81static void bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
82 enum bfa_fcs_itnim_event event);
83static void bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
84 enum bfa_fcs_itnim_event event);
85static void bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
86 enum bfa_fcs_itnim_event event);
87
88static struct bfa_sm_table_s itnim_sm_table[] = {
89 {BFA_SM(bfa_fcs_itnim_sm_offline), BFA_ITNIM_OFFLINE},
90 {BFA_SM(bfa_fcs_itnim_sm_prli_send), BFA_ITNIM_PRLI_SEND},
91 {BFA_SM(bfa_fcs_itnim_sm_prli), BFA_ITNIM_PRLI_SENT},
92 {BFA_SM(bfa_fcs_itnim_sm_prli_retry), BFA_ITNIM_PRLI_RETRY},
93 {BFA_SM(bfa_fcs_itnim_sm_hcb_online), BFA_ITNIM_HCB_ONLINE},
94 {BFA_SM(bfa_fcs_itnim_sm_online), BFA_ITNIM_ONLINE},
95 {BFA_SM(bfa_fcs_itnim_sm_hcb_offline), BFA_ITNIM_HCB_OFFLINE},
96 {BFA_SM(bfa_fcs_itnim_sm_initiator), BFA_ITNIM_INITIATIOR},
97};
98
99/**
100 * fcs_itnim_sm FCS itnim state machine
101 */
102
103static void
104bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
105 enum bfa_fcs_itnim_event event)
106{
107 bfa_trc(itnim->fcs, itnim->rport->pwwn);
108 bfa_trc(itnim->fcs, event);
109
110 switch (event) {
111 case BFA_FCS_ITNIM_SM_ONLINE:
112 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
113 bfa_fcs_itnim_send_prli(itnim, NULL);
114 break;
115
116 case BFA_FCS_ITNIM_SM_OFFLINE:
117 bfa_fcs_rport_itnim_ack(itnim->rport);
118 break;
119
120 case BFA_FCS_ITNIM_SM_INITIATOR:
121 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
122 break;
123
124 case BFA_FCS_ITNIM_SM_DELETE:
125 bfa_fcs_itnim_free(itnim);
126 break;
127
128 default:
129 bfa_assert(0);
130 }
131
132}
133
134static void
135bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
136 enum bfa_fcs_itnim_event event)
137{
138 bfa_trc(itnim->fcs, itnim->rport->pwwn);
139 bfa_trc(itnim->fcs, event);
140
141 switch (event) {
142 case BFA_FCS_ITNIM_SM_FRMSENT:
143 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli);
144 break;
145
146 case BFA_FCS_ITNIM_SM_INITIATOR:
147 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
148 bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
149 break;
150
151 case BFA_FCS_ITNIM_SM_OFFLINE:
152 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
153 bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
154 bfa_fcs_rport_itnim_ack(itnim->rport);
155 break;
156
157 case BFA_FCS_ITNIM_SM_DELETE:
158 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
159 bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
160 bfa_fcs_itnim_free(itnim);
161 break;
162
163 default:
164 bfa_assert(0);
165 }
166}
167
168static void
169bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
170 enum bfa_fcs_itnim_event event)
171{
172 bfa_trc(itnim->fcs, itnim->rport->pwwn);
173 bfa_trc(itnim->fcs, event);
174
175 switch (event) {
176 case BFA_FCS_ITNIM_SM_RSP_OK:
177 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online);
178 bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec);
179 break;
180
181 case BFA_FCS_ITNIM_SM_RSP_ERROR:
182 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_retry);
183 bfa_timer_start(itnim->fcs->bfa, &itnim->timer,
184 bfa_fcs_itnim_timeout, itnim,
185 BFA_FCS_RETRY_TIMEOUT);
186 break;
187
188 case BFA_FCS_ITNIM_SM_OFFLINE:
189 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
190 bfa_fcxp_discard(itnim->fcxp);
191 bfa_fcs_rport_itnim_ack(itnim->rport);
192 break;
193
194 case BFA_FCS_ITNIM_SM_INITIATOR:
195 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
196 /*
197 * dont discard fcxp. accept will reach same state
198 */
199 break;
200
201 case BFA_FCS_ITNIM_SM_DELETE:
202 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
203 bfa_fcxp_discard(itnim->fcxp);
204 bfa_fcs_itnim_free(itnim);
205 break;
206
207 default:
208 bfa_assert(0);
209 }
210}
211
212static void
213bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
214 enum bfa_fcs_itnim_event event)
215{
216 bfa_trc(itnim->fcs, itnim->rport->pwwn);
217 bfa_trc(itnim->fcs, event);
218
219 switch (event) {
220 case BFA_FCS_ITNIM_SM_TIMEOUT:
221 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
222 bfa_fcs_itnim_send_prli(itnim, NULL);
223 break;
224
225 case BFA_FCS_ITNIM_SM_OFFLINE:
226 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
227 bfa_timer_stop(&itnim->timer);
228 bfa_fcs_rport_itnim_ack(itnim->rport);
229 break;
230
231 case BFA_FCS_ITNIM_SM_INITIATOR:
232 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
233 bfa_timer_stop(&itnim->timer);
234 break;
235
236 case BFA_FCS_ITNIM_SM_DELETE:
237 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
238 bfa_timer_stop(&itnim->timer);
239 bfa_fcs_itnim_free(itnim);
240 break;
241
242 default:
243 bfa_assert(0);
244 }
245}
246
247static void
248bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
249 enum bfa_fcs_itnim_event event)
250{
251 bfa_trc(itnim->fcs, itnim->rport->pwwn);
252 bfa_trc(itnim->fcs, event);
253
254 switch (event) {
255 case BFA_FCS_ITNIM_SM_HCB_ONLINE:
256 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_online);
257 bfa_fcb_itnim_online(itnim->itnim_drv);
258 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_ONLINE);
259 break;
260
261 case BFA_FCS_ITNIM_SM_OFFLINE:
262 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
263 bfa_itnim_offline(itnim->bfa_itnim);
264 bfa_fcs_rport_itnim_ack(itnim->rport);
265 break;
266
267 case BFA_FCS_ITNIM_SM_DELETE:
268 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
269 bfa_fcs_itnim_free(itnim);
270 break;
271
272 default:
273 bfa_assert(0);
274 }
275}
276
277static void
278bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
279 enum bfa_fcs_itnim_event event)
280{
281 bfa_trc(itnim->fcs, itnim->rport->pwwn);
282 bfa_trc(itnim->fcs, event);
283
284 switch (event) {
285 case BFA_FCS_ITNIM_SM_OFFLINE:
286 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline);
287 bfa_fcb_itnim_offline(itnim->itnim_drv);
288 bfa_itnim_offline(itnim->bfa_itnim);
289 if (bfa_fcs_port_is_online(itnim->rport->port) == BFA_TRUE) {
290 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_DISCONNECT);
291 } else {
292 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_OFFLINE);
293 }
294 break;
295
296 case BFA_FCS_ITNIM_SM_DELETE:
297 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
298 bfa_fcs_itnim_free(itnim);
299 break;
300
301 default:
302 bfa_assert(0);
303 }
304}
305
306static void
307bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
308 enum bfa_fcs_itnim_event event)
309{
310 bfa_trc(itnim->fcs, itnim->rport->pwwn);
311 bfa_trc(itnim->fcs, event);
312
313 switch (event) {
314 case BFA_FCS_ITNIM_SM_HCB_OFFLINE:
315 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
316 bfa_fcs_rport_itnim_ack(itnim->rport);
317 break;
318
319 case BFA_FCS_ITNIM_SM_DELETE:
320 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
321 bfa_fcs_itnim_free(itnim);
322 break;
323
324 default:
325 bfa_assert(0);
326 }
327}
328
329/*
330 * This state is set when a discovered rport is also in intiator mode.
331 * This ITN is marked as no_op and is not active and will not be truned into
332 * online state.
333 */
334static void
335bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
336 enum bfa_fcs_itnim_event event)
337{
338 bfa_trc(itnim->fcs, itnim->rport->pwwn);
339 bfa_trc(itnim->fcs, event);
340
341 switch (event) {
342 case BFA_FCS_ITNIM_SM_OFFLINE:
343 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
344 bfa_fcs_rport_itnim_ack(itnim->rport);
345 break;
346
347 case BFA_FCS_ITNIM_SM_RSP_ERROR:
348 case BFA_FCS_ITNIM_SM_ONLINE:
349 case BFA_FCS_ITNIM_SM_INITIATOR:
350 break;
351
352 case BFA_FCS_ITNIM_SM_DELETE:
353 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
354 bfa_fcs_itnim_free(itnim);
355 break;
356
357 default:
358 bfa_assert(0);
359 }
360}
361
362
363
364/**
365 * itnim_private FCS ITNIM private interfaces
366 */
367
368static void
369bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
370 enum bfa_itnim_aen_event event)
371{
372 struct bfa_fcs_rport_s *rport = itnim->rport;
373 union bfa_aen_data_u aen_data;
374 struct bfa_log_mod_s *logmod = rport->fcs->logm;
375 wwn_t lpwwn = bfa_fcs_port_get_pwwn(rport->port);
376 wwn_t rpwwn = rport->pwwn;
377 char lpwwn_ptr[BFA_STRING_32];
378 char rpwwn_ptr[BFA_STRING_32];
379
380 /*
381 * Don't post events for well known addresses
382 */
383 if (BFA_FCS_PID_IS_WKA(rport->pid))
384 return;
385
386 wwn2str(lpwwn_ptr, lpwwn);
387 wwn2str(rpwwn_ptr, rpwwn);
388
389 switch (event) {
390 case BFA_ITNIM_AEN_ONLINE:
391 bfa_log(logmod, BFA_AEN_ITNIM_ONLINE, rpwwn_ptr, lpwwn_ptr);
392 break;
393 case BFA_ITNIM_AEN_OFFLINE:
394 bfa_log(logmod, BFA_AEN_ITNIM_OFFLINE, rpwwn_ptr, lpwwn_ptr);
395 break;
396 case BFA_ITNIM_AEN_DISCONNECT:
397 bfa_log(logmod, BFA_AEN_ITNIM_DISCONNECT, rpwwn_ptr, lpwwn_ptr);
398 break;
399 default:
400 break;
401 }
402
403 aen_data.itnim.vf_id = rport->port->fabric->vf_id;
404 aen_data.itnim.ppwwn =
405 bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(itnim->fcs));
406 aen_data.itnim.lpwwn = lpwwn;
407 aen_data.itnim.rpwwn = rpwwn;
408}
409
410static void
411bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced)
412{
413 struct bfa_fcs_itnim_s *itnim = itnim_cbarg;
414 struct bfa_fcs_rport_s *rport = itnim->rport;
415 struct bfa_fcs_port_s *port = rport->port;
416 struct fchs_s fchs;
417 struct bfa_fcxp_s *fcxp;
418 int len;
419
420 bfa_trc(itnim->fcs, itnim->rport->pwwn);
421
422 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
423 if (!fcxp) {
424 itnim->stats.fcxp_alloc_wait++;
425 bfa_fcxp_alloc_wait(port->fcs->bfa, &itnim->fcxp_wqe,
426 bfa_fcs_itnim_send_prli, itnim);
427 return;
428 }
429 itnim->fcxp = fcxp;
430
431 len = fc_prli_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), itnim->rport->pid,
432 bfa_fcs_port_get_fcid(port), 0);
433
434 bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id, port->lp_tag,
435 BFA_FALSE, FC_CLASS_3, len, &fchs,
436 bfa_fcs_itnim_prli_response, (void *)itnim, FC_MAX_PDUSZ,
437 FC_RA_TOV);
438
439 itnim->stats.prli_sent++;
440 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_FRMSENT);
441}
442
443static void
444bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
445 bfa_status_t req_status, u32 rsp_len,
446 u32 resid_len, struct fchs_s *rsp_fchs)
447{
448 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cbarg;
449 struct fc_els_cmd_s *els_cmd;
450 struct fc_prli_s *prli_resp;
451 struct fc_ls_rjt_s *ls_rjt;
452 struct fc_prli_params_s *sparams;
453
454 bfa_trc(itnim->fcs, req_status);
455
456 /*
457 * Sanity Checks
458 */
459 if (req_status != BFA_STATUS_OK) {
460 itnim->stats.prli_rsp_err++;
461 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR);
462 return;
463 }
464
465 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
466
467 if (els_cmd->els_code == FC_ELS_ACC) {
468 prli_resp = (struct fc_prli_s *) els_cmd;
469
470 if (fc_prli_rsp_parse(prli_resp, rsp_len) != FC_PARSE_OK) {
471 bfa_trc(itnim->fcs, rsp_len);
472 /*
473 * Check if this r-port is also in Initiator mode.
474 * If so, we need to set this ITN as a no-op.
475 */
476 if (prli_resp->parampage.servparams.initiator) {
477 bfa_trc(itnim->fcs, prli_resp->parampage.type);
478 itnim->rport->scsi_function =
479 BFA_RPORT_INITIATOR;
480 itnim->stats.prli_rsp_acc++;
481 bfa_sm_send_event(itnim,
482 BFA_FCS_ITNIM_SM_INITIATOR);
483 return;
484 }
485
486 itnim->stats.prli_rsp_parse_err++;
487 return;
488 }
489 itnim->rport->scsi_function = BFA_RPORT_TARGET;
490
491 sparams = &prli_resp->parampage.servparams;
492 itnim->seq_rec = sparams->retry;
493 itnim->rec_support = sparams->rec_support;
494 itnim->task_retry_id = sparams->task_retry_id;
495 itnim->conf_comp = sparams->confirm;
496
497 itnim->stats.prli_rsp_acc++;
498 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_OK);
499 } else {
500 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
501
502 bfa_trc(itnim->fcs, ls_rjt->reason_code);
503 bfa_trc(itnim->fcs, ls_rjt->reason_code_expl);
504
505 itnim->stats.prli_rsp_rjt++;
506 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR);
507 }
508}
509
510static void
511bfa_fcs_itnim_timeout(void *arg)
512{
513 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)arg;
514
515 itnim->stats.timeout++;
516 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_TIMEOUT);
517}
518
519static void
520bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim)
521{
522 bfa_itnim_delete(itnim->bfa_itnim);
523 bfa_fcb_itnim_free(itnim->fcs->bfad, itnim->itnim_drv);
524}
525
526
527
528/**
529 * itnim_public FCS ITNIM public interfaces
530 */
531
532/**
533 * Called by rport when a new rport is created.
534 *
535 * @param[in] rport - remote port.
536 */
537struct bfa_fcs_itnim_s *
538bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport)
539{
540 struct bfa_fcs_port_s *port = rport->port;
541 struct bfa_fcs_itnim_s *itnim;
542 struct bfad_itnim_s *itnim_drv;
543 struct bfa_itnim_s *bfa_itnim;
544
545 /*
546 * call bfad to allocate the itnim
547 */
548 bfa_fcb_itnim_alloc(port->fcs->bfad, &itnim, &itnim_drv);
549 if (itnim == NULL) {
550 bfa_trc(port->fcs, rport->pwwn);
551 return NULL;
552 }
553
554 /*
555 * Initialize itnim
556 */
557 itnim->rport = rport;
558 itnim->fcs = rport->fcs;
559 itnim->itnim_drv = itnim_drv;
560
561 /*
562 * call BFA to create the itnim
563 */
564 bfa_itnim = bfa_itnim_create(port->fcs->bfa, rport->bfa_rport, itnim);
565
566 if (bfa_itnim == NULL) {
567 bfa_trc(port->fcs, rport->pwwn);
568 bfa_fcb_itnim_free(port->fcs->bfad, itnim_drv);
569 bfa_assert(0);
570 return NULL;
571 }
572
573 itnim->bfa_itnim = bfa_itnim;
574 itnim->seq_rec = BFA_FALSE;
575 itnim->rec_support = BFA_FALSE;
576 itnim->conf_comp = BFA_FALSE;
577 itnim->task_retry_id = BFA_FALSE;
578
579 /*
580 * Set State machine
581 */
582 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
583
584 return itnim;
585}
586
587/**
588 * Called by rport to delete the instance of FCPIM.
589 *
590 * @param[in] rport - remote port.
591 */
592void
593bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s *itnim)
594{
595 bfa_trc(itnim->fcs, itnim->rport->pid);
596 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_DELETE);
597}
598
599/**
600 * Notification from rport that PLOGI is complete to initiate FC-4 session.
601 */
602void
603bfa_fcs_itnim_rport_online(struct bfa_fcs_itnim_s *itnim)
604{
605 itnim->stats.onlines++;
606
607 if (!BFA_FCS_PID_IS_WKA(itnim->rport->pid)) {
608 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_ONLINE);
609 } else {
610 /*
611 * For well known addresses, we set the itnim to initiator
612 * state
613 */
614 itnim->stats.initiator++;
615 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_INITIATOR);
616 }
617}
618
619/**
620 * Called by rport to handle a remote device offline.
621 */
622void
623bfa_fcs_itnim_rport_offline(struct bfa_fcs_itnim_s *itnim)
624{
625 itnim->stats.offlines++;
626 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_OFFLINE);
627}
628
629/**
630 * Called by rport when remote port is known to be an initiator from
631 * PRLI received.
632 */
633void
634bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim)
635{
636 bfa_trc(itnim->fcs, itnim->rport->pid);
637 itnim->stats.initiator++;
638 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_INITIATOR);
639}
640
641/**
642 * Called by rport to check if the itnim is online.
643 */
644bfa_status_t
645bfa_fcs_itnim_get_online_state(struct bfa_fcs_itnim_s *itnim)
646{
647 bfa_trc(itnim->fcs, itnim->rport->pid);
648 switch (bfa_sm_to_state(itnim_sm_table, itnim->sm)) {
649 case BFA_ITNIM_ONLINE:
650 case BFA_ITNIM_INITIATIOR:
651 return BFA_STATUS_OK;
652
653 default:
654 return BFA_STATUS_NO_FCPIM_NEXUS;
655
656 }
657}
658
659/**
660 * BFA completion callback for bfa_itnim_online().
661 */
662void
663bfa_cb_itnim_online(void *cbarg)
664{
665 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cbarg;
666
667 bfa_trc(itnim->fcs, itnim->rport->pwwn);
668 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HCB_ONLINE);
669}
670
671/**
672 * BFA completion callback for bfa_itnim_offline().
673 */
674void
675bfa_cb_itnim_offline(void *cb_arg)
676{
677 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg;
678
679 bfa_trc(itnim->fcs, itnim->rport->pwwn);
680 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HCB_OFFLINE);
681}
682
683/**
684 * Mark the beginning of PATH TOV handling. IO completion callbacks
685 * are still pending.
686 */
687void
688bfa_cb_itnim_tov_begin(void *cb_arg)
689{
690 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg;
691
692 bfa_trc(itnim->fcs, itnim->rport->pwwn);
693 bfa_fcb_itnim_tov_begin(itnim->itnim_drv);
694}
695
696/**
697 * Mark the end of PATH TOV handling. All pending IOs are already cleaned up.
698 */
699void
700bfa_cb_itnim_tov(void *cb_arg)
701{
702 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg;
703
704 bfa_trc(itnim->fcs, itnim->rport->pwwn);
705 bfa_fcb_itnim_tov(itnim->itnim_drv);
706}
707
708/**
709 * BFA notification to FCS/driver for second level error recovery.
710 *
711 * Atleast one I/O request has timedout and target is unresponsive to
712 * repeated abort requests. Second level error recovery should be initiated
713 * by starting implicit logout and recovery procedures.
714 */
715void
716bfa_cb_itnim_sler(void *cb_arg)
717{
718 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg;
719
720 itnim->stats.sler++;
721 bfa_trc(itnim->fcs, itnim->rport->pwwn);
722 bfa_fcs_rport_logo_imp(itnim->rport);
723}
724
725struct bfa_fcs_itnim_s *
726bfa_fcs_itnim_lookup(struct bfa_fcs_port_s *port, wwn_t rpwwn)
727{
728 struct bfa_fcs_rport_s *rport;
729 rport = bfa_fcs_rport_lookup(port, rpwwn);
730
731 if (!rport)
732 return NULL;
733
734 bfa_assert(rport->itnim != NULL);
735 return (rport->itnim);
736}
737
738bfa_status_t
739bfa_fcs_itnim_attr_get(struct bfa_fcs_port_s *port, wwn_t rpwwn,
740 struct bfa_itnim_attr_s *attr)
741{
742 struct bfa_fcs_itnim_s *itnim = NULL;
743
744 itnim = bfa_fcs_itnim_lookup(port, rpwwn);
745
746 if (itnim == NULL)
747 return BFA_STATUS_NO_FCPIM_NEXUS;
748
749 attr->state = bfa_sm_to_state(itnim_sm_table, itnim->sm);
750 attr->retry = itnim->seq_rec;
751 attr->rec_support = itnim->rec_support;
752 attr->conf_comp = itnim->conf_comp;
753 attr->task_retry_id = itnim->task_retry_id;
754
755 return BFA_STATUS_OK;
756}
757
758bfa_status_t
759bfa_fcs_itnim_stats_get(struct bfa_fcs_port_s *port, wwn_t rpwwn,
760 struct bfa_itnim_stats_s *stats)
761{
762 struct bfa_fcs_itnim_s *itnim = NULL;
763
764 bfa_assert(port != NULL);
765
766 itnim = bfa_fcs_itnim_lookup(port, rpwwn);
767
768 if (itnim == NULL)
769 return BFA_STATUS_NO_FCPIM_NEXUS;
770
771 bfa_os_memcpy(stats, &itnim->stats, sizeof(struct bfa_itnim_stats_s));
772
773 return BFA_STATUS_OK;
774}
775
776bfa_status_t
777bfa_fcs_itnim_stats_clear(struct bfa_fcs_port_s *port, wwn_t rpwwn)
778{
779 struct bfa_fcs_itnim_s *itnim = NULL;
780
781 bfa_assert(port != NULL);
782
783 itnim = bfa_fcs_itnim_lookup(port, rpwwn);
784
785 if (itnim == NULL)
786 return BFA_STATUS_NO_FCPIM_NEXUS;
787
788 bfa_os_memset(&itnim->stats, 0, sizeof(struct bfa_itnim_stats_s));
789 return BFA_STATUS_OK;
790}
791
792void
793bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs,
794 u16 len)
795{
796 struct fc_els_cmd_s *els_cmd;
797
798 bfa_trc(itnim->fcs, fchs->type);
799
800 if (fchs->type != FC_TYPE_ELS)
801 return;
802
803 els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
804
805 bfa_trc(itnim->fcs, els_cmd->els_code);
806
807 switch (els_cmd->els_code) {
808 case FC_ELS_PRLO:
809 /* bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_PRLO); */
810 break;
811
812 default:
813 bfa_assert(0);
814 }
815}
816
817void
818bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim)
819{
820}
821
822void
823bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim)
824{
825}
826
827/**
828 * Module initialization
829 */
830void
831bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs)
832{
833}
834
835/**
836 * Module cleanup
837 */
838void
839bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs)
840{
841 bfa_fcs_modexit_comp(fcs);
842}
843
844
diff --git a/drivers/scsi/bfa/fcptm.c b/drivers/scsi/bfa/fcptm.c
new file mode 100644
index 000000000000..8c8b08c72e7a
--- /dev/null
+++ b/drivers/scsi/bfa/fcptm.c
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * This file contains dummy FCPTM routines to aid in Initiator Mode only
20 * compilation of OS driver.
21 *
22 */
23
24#include "bfa_os_inc.h"
25#include "fcs_rport.h"
26#include "fcs_fcptm.h"
27#include "fcs/bfa_fcs_rport.h"
28
29struct bfa_fcs_tin_s *
30bfa_fcs_tin_create(struct bfa_fcs_rport_s *rport)
31{
32 return NULL;
33}
34
35void
36bfa_fcs_tin_delete(struct bfa_fcs_tin_s *tin)
37{
38}
39
40void
41bfa_fcs_tin_rport_offline(struct bfa_fcs_tin_s *tin)
42{
43}
44
45void
46bfa_fcs_tin_rport_online(struct bfa_fcs_tin_s *tin)
47{
48}
49
50void
51bfa_fcs_tin_rx_prli(struct bfa_fcs_tin_s *tin, struct fchs_s *fchs, u16 len)
52{
53}
54
55void
56bfa_fcs_fcptm_uf_recv(struct bfa_fcs_tin_s *tin, struct fchs_s *fchs, u16 len)
57{
58}
59
60void
61bfa_fcs_tin_pause(struct bfa_fcs_tin_s *tin)
62{
63}
64
65void
66bfa_fcs_tin_resume(struct bfa_fcs_tin_s *tin)
67{
68}
diff --git a/drivers/scsi/bfa/fcs.h b/drivers/scsi/bfa/fcs.h
new file mode 100644
index 000000000000..deee685e8478
--- /dev/null
+++ b/drivers/scsi/bfa/fcs.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * fcs.h FCS module functions
20 */
21
22
23#ifndef __FCS_H__
24#define __FCS_H__
25
26#define __fcs_min_cfg(__fcs) (__fcs)->min_cfg
27
28void bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs);
29
30#endif /* __FCS_H__ */
diff --git a/drivers/scsi/bfa/fcs_auth.h b/drivers/scsi/bfa/fcs_auth.h
new file mode 100644
index 000000000000..65d155fea3d7
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_auth.h
@@ -0,0 +1,37 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * fcs_uf.h FCS unsolicited frame receive
20 */
21
22
23#ifndef __FCS_AUTH_H__
24#define __FCS_AUTH_H__
25
26#include <fcs/bfa_fcs.h>
27#include <fcs/bfa_fcs_vport.h>
28#include <fcs/bfa_fcs_lport.h>
29
30/*
31 * fcs friend functions: only between fcs modules
32 */
33void bfa_fcs_auth_uf_recv(struct bfa_fcs_fabric_s *fabric, int len);
34void bfa_fcs_auth_start(struct bfa_fcs_fabric_s *fabric);
35void bfa_fcs_auth_stop(struct bfa_fcs_fabric_s *fabric);
36
37#endif /* __FCS_UF_H__ */
diff --git a/drivers/scsi/bfa/fcs_fabric.h b/drivers/scsi/bfa/fcs_fabric.h
new file mode 100644
index 000000000000..eee960820f86
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_fabric.h
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * fcs_lport.h FCS logical port interfaces
20 */
21
22#ifndef __FCS_FABRIC_H__
23#define __FCS_FABRIC_H__
24
25#include <fcs/bfa_fcs.h>
26#include <fcs/bfa_fcs_vport.h>
27#include <fcs/bfa_fcs_lport.h>
28
29/*
30* fcs friend functions: only between fcs modules
31 */
32void bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs);
33void bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs);
34void bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs);
35void bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric);
36void bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric);
37void bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
38 struct bfa_fcs_vport_s *vport);
39void bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
40 struct bfa_fcs_vport_s *vport);
41int bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric);
42struct bfa_fcs_vport_s *bfa_fcs_fabric_vport_lookup(
43 struct bfa_fcs_fabric_s *fabric, wwn_t pwwn);
44void bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs);
45void bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric,
46 struct fchs_s *fchs, u16 len);
47u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric);
48bfa_boolean_t bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric);
49enum bfa_pport_type bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric);
50void bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric);
51void bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric);
52
53bfa_status_t bfa_fcs_fabric_addvf(struct bfa_fcs_fabric_s *vf,
54 struct bfa_fcs_s *fcs, struct bfa_port_cfg_s *port_cfg,
55 struct bfad_vf_s *vf_drv);
56void bfa_fcs_auth_finished(struct bfa_fcs_fabric_s *fabric,
57 enum auth_status status);
58
59void bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
60 wwn_t fabric_name);
61#endif /* __FCS_FABRIC_H__ */
diff --git a/drivers/scsi/bfa/fcs_fcpim.h b/drivers/scsi/bfa/fcs_fcpim.h
new file mode 100644
index 000000000000..61e9e2687de3
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_fcpim.h
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __FCS_FCPIM_H__
18#define __FCS_FCPIM_H__
19
20#include <defs/bfa_defs_port.h>
21#include <fcs/bfa_fcs_lport.h>
22#include <fcs/bfa_fcs_rport.h>
23
24/*
25 * Following routines are from FCPIM and will be called by rport.
26 */
27struct bfa_fcs_itnim_s *bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport);
28void bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s *itnim);
29void bfa_fcs_itnim_rport_offline(struct bfa_fcs_itnim_s *itnim);
30void bfa_fcs_itnim_rport_online(struct bfa_fcs_itnim_s *itnim);
31bfa_status_t bfa_fcs_itnim_get_online_state(struct bfa_fcs_itnim_s *itnim);
32
33void bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim);
34void bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim);
35void bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim);
36
37/*
38 * Modudle init/cleanup routines.
39 */
40void bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs);
41void bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs);
42void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs,
43 u16 len);
44#endif /* __FCS_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/fcs_fcptm.h b/drivers/scsi/bfa/fcs_fcptm.h
new file mode 100644
index 000000000000..ffff0829fd31
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_fcptm.h
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __FCS_FCPTM_H__
19#define __FCS_FCPTM_H__
20
21#include <defs/bfa_defs_port.h>
22#include <fcs/bfa_fcs_lport.h>
23#include <fcs/bfa_fcs_rport.h>
24
25/*
26 * Following routines are from FCPTM and will be called by rport.
27 */
28struct bfa_fcs_tin_s *bfa_fcs_tin_create(struct bfa_fcs_rport_s *rport);
29void bfa_fcs_tin_rport_offline(struct bfa_fcs_tin_s *tin);
30void bfa_fcs_tin_rport_online(struct bfa_fcs_tin_s *tin);
31void bfa_fcs_tin_delete(struct bfa_fcs_tin_s *tin);
32void bfa_fcs_tin_rx_prli(struct bfa_fcs_tin_s *tin, struct fchs_s *fchs,
33 u16 len);
34void bfa_fcs_tin_pause(struct bfa_fcs_tin_s *tin);
35void bfa_fcs_tin_resume(struct bfa_fcs_tin_s *tin);
36
37/*
38 * Modudle init/cleanup routines.
39 */
40void bfa_fcs_fcptm_modinit(struct bfa_fcs_s *fcs);
41void bfa_fcs_fcptm_modexit(struct bfa_fcs_s *fcs);
42void bfa_fcs_fcptm_uf_recv(struct bfa_fcs_tin_s *tin, struct fchs_s *fchs,
43 u16 len);
44
45#endif /* __FCS_FCPTM_H__ */
diff --git a/drivers/scsi/bfa/fcs_fcxp.h b/drivers/scsi/bfa/fcs_fcxp.h
new file mode 100644
index 000000000000..8277fe9c2b70
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_fcxp.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * fcs_fcxp.h FCXP helper macros for FCS
20 */
21
22
23#ifndef __FCS_FCXP_H__
24#define __FCS_FCXP_H__
25
26#define bfa_fcs_fcxp_alloc(__fcs) \
27 bfa_fcxp_alloc(NULL, (__fcs)->bfa, 0, 0, NULL, NULL, NULL, NULL)
28
29#endif /* __FCS_FCXP_H__ */
diff --git a/drivers/scsi/bfa/fcs_lport.h b/drivers/scsi/bfa/fcs_lport.h
new file mode 100644
index 000000000000..ae744ba35671
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_lport.h
@@ -0,0 +1,117 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * fcs_lport.h FCS logical port interfaces
20 */
21
22#ifndef __FCS_LPORT_H__
23#define __FCS_LPORT_H__
24
25#define __VPORT_H__
26#include <defs/bfa_defs_port.h>
27#include <bfa_svc.h>
28#include <fcs/bfa_fcs_lport.h>
29#include <fcs/bfa_fcs_rport.h>
30#include <fcs/bfa_fcs_vport.h>
31#include <fcs_fabric.h>
32#include <fcs_ms.h>
33#include <cs/bfa_q.h>
34#include <fcbuild.h>
35
36/*
37 * PID used in P2P/N2N ( In Big Endian)
38 */
39#define N2N_LOCAL_PID 0x010000
40#define N2N_REMOTE_PID 0x020000
41
42/*
43 * Misc Timeouts
44 */
45/*
46 * To be used when spawning a timer before retrying a failed command. Milli
47 * Secs.
48 */
49#define BFA_FCS_RETRY_TIMEOUT 2000
50
51/*
52 * Check for Port/Vport Mode/Role
53 */
54#define BFA_FCS_VPORT_IS_INITIATOR_MODE(port) \
55 (port->port_cfg.roles & BFA_PORT_ROLE_FCP_IM)
56
57#define BFA_FCS_VPORT_IS_TARGET_MODE(port) \
58 (port->port_cfg.roles & BFA_PORT_ROLE_FCP_TM)
59
60#define BFA_FCS_VPORT_IS_IPFC_MODE(port) \
61 (port->port_cfg.roles & BFA_PORT_ROLE_FCP_IPFC)
62
63/*
64 * Is this a Well Known Address
65 */
66#define BFA_FCS_PID_IS_WKA(pid) ((bfa_os_ntoh3b(pid) > 0xFFF000) ? 1 : 0)
67
68/*
69 * Pointer to elements within Port
70 */
71#define BFA_FCS_GET_HAL_FROM_PORT(port) (port->fcs->bfa)
72#define BFA_FCS_GET_NS_FROM_PORT(port) (&port->port_topo.pfab.ns)
73#define BFA_FCS_GET_SCN_FROM_PORT(port) (&port->port_topo.pfab.scn)
74#define BFA_FCS_GET_MS_FROM_PORT(port) (&port->port_topo.pfab.ms)
75#define BFA_FCS_GET_FDMI_FROM_PORT(port) (&port->port_topo.pfab.ms.fdmi)
76
77/*
78 * handler for unsolicied frames
79 */
80void bfa_fcs_port_uf_recv(struct bfa_fcs_port_s *lport, struct fchs_s *fchs,
81 u16 len);
82
83/*
84 * Following routines will be called by Fabric to indicate port
85 * online/offline to vport.
86 */
87void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
88 u16 vf_id, struct bfa_port_cfg_s *port_cfg,
89 struct bfa_fcs_vport_s *vport);
90void bfa_fcs_port_online(struct bfa_fcs_port_s *port);
91void bfa_fcs_port_offline(struct bfa_fcs_port_s *port);
92void bfa_fcs_port_delete(struct bfa_fcs_port_s *port);
93bfa_boolean_t bfa_fcs_port_is_online(struct bfa_fcs_port_s *port);
94
95/*
96 * Lookup rport based on PID
97 */
98struct bfa_fcs_rport_s *bfa_fcs_port_get_rport_by_pid(
99 struct bfa_fcs_port_s *port, u32 pid);
100
101/*
102 * Lookup rport based on PWWN
103 */
104struct bfa_fcs_rport_s *bfa_fcs_port_get_rport_by_pwwn(
105 struct bfa_fcs_port_s *port, wwn_t pwwn);
106struct bfa_fcs_rport_s *bfa_fcs_port_get_rport_by_nwwn(
107 struct bfa_fcs_port_s *port, wwn_t nwwn);
108void bfa_fcs_port_add_rport(struct bfa_fcs_port_s *port,
109 struct bfa_fcs_rport_s *rport);
110void bfa_fcs_port_del_rport(struct bfa_fcs_port_s *port,
111 struct bfa_fcs_rport_s *rport);
112
113void bfa_fcs_port_modinit(struct bfa_fcs_s *fcs);
114void bfa_fcs_port_modexit(struct bfa_fcs_s *fcs);
115void bfa_fcs_port_lip(struct bfa_fcs_port_s *port);
116
117#endif /* __FCS_LPORT_H__ */
diff --git a/drivers/scsi/bfa/fcs_ms.h b/drivers/scsi/bfa/fcs_ms.h
new file mode 100644
index 000000000000..b6a8c12876f4
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_ms.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * fcs_ms.h FCS ms interfaces
20 */
21#ifndef __FCS_MS_H__
22#define __FCS_MS_H__
23
24/* MS FCS routines */
25void bfa_fcs_port_ms_init(struct bfa_fcs_port_s *port);
26void bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port);
27void bfa_fcs_port_ms_online(struct bfa_fcs_port_s *port);
28void bfa_fcs_port_ms_fabric_rscn(struct bfa_fcs_port_s *port);
29
30/* FDMI FCS routines */
31void bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms);
32void bfa_fcs_port_fdmi_offline(struct bfa_fcs_port_ms_s *ms);
33void bfa_fcs_port_fdmi_online(struct bfa_fcs_port_ms_s *ms);
34
35#endif
diff --git a/drivers/scsi/bfa/fcs_port.h b/drivers/scsi/bfa/fcs_port.h
new file mode 100644
index 000000000000..abb65191dd27
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_port.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * fcs_pport.h FCS physical port interfaces
20 */
21
22
23#ifndef __FCS_PPORT_H__
24#define __FCS_PPORT_H__
25
26/*
27 * fcs friend functions: only between fcs modules
28 */
29void bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs);
30void bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs);
31
32#endif /* __FCS_PPORT_H__ */
diff --git a/drivers/scsi/bfa/fcs_rport.h b/drivers/scsi/bfa/fcs_rport.h
new file mode 100644
index 000000000000..f601e9d74236
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_rport.h
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * fcs_rport.h FCS rport interfaces and defines
20 */
21
22#ifndef __FCS_RPORT_H__
23#define __FCS_RPORT_H__
24
25#include <fcs/bfa_fcs_rport.h>
26
27void bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs);
28void bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs);
29
30void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
31 u16 len);
32void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport);
33
34struct bfa_fcs_rport_s *bfa_fcs_rport_create(struct bfa_fcs_port_s *port,
35 u32 pid);
36void bfa_fcs_rport_delete(struct bfa_fcs_rport_s *rport);
37void bfa_fcs_rport_online(struct bfa_fcs_rport_s *rport);
38void bfa_fcs_rport_offline(struct bfa_fcs_rport_s *rport);
39void bfa_fcs_rport_start(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
40 struct fc_logi_s *plogi_rsp);
41void bfa_fcs_rport_plogi_create(struct bfa_fcs_port_s *port,
42 struct fchs_s *rx_fchs,
43 struct fc_logi_s *plogi);
44void bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
45 struct fc_logi_s *plogi);
46void bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport);
47void bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport);
48void bfa_fcs_rport_itntm_ack(struct bfa_fcs_rport_s *rport);
49void bfa_fcs_rport_tin_ack(struct bfa_fcs_rport_s *rport);
50void bfa_fcs_rport_fcptm_offline_done(struct bfa_fcs_rport_s *rport);
51int bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport);
52struct bfa_fcs_rport_s *bfa_fcs_rport_create_by_wwn(struct bfa_fcs_port_s *port,
53 wwn_t wwn);
54
55
56/* Rport Features */
57void bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport);
58void bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport);
59void bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport);
60
61#endif /* __FCS_RPORT_H__ */
diff --git a/drivers/scsi/bfa/fcs_trcmod.h b/drivers/scsi/bfa/fcs_trcmod.h
new file mode 100644
index 000000000000..41b5ae8d7644
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_trcmod.h
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * fcs_trcmod.h BFA FCS trace modules
20 */
21
22#ifndef __FCS_TRCMOD_H__
23#define __FCS_TRCMOD_H__
24
25#include <cs/bfa_trc.h>
26
27/*
28 * !!! Only append to the enums defined here to avoid any versioning
29 * !!! needed between trace utility and driver version
30 */
31enum {
32 BFA_TRC_FCS_FABRIC = 1,
33 BFA_TRC_FCS_VFAPI = 2,
34 BFA_TRC_FCS_PORT = 3,
35 BFA_TRC_FCS_VPORT = 4,
36 BFA_TRC_FCS_VP_API = 5,
37 BFA_TRC_FCS_VPS = 6,
38 BFA_TRC_FCS_RPORT = 7,
39 BFA_TRC_FCS_FCPIM = 8,
40 BFA_TRC_FCS_FCPTM = 9,
41 BFA_TRC_FCS_NS = 10,
42 BFA_TRC_FCS_SCN = 11,
43 BFA_TRC_FCS_LOOP = 12,
44 BFA_TRC_FCS_UF = 13,
45 BFA_TRC_FCS_PPORT = 14,
46 BFA_TRC_FCS_FCPIP = 15,
47 BFA_TRC_FCS_PORT_API = 16,
48 BFA_TRC_FCS_RPORT_API = 17,
49 BFA_TRC_FCS_AUTH = 18,
50 BFA_TRC_FCS_N2N = 19,
51 BFA_TRC_FCS_MS = 20,
52 BFA_TRC_FCS_FDMI = 21,
53 BFA_TRC_FCS_RPORT_FTRS = 22,
54};
55
56#endif /* __FCS_TRCMOD_H__ */
diff --git a/drivers/scsi/bfa/fcs_uf.h b/drivers/scsi/bfa/fcs_uf.h
new file mode 100644
index 000000000000..96f1bdcb31ed
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_uf.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * fcs_uf.h FCS unsolicited frame receive
20 */
21
22
23#ifndef __FCS_UF_H__
24#define __FCS_UF_H__
25
26/*
27 * fcs friend functions: only between fcs modules
28 */
29void bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs);
30void bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs);
31
32#endif /* __FCS_UF_H__ */
diff --git a/drivers/scsi/bfa/fcs_vport.h b/drivers/scsi/bfa/fcs_vport.h
new file mode 100644
index 000000000000..9e80b6a97b7f
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_vport.h
@@ -0,0 +1,39 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __FCS_VPORT_H__
19#define __FCS_VPORT_H__
20
21#include <fcs/bfa_fcs_lport.h>
22#include <fcs/bfa_fcs_vport.h>
23#include <defs/bfa_defs_pci.h>
24
25/*
26 * Modudle init/cleanup routines.
27 */
28
29void bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs);
30void bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs);
31
32void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport);
33void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport);
34void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport);
35void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport);
36u32 bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs);
37
38#endif /* __FCS_VPORT_H__ */
39
diff --git a/drivers/scsi/bfa/fdmi.c b/drivers/scsi/bfa/fdmi.c
new file mode 100644
index 000000000000..b845eb272c78
--- /dev/null
+++ b/drivers/scsi/bfa/fdmi.c
@@ -0,0 +1,1223 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * port_api.c BFA FCS port
20 */
21
22
23#include <bfa.h>
24#include <bfa_svc.h>
25#include "fcs_lport.h"
26#include "fcs_rport.h"
27#include "lport_priv.h"
28#include "fcs_trcmod.h"
29#include "fcs_fcxp.h"
30#include <fcs/bfa_fcs_fdmi.h>
31
32BFA_TRC_FILE(FCS, FDMI);
33
34#define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
35
36/*
37 * forward declarations
38 */
39static void bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg,
40 struct bfa_fcxp_s *fcxp_alloced);
41static void bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg,
42 struct bfa_fcxp_s *fcxp_alloced);
43static void bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg,
44 struct bfa_fcxp_s *fcxp_alloced);
45static void bfa_fcs_port_fdmi_rhba_response(void *fcsarg,
46 struct bfa_fcxp_s *fcxp,
47 void *cbarg,
48 bfa_status_t req_status,
49 u32 rsp_len,
50 u32 resid_len,
51 struct fchs_s *rsp_fchs);
52static void bfa_fcs_port_fdmi_rprt_response(void *fcsarg,
53 struct bfa_fcxp_s *fcxp,
54 void *cbarg,
55 bfa_status_t req_status,
56 u32 rsp_len,
57 u32 resid_len,
58 struct fchs_s *rsp_fchs);
59static void bfa_fcs_port_fdmi_rpa_response(void *fcsarg,
60 struct bfa_fcxp_s *fcxp,
61 void *cbarg,
62 bfa_status_t req_status,
63 u32 rsp_len,
64 u32 resid_len,
65 struct fchs_s *rsp_fchs);
66static void bfa_fcs_port_fdmi_timeout(void *arg);
67static u16 bfa_fcs_port_fdmi_build_rhba_pyld(
68 struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
69static u16 bfa_fcs_port_fdmi_build_rprt_pyld(
70 struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
71static u16 bfa_fcs_port_fdmi_build_rpa_pyld(
72 struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
73static u16 bfa_fcs_port_fdmi_build_portattr_block(
74 struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
75void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
76 struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
77void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
78 struct bfa_fcs_fdmi_port_attr_s *port_attr);
79/**
80 * fcs_fdmi_sm FCS FDMI state machine
81 */
82
83/**
84 * FDMI State Machine events
85 */
86enum port_fdmi_event {
87 FDMISM_EVENT_PORT_ONLINE = 1,
88 FDMISM_EVENT_PORT_OFFLINE = 2,
89 FDMISM_EVENT_RSP_OK = 4,
90 FDMISM_EVENT_RSP_ERROR = 5,
91 FDMISM_EVENT_TIMEOUT = 6,
92 FDMISM_EVENT_RHBA_SENT = 7,
93 FDMISM_EVENT_RPRT_SENT = 8,
94 FDMISM_EVENT_RPA_SENT = 9,
95};
96
97static void bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi,
98 enum port_fdmi_event event);
99static void bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
100 enum port_fdmi_event event);
101static void bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
102 enum port_fdmi_event event);
103static void bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi,
104 enum port_fdmi_event event);
105static void bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
106 enum port_fdmi_event event);
107static void bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
108 enum port_fdmi_event event);
109static void bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi,
110 enum port_fdmi_event event);
111static void bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
112 enum port_fdmi_event event);
113static void bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
114 enum port_fdmi_event event);
115static void bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
116 enum port_fdmi_event event);
117static void bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
118 enum port_fdmi_event event);
119/**
120 * Start in offline state - awaiting MS to send start.
121 */
122static void
123bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi,
124 enum port_fdmi_event event)
125{
126 struct bfa_fcs_port_s *port = fdmi->ms->port;
127
128 bfa_trc(port->fcs, port->port_cfg.pwwn);
129 bfa_trc(port->fcs, event);
130
131 fdmi->retry_cnt = 0;
132
133 switch (event) {
134 case FDMISM_EVENT_PORT_ONLINE:
135 if (port->vport) {
136 /*
137 * For Vports, register a new port.
138 */
139 bfa_sm_set_state(fdmi,
140 bfa_fcs_port_fdmi_sm_sending_rprt);
141 bfa_fcs_port_fdmi_send_rprt(fdmi, NULL);
142 } else {
143 /*
144 * For a base port, we should first register the HBA
145 * atribute. The HBA attribute also contains the base
146 * port registration.
147 */
148 bfa_sm_set_state(fdmi,
149 bfa_fcs_port_fdmi_sm_sending_rhba);
150 bfa_fcs_port_fdmi_send_rhba(fdmi, NULL);
151 }
152 break;
153
154 case FDMISM_EVENT_PORT_OFFLINE:
155 break;
156
157 default:
158 bfa_assert(0);
159 }
160}
161
162static void
163bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
164 enum port_fdmi_event event)
165{
166 struct bfa_fcs_port_s *port = fdmi->ms->port;
167
168 bfa_trc(port->fcs, port->port_cfg.pwwn);
169 bfa_trc(port->fcs, event);
170
171 switch (event) {
172 case FDMISM_EVENT_RHBA_SENT:
173 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rhba);
174 break;
175
176 case FDMISM_EVENT_PORT_OFFLINE:
177 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
178 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
179 &fdmi->fcxp_wqe);
180 break;
181
182 default:
183 bfa_assert(0);
184 }
185}
186
187static void
188bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
189 enum port_fdmi_event event)
190{
191 struct bfa_fcs_port_s *port = fdmi->ms->port;
192
193 bfa_trc(port->fcs, port->port_cfg.pwwn);
194 bfa_trc(port->fcs, event);
195
196 switch (event) {
197 case FDMISM_EVENT_RSP_ERROR:
198 /*
199 * if max retries have not been reached, start timer for a
200 * delayed retry
201 */
202 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
203 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rhba_retry);
204 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
205 &fdmi->timer, bfa_fcs_port_fdmi_timeout,
206 fdmi, BFA_FCS_RETRY_TIMEOUT);
207 } else {
208 /*
209 * set state to offline
210 */
211 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
212 }
213 break;
214
215 case FDMISM_EVENT_RSP_OK:
216 /*
217 * Initiate Register Port Attributes
218 */
219 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa);
220 fdmi->retry_cnt = 0;
221 bfa_fcs_port_fdmi_send_rpa(fdmi, NULL);
222 break;
223
224 case FDMISM_EVENT_PORT_OFFLINE:
225 bfa_fcxp_discard(fdmi->fcxp);
226 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
227 break;
228
229 default:
230 bfa_assert(0);
231 }
232}
233
234static void
235bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi,
236 enum port_fdmi_event event)
237{
238 struct bfa_fcs_port_s *port = fdmi->ms->port;
239
240 bfa_trc(port->fcs, port->port_cfg.pwwn);
241 bfa_trc(port->fcs, event);
242
243 switch (event) {
244 case FDMISM_EVENT_TIMEOUT:
245 /*
246 * Retry Timer Expired. Re-send
247 */
248 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rhba);
249 bfa_fcs_port_fdmi_send_rhba(fdmi, NULL);
250 break;
251
252 case FDMISM_EVENT_PORT_OFFLINE:
253 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
254 bfa_timer_stop(&fdmi->timer);
255 break;
256
257 default:
258 bfa_assert(0);
259 }
260}
261
262/*
263* RPRT : Register Port
264 */
265static void
266bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
267 enum port_fdmi_event event)
268{
269 struct bfa_fcs_port_s *port = fdmi->ms->port;
270
271 bfa_trc(port->fcs, port->port_cfg.pwwn);
272 bfa_trc(port->fcs, event);
273
274 switch (event) {
275 case FDMISM_EVENT_RPRT_SENT:
276 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rprt);
277 break;
278
279 case FDMISM_EVENT_PORT_OFFLINE:
280 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
281 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
282 &fdmi->fcxp_wqe);
283 break;
284
285 default:
286 bfa_assert(0);
287 }
288}
289
290static void
291bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
292 enum port_fdmi_event event)
293{
294 struct bfa_fcs_port_s *port = fdmi->ms->port;
295
296 bfa_trc(port->fcs, port->port_cfg.pwwn);
297 bfa_trc(port->fcs, event);
298
299 switch (event) {
300 case FDMISM_EVENT_RSP_ERROR:
301 /*
302 * if max retries have not been reached, start timer for a
303 * delayed retry
304 */
305 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
306 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rprt_retry);
307 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
308 &fdmi->timer, bfa_fcs_port_fdmi_timeout,
309 fdmi, BFA_FCS_RETRY_TIMEOUT);
310
311 } else {
312 /*
313 * set state to offline
314 */
315 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
316 fdmi->retry_cnt = 0;
317 }
318 break;
319
320 case FDMISM_EVENT_RSP_OK:
321 fdmi->retry_cnt = 0;
322 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online);
323 break;
324
325 case FDMISM_EVENT_PORT_OFFLINE:
326 bfa_fcxp_discard(fdmi->fcxp);
327 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
328 break;
329
330 default:
331 bfa_assert(0);
332 }
333}
334
335static void
336bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi,
337 enum port_fdmi_event event)
338{
339 struct bfa_fcs_port_s *port = fdmi->ms->port;
340
341 bfa_trc(port->fcs, port->port_cfg.pwwn);
342 bfa_trc(port->fcs, event);
343
344 switch (event) {
345 case FDMISM_EVENT_TIMEOUT:
346 /*
347 * Retry Timer Expired. Re-send
348 */
349 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rprt);
350 bfa_fcs_port_fdmi_send_rprt(fdmi, NULL);
351 break;
352
353 case FDMISM_EVENT_PORT_OFFLINE:
354 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
355 bfa_timer_stop(&fdmi->timer);
356 break;
357
358 default:
359 bfa_assert(0);
360 }
361}
362
363/*
364 * Register Port Attributes
365 */
366static void
367bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
368 enum port_fdmi_event event)
369{
370 struct bfa_fcs_port_s *port = fdmi->ms->port;
371
372 bfa_trc(port->fcs, port->port_cfg.pwwn);
373 bfa_trc(port->fcs, event);
374
375 switch (event) {
376 case FDMISM_EVENT_RPA_SENT:
377 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rpa);
378 break;
379
380 case FDMISM_EVENT_PORT_OFFLINE:
381 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
382 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
383 &fdmi->fcxp_wqe);
384 break;
385
386 default:
387 bfa_assert(0);
388 }
389}
390
391static void
392bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
393 enum port_fdmi_event event)
394{
395 struct bfa_fcs_port_s *port = fdmi->ms->port;
396
397 bfa_trc(port->fcs, port->port_cfg.pwwn);
398 bfa_trc(port->fcs, event);
399
400 switch (event) {
401 case FDMISM_EVENT_RSP_ERROR:
402 /*
403 * if max retries have not been reached, start timer for a
404 * delayed retry
405 */
406 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
407 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rpa_retry);
408 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
409 &fdmi->timer, bfa_fcs_port_fdmi_timeout,
410 fdmi, BFA_FCS_RETRY_TIMEOUT);
411 } else {
412 /*
413 * set state to offline
414 */
415 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
416 fdmi->retry_cnt = 0;
417 }
418 break;
419
420 case FDMISM_EVENT_RSP_OK:
421 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online);
422 fdmi->retry_cnt = 0;
423 break;
424
425 case FDMISM_EVENT_PORT_OFFLINE:
426 bfa_fcxp_discard(fdmi->fcxp);
427 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
428 break;
429
430 default:
431 bfa_assert(0);
432 }
433}
434
435static void
436bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
437 enum port_fdmi_event event)
438{
439 struct bfa_fcs_port_s *port = fdmi->ms->port;
440
441 bfa_trc(port->fcs, port->port_cfg.pwwn);
442 bfa_trc(port->fcs, event);
443
444 switch (event) {
445 case FDMISM_EVENT_TIMEOUT:
446 /*
447 * Retry Timer Expired. Re-send
448 */
449 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa);
450 bfa_fcs_port_fdmi_send_rpa(fdmi, NULL);
451 break;
452
453 case FDMISM_EVENT_PORT_OFFLINE:
454 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
455 bfa_timer_stop(&fdmi->timer);
456 break;
457
458 default:
459 bfa_assert(0);
460 }
461}
462
463static void
464bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
465 enum port_fdmi_event event)
466{
467 struct bfa_fcs_port_s *port = fdmi->ms->port;
468
469 bfa_trc(port->fcs, port->port_cfg.pwwn);
470 bfa_trc(port->fcs, event);
471
472 switch (event) {
473 case FDMISM_EVENT_PORT_OFFLINE:
474 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
475 break;
476
477 default:
478 bfa_assert(0);
479 }
480}
481
482
483/**
484* RHBA : Register HBA Attributes.
485 */
486static void
487bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
488{
489 struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
490 struct bfa_fcs_port_s *port = fdmi->ms->port;
491 struct fchs_s fchs;
492 int len, attr_len;
493 struct bfa_fcxp_s *fcxp;
494 u8 *pyld;
495
496 bfa_trc(port->fcs, port->port_cfg.pwwn);
497
498 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
499 if (!fcxp) {
500 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
501 bfa_fcs_port_fdmi_send_rhba, fdmi);
502 return;
503 }
504 fdmi->fcxp = fcxp;
505
506 pyld = bfa_fcxp_get_reqbuf(fcxp);
507 bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
508
509 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
510 FDMI_RHBA);
511
512 attr_len = bfa_fcs_port_fdmi_build_rhba_pyld(fdmi,
513 (u8 *) ((struct ct_hdr_s *) pyld + 1));
514
515 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
516 FC_CLASS_3, (len + attr_len), &fchs,
517 bfa_fcs_port_fdmi_rhba_response, (void *)fdmi,
518 FC_MAX_PDUSZ, FC_RA_TOV);
519
520 bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT);
521}
522
523static u16
524bfa_fcs_port_fdmi_build_rhba_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
525 u8 *pyld)
526{
527 struct bfa_fcs_port_s *port = fdmi->ms->port;
528 struct bfa_fcs_fdmi_hba_attr_s hba_attr; /* @todo */
529 struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr; /* @todo */
530 struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld;
531 struct fdmi_attr_s *attr;
532 u8 *curr_ptr;
533 u16 len, count;
534
535 /*
536 * get hba attributes
537 */
538 bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr);
539
540 rhba->hba_id = bfa_fcs_port_get_pwwn(port);
541 rhba->port_list.num_ports = bfa_os_htonl(1);
542 rhba->port_list.port_entry = bfa_fcs_port_get_pwwn(port);
543
544 len = sizeof(rhba->hba_id) + sizeof(rhba->port_list);
545
546 count = 0;
547 len += sizeof(rhba->hba_attr_blk.attr_count);
548
549 /*
550 * fill out the invididual entries of the HBA attrib Block
551 */
552 curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr;
553
554 /*
555 * Node Name
556 */
557 attr = (struct fdmi_attr_s *) curr_ptr;
558 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_NODENAME);
559 attr->len = sizeof(wwn_t);
560 memcpy(attr->value, &bfa_fcs_port_get_nwwn(port), attr->len);
561 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
562 len += attr->len;
563 count++;
564 attr->len =
565 bfa_os_htons(attr->len + sizeof(attr->type) +
566 sizeof(attr->len));
567
568 /*
569 * Manufacturer
570 */
571 attr = (struct fdmi_attr_s *) curr_ptr;
572 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MANUFACTURER);
573 attr->len = (u16) strlen(fcs_hba_attr->manufacturer);
574 memcpy(attr->value, fcs_hba_attr->manufacturer, attr->len);
575 /* variable fields need to be 4 byte aligned */
576 attr->len = fc_roundup(attr->len, sizeof(u32));
577 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
578 len += attr->len;
579 count++;
580 attr->len =
581 bfa_os_htons(attr->len + sizeof(attr->type) +
582 sizeof(attr->len));
583
584 /*
585 * Serial Number
586 */
587 attr = (struct fdmi_attr_s *) curr_ptr;
588 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_SERIALNUM);
589 attr->len = (u16) strlen(fcs_hba_attr->serial_num);
590 memcpy(attr->value, fcs_hba_attr->serial_num, attr->len);
591 /* variable fields need to be 4 byte aligned */
592 attr->len = fc_roundup(attr->len, sizeof(u32));
593 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
594 len += attr->len;
595 count++;
596 attr->len =
597 bfa_os_htons(attr->len + sizeof(attr->type) +
598 sizeof(attr->len));
599
600 /*
601 * Model
602 */
603 attr = (struct fdmi_attr_s *) curr_ptr;
604 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MODEL);
605 attr->len = (u16) strlen(fcs_hba_attr->model);
606 memcpy(attr->value, fcs_hba_attr->model, attr->len);
607 /* variable fields need to be 4 byte aligned */
608 attr->len = fc_roundup(attr->len, sizeof(u32));
609 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
610 len += attr->len;
611 count++;
612 attr->len =
613 bfa_os_htons(attr->len + sizeof(attr->type) +
614 sizeof(attr->len));
615
616 /*
617 * Model Desc
618 */
619 attr = (struct fdmi_attr_s *) curr_ptr;
620 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MODEL_DESC);
621 attr->len = (u16) strlen(fcs_hba_attr->model_desc);
622 memcpy(attr->value, fcs_hba_attr->model_desc, attr->len);
623 /* variable fields need to be 4 byte aligned */
624 attr->len = fc_roundup(attr->len, sizeof(u32));
625 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
626 len += attr->len;
627 count++;
628 attr->len =
629 bfa_os_htons(attr->len + sizeof(attr->type) +
630 sizeof(attr->len));
631
632 /*
633 * H/W Version
634 */
635 if (fcs_hba_attr->hw_version[0] != '\0') {
636 attr = (struct fdmi_attr_s *) curr_ptr;
637 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_HW_VERSION);
638 attr->len = (u16) strlen(fcs_hba_attr->hw_version);
639 memcpy(attr->value, fcs_hba_attr->hw_version, attr->len);
640 /* variable fields need to be 4 byte aligned */
641 attr->len = fc_roundup(attr->len, sizeof(u32));
642 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
643 len += attr->len;
644 count++;
645 attr->len =
646 bfa_os_htons(attr->len + sizeof(attr->type) +
647 sizeof(attr->len));
648 }
649
650 /*
651 * Driver Version
652 */
653 attr = (struct fdmi_attr_s *) curr_ptr;
654 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_DRIVER_VERSION);
655 attr->len = (u16) strlen(fcs_hba_attr->driver_version);
656 memcpy(attr->value, fcs_hba_attr->driver_version, attr->len);
657 /* variable fields need to be 4 byte aligned */
658 attr->len = fc_roundup(attr->len, sizeof(u32));
659 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
660 len += attr->len;;
661 count++;
662 attr->len =
663 bfa_os_htons(attr->len + sizeof(attr->type) +
664 sizeof(attr->len));
665
666 /*
667 * Option Rom Version
668 */
669 if (fcs_hba_attr->option_rom_ver[0] != '\0') {
670 attr = (struct fdmi_attr_s *) curr_ptr;
671 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_ROM_VERSION);
672 attr->len = (u16) strlen(fcs_hba_attr->option_rom_ver);
673 memcpy(attr->value, fcs_hba_attr->option_rom_ver, attr->len);
674 /* variable fields need to be 4 byte aligned */
675 attr->len = fc_roundup(attr->len, sizeof(u32));
676 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
677 len += attr->len;
678 count++;
679 attr->len =
680 bfa_os_htons(attr->len + sizeof(attr->type) +
681 sizeof(attr->len));
682 }
683
684 /*
685 * f/w Version = driver version
686 */
687 attr = (struct fdmi_attr_s *) curr_ptr;
688 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_FW_VERSION);
689 attr->len = (u16) strlen(fcs_hba_attr->driver_version);
690 memcpy(attr->value, fcs_hba_attr->driver_version, attr->len);
691 /* variable fields need to be 4 byte aligned */
692 attr->len = fc_roundup(attr->len, sizeof(u32));
693 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
694 len += attr->len;
695 count++;
696 attr->len =
697 bfa_os_htons(attr->len + sizeof(attr->type) +
698 sizeof(attr->len));
699
700 /*
701 * OS Name
702 */
703 if (fcs_hba_attr->os_name[0] != '\0') {
704 attr = (struct fdmi_attr_s *) curr_ptr;
705 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_OS_NAME);
706 attr->len = (u16) strlen(fcs_hba_attr->os_name);
707 memcpy(attr->value, fcs_hba_attr->os_name, attr->len);
708 /* variable fields need to be 4 byte aligned */
709 attr->len = fc_roundup(attr->len, sizeof(u32));
710 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
711 len += attr->len;
712 count++;
713 attr->len =
714 bfa_os_htons(attr->len + sizeof(attr->type) +
715 sizeof(attr->len));
716 }
717
718 /*
719 * MAX_CT_PAYLOAD
720 */
721 attr = (struct fdmi_attr_s *) curr_ptr;
722 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MAX_CT);
723 attr->len = sizeof(fcs_hba_attr->max_ct_pyld);
724 memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, attr->len);
725 len += attr->len;
726 count++;
727 attr->len =
728 bfa_os_htons(attr->len + sizeof(attr->type) +
729 sizeof(attr->len));
730
731 /*
732 * Update size of payload
733 */
734 len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
735
736 rhba->hba_attr_blk.attr_count = bfa_os_htonl(count);
737 return len;
738}
739
740static void
741bfa_fcs_port_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
742 void *cbarg, bfa_status_t req_status,
743 u32 rsp_len, u32 resid_len,
744 struct fchs_s *rsp_fchs)
745{
746 struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg;
747 struct bfa_fcs_port_s *port = fdmi->ms->port;
748 struct ct_hdr_s *cthdr = NULL;
749
750 bfa_trc(port->fcs, port->port_cfg.pwwn);
751
752 /*
753 * Sanity Checks
754 */
755 if (req_status != BFA_STATUS_OK) {
756 bfa_trc(port->fcs, req_status);
757 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
758 return;
759 }
760
761 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
762 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
763
764 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
765 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
766 return;
767 }
768
769 bfa_trc(port->fcs, cthdr->reason_code);
770 bfa_trc(port->fcs, cthdr->exp_code);
771 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
772}
773
774/**
775* RPRT : Register Port
776 */
777static void
778bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
779{
780 struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
781 struct bfa_fcs_port_s *port = fdmi->ms->port;
782 struct fchs_s fchs;
783 u16 len, attr_len;
784 struct bfa_fcxp_s *fcxp;
785 u8 *pyld;
786
787 bfa_trc(port->fcs, port->port_cfg.pwwn);
788
789 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
790 if (!fcxp) {
791 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
792 bfa_fcs_port_fdmi_send_rprt, fdmi);
793 return;
794 }
795 fdmi->fcxp = fcxp;
796
797 pyld = bfa_fcxp_get_reqbuf(fcxp);
798 bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
799
800 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
801 FDMI_RPRT);
802
803 attr_len = bfa_fcs_port_fdmi_build_rprt_pyld(fdmi,
804 (u8 *) ((struct ct_hdr_s *) pyld + 1));
805
806 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
807 FC_CLASS_3, len + attr_len, &fchs,
808 bfa_fcs_port_fdmi_rprt_response, (void *)fdmi,
809 FC_MAX_PDUSZ, FC_RA_TOV);
810
811 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT);
812}
813
814/**
815 * This routine builds Port Attribute Block that used in RPA, RPRT commands.
816 */
817static u16
818bfa_fcs_port_fdmi_build_portattr_block(struct bfa_fcs_port_fdmi_s *fdmi,
819 u8 *pyld)
820{
821 struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
822 struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld;
823 struct fdmi_attr_s *attr;
824 u8 *curr_ptr;
825 u16 len;
826 u8 count = 0;
827
828 /*
829 * get port attributes
830 */
831 bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
832
833 len = sizeof(port_attrib->attr_count);
834
835 /*
836 * fill out the invididual entries
837 */
838 curr_ptr = (u8 *) &port_attrib->port_attr;
839
840 /*
841 * FC4 Types
842 */
843 attr = (struct fdmi_attr_s *) curr_ptr;
844 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_FC4_TYPES);
845 attr->len = sizeof(fcs_port_attr.supp_fc4_types);
846 memcpy(attr->value, fcs_port_attr.supp_fc4_types, attr->len);
847 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
848 len += attr->len;
849 ++count;
850 attr->len =
851 bfa_os_htons(attr->len + sizeof(attr->type) +
852 sizeof(attr->len));
853
854 /*
855 * Supported Speed
856 */
857 attr = (struct fdmi_attr_s *) curr_ptr;
858 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_SUPP_SPEED);
859 attr->len = sizeof(fcs_port_attr.supp_speed);
860 memcpy(attr->value, &fcs_port_attr.supp_speed, attr->len);
861 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
862 len += attr->len;
863 ++count;
864 attr->len =
865 bfa_os_htons(attr->len + sizeof(attr->type) +
866 sizeof(attr->len));
867
868 /*
869 * current Port Speed
870 */
871 attr = (struct fdmi_attr_s *) curr_ptr;
872 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_PORT_SPEED);
873 attr->len = sizeof(fcs_port_attr.curr_speed);
874 memcpy(attr->value, &fcs_port_attr.curr_speed, attr->len);
875 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
876 len += attr->len;
877 ++count;
878 attr->len =
879 bfa_os_htons(attr->len + sizeof(attr->type) +
880 sizeof(attr->len));
881
882 /*
883 * max frame size
884 */
885 attr = (struct fdmi_attr_s *) curr_ptr;
886 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_FRAME_SIZE);
887 attr->len = sizeof(fcs_port_attr.max_frm_size);
888 memcpy(attr->value, &fcs_port_attr.max_frm_size, attr->len);
889 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
890 len += attr->len;
891 ++count;
892 attr->len =
893 bfa_os_htons(attr->len + sizeof(attr->type) +
894 sizeof(attr->len));
895
896 /*
897 * OS Device Name
898 */
899 if (fcs_port_attr.os_device_name[0] != '\0') {
900 attr = (struct fdmi_attr_s *) curr_ptr;
901 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_DEV_NAME);
902 attr->len = (u16) strlen(fcs_port_attr.os_device_name);
903 memcpy(attr->value, fcs_port_attr.os_device_name, attr->len);
904 /* variable fields need to be 4 byte aligned */
905 attr->len = fc_roundup(attr->len, sizeof(u32));
906 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
907 len += attr->len;
908 ++count;
909 attr->len =
910 bfa_os_htons(attr->len + sizeof(attr->type) +
911 sizeof(attr->len));
912
913 }
914 /*
915 * Host Name
916 */
917 if (fcs_port_attr.host_name[0] != '\0') {
918 attr = (struct fdmi_attr_s *) curr_ptr;
919 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_HOST_NAME);
920 attr->len = (u16) strlen(fcs_port_attr.host_name);
921 memcpy(attr->value, fcs_port_attr.host_name, attr->len);
922 /* variable fields need to be 4 byte aligned */
923 attr->len = fc_roundup(attr->len, sizeof(u32));
924 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
925 len += attr->len;
926 ++count;
927 attr->len =
928 bfa_os_htons(attr->len + sizeof(attr->type) +
929 sizeof(attr->len));
930
931 }
932
933 /*
934 * Update size of payload
935 */
936 port_attrib->attr_count = bfa_os_htonl(count);
937 len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
938 return len;
939}
940
941static u16
942bfa_fcs_port_fdmi_build_rprt_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
943 u8 *pyld)
944{
945 struct bfa_fcs_port_s *port = fdmi->ms->port;
946 struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld;
947 u16 len;
948
949 rprt->hba_id = bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port->fcs));
950 rprt->port_name = bfa_fcs_port_get_pwwn(port);
951
952 len = bfa_fcs_port_fdmi_build_portattr_block(fdmi,
953 (u8 *) &rprt->port_attr_blk);
954
955 len += sizeof(rprt->hba_id) + sizeof(rprt->port_name);
956
957 return len;
958}
959
960static void
961bfa_fcs_port_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
962 void *cbarg, bfa_status_t req_status,
963 u32 rsp_len, u32 resid_len,
964 struct fchs_s *rsp_fchs)
965{
966 struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg;
967 struct bfa_fcs_port_s *port = fdmi->ms->port;
968 struct ct_hdr_s *cthdr = NULL;
969
970 bfa_trc(port->fcs, port->port_cfg.pwwn);
971
972 /*
973 * Sanity Checks
974 */
975 if (req_status != BFA_STATUS_OK) {
976 bfa_trc(port->fcs, req_status);
977 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
978 return;
979 }
980
981 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
982 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
983
984 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
985 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
986 return;
987 }
988
989 bfa_trc(port->fcs, cthdr->reason_code);
990 bfa_trc(port->fcs, cthdr->exp_code);
991 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
992}
993
994/**
995* RPA : Register Port Attributes.
996 */
997static void
998bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
999{
1000 struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
1001 struct bfa_fcs_port_s *port = fdmi->ms->port;
1002 struct fchs_s fchs;
1003 u16 len, attr_len;
1004 struct bfa_fcxp_s *fcxp;
1005 u8 *pyld;
1006
1007 bfa_trc(port->fcs, port->port_cfg.pwwn);
1008
1009 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1010 if (!fcxp) {
1011 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1012 bfa_fcs_port_fdmi_send_rpa, fdmi);
1013 return;
1014 }
1015 fdmi->fcxp = fcxp;
1016
1017 pyld = bfa_fcxp_get_reqbuf(fcxp);
1018 bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
1019
1020 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
1021 FDMI_RPA);
1022
1023 attr_len = bfa_fcs_port_fdmi_build_rpa_pyld(fdmi,
1024 (u8 *) ((struct ct_hdr_s *) pyld + 1));
1025
1026 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1027 FC_CLASS_3, len + attr_len, &fchs,
1028 bfa_fcs_port_fdmi_rpa_response, (void *)fdmi,
1029 FC_MAX_PDUSZ, FC_RA_TOV);
1030
1031 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT);
1032}
1033
1034static u16
1035bfa_fcs_port_fdmi_build_rpa_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
1036 u8 *pyld)
1037{
1038 struct bfa_fcs_port_s *port = fdmi->ms->port;
1039 struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld;
1040 u16 len;
1041
1042 rpa->port_name = bfa_fcs_port_get_pwwn(port);
1043
1044 len = bfa_fcs_port_fdmi_build_portattr_block(fdmi,
1045 (u8 *) &rpa->port_attr_blk);
1046
1047 len += sizeof(rpa->port_name);
1048
1049 return len;
1050}
1051
1052static void
1053bfa_fcs_port_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
1054 void *cbarg, bfa_status_t req_status,
1055 u32 rsp_len, u32 resid_len,
1056 struct fchs_s *rsp_fchs)
1057{
1058 struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg;
1059 struct bfa_fcs_port_s *port = fdmi->ms->port;
1060 struct ct_hdr_s *cthdr = NULL;
1061
1062 bfa_trc(port->fcs, port->port_cfg.pwwn);
1063
1064 /*
1065 * Sanity Checks
1066 */
1067 if (req_status != BFA_STATUS_OK) {
1068 bfa_trc(port->fcs, req_status);
1069 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1070 return;
1071 }
1072
1073 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1074 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
1075
1076 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1077 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
1078 return;
1079 }
1080
1081 bfa_trc(port->fcs, cthdr->reason_code);
1082 bfa_trc(port->fcs, cthdr->exp_code);
1083 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1084}
1085
1086static void
1087bfa_fcs_port_fdmi_timeout(void *arg)
1088{
1089 struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)arg;
1090
1091 bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
1092}
1093
1094void
1095bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
1096 struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
1097{
1098 struct bfa_fcs_port_s *port = fdmi->ms->port;
1099 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
1100 struct bfa_adapter_attr_s adapter_attr;
1101
1102 bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
1103 bfa_os_memset(&adapter_attr, 0, sizeof(struct bfa_adapter_attr_s));
1104
1105 bfa_ioc_get_adapter_attr(&port->fcs->bfa->ioc, &adapter_attr);
1106
1107 strncpy(hba_attr->manufacturer, adapter_attr.manufacturer,
1108 sizeof(adapter_attr.manufacturer));
1109
1110 strncpy(hba_attr->serial_num, adapter_attr.serial_num,
1111 sizeof(adapter_attr.serial_num));
1112
1113 strncpy(hba_attr->model, adapter_attr.model, sizeof(hba_attr->model));
1114
1115 strncpy(hba_attr->model_desc, adapter_attr.model_descr,
1116 sizeof(hba_attr->model_desc));
1117
1118 strncpy(hba_attr->hw_version, adapter_attr.hw_ver,
1119 sizeof(hba_attr->hw_version));
1120
1121 strncpy(hba_attr->driver_version, (char *)driver_info->version,
1122 sizeof(hba_attr->driver_version));
1123
1124 strncpy(hba_attr->option_rom_ver, adapter_attr.optrom_ver,
1125 sizeof(hba_attr->option_rom_ver));
1126
1127 strncpy(hba_attr->fw_version, adapter_attr.fw_ver,
1128 sizeof(hba_attr->fw_version));
1129
1130 strncpy(hba_attr->os_name, driver_info->host_os_name,
1131 sizeof(hba_attr->os_name));
1132
1133 /*
1134 * If there is a patch level, append it to the os name along with a
1135 * separator
1136 */
1137 if (driver_info->host_os_patch[0] != '\0') {
1138 strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
1139 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
1140 strncat(hba_attr->os_name, driver_info->host_os_patch,
1141 sizeof(driver_info->host_os_patch));
1142 }
1143
1144 hba_attr->max_ct_pyld = bfa_os_htonl(FC_MAX_PDUSZ);
1145
1146}
1147
1148void
1149bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
1150 struct bfa_fcs_fdmi_port_attr_s *port_attr)
1151{
1152 struct bfa_fcs_port_s *port = fdmi->ms->port;
1153 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
1154 struct bfa_pport_attr_s pport_attr;
1155
1156 bfa_os_memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
1157
1158 /*
1159 * get pport attributes from hal
1160 */
1161 bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
1162
1163 /*
1164 * get FC4 type Bitmask
1165 */
1166 fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types);
1167
1168 /*
1169 * Supported Speeds
1170 */
1171 port_attr->supp_speed = bfa_os_htonl(BFA_FCS_FDMI_SUPORTED_SPEEDS);
1172
1173 /*
1174 * Current Speed
1175 */
1176 port_attr->curr_speed = bfa_os_htonl(pport_attr.speed);
1177
1178 /*
1179 * Max PDU Size.
1180 */
1181 port_attr->max_frm_size = bfa_os_htonl(FC_MAX_PDUSZ);
1182
1183 /*
1184 * OS device Name
1185 */
1186 strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name,
1187 sizeof(port_attr->os_device_name));
1188
1189 /*
1190 * Host name
1191 */
1192 strncpy(port_attr->host_name, (char *)driver_info->host_machine_name,
1193 sizeof(port_attr->host_name));
1194
1195}
1196
1197
1198void
1199bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms)
1200{
1201 struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
1202
1203 fdmi->ms = ms;
1204 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
1205}
1206
1207void
1208bfa_fcs_port_fdmi_offline(struct bfa_fcs_port_ms_s *ms)
1209{
1210 struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
1211
1212 fdmi->ms = ms;
1213 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE);
1214}
1215
1216void
1217bfa_fcs_port_fdmi_online(struct bfa_fcs_port_ms_s *ms)
1218{
1219 struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
1220
1221 fdmi->ms = ms;
1222 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE);
1223}
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen.h b/drivers/scsi/bfa/include/aen/bfa_aen.h
new file mode 100644
index 000000000000..da8cac093d3d
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen.h
@@ -0,0 +1,92 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_AEN_H__
18#define __BFA_AEN_H__
19
20#include "defs/bfa_defs_aen.h"
21
22#define BFA_AEN_MAX_ENTRY 512
23
24extern s32 bfa_aen_max_cfg_entry;
25struct bfa_aen_s {
26 void *bfad;
27 s32 max_entry;
28 s32 write_index;
29 s32 read_index;
30 u32 bfad_num;
31 u32 seq_num;
32 void (*aen_cb_notify)(void *bfad);
33 void (*gettimeofday)(struct bfa_timeval_s *tv);
34 struct bfa_trc_mod_s *trcmod;
35 struct bfa_aen_entry_s list[BFA_AEN_MAX_ENTRY]; /* Must be the last */
36};
37
38
39/**
40 * Public APIs
41 */
42static inline void
43bfa_aen_set_max_cfg_entry(int max_entry)
44{
45 bfa_aen_max_cfg_entry = max_entry;
46}
47
48static inline s32
49bfa_aen_get_max_cfg_entry(void)
50{
51 return bfa_aen_max_cfg_entry;
52}
53
54static inline s32
55bfa_aen_get_meminfo(void)
56{
57 return (sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry());
58}
59
60static inline s32
61bfa_aen_get_wi(struct bfa_aen_s *aen)
62{
63 return aen->write_index;
64}
65
66static inline s32
67bfa_aen_get_ri(struct bfa_aen_s *aen)
68{
69 return aen->read_index;
70}
71
72static inline s32
73bfa_aen_fetch_count(struct bfa_aen_s *aen, s32 read_index)
74{
75 return ((aen->write_index + aen->max_entry) - read_index)
76 % aen->max_entry;
77}
78
79s32 bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod,
80 void *bfad, u32 inst_id, void (*aen_cb_notify)(void *),
81 void (*gettimeofday)(struct bfa_timeval_s *));
82
83s32 bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category,
84 int aen_type, union bfa_aen_data_u *aen_data);
85
86s32 bfa_aen_fetch(struct bfa_aen_s *aen, struct bfa_aen_entry_s *aen_entry,
87 s32 entry_space, s32 rii, s32 *ri_arr,
88 s32 ri_arr_cnt);
89
90s32 bfa_aen_get_inst(struct bfa_aen_s *aen);
91
92#endif /* __BFA_AEN_H__ */
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_adapter.h b/drivers/scsi/bfa/include/aen/bfa_aen_adapter.h
new file mode 100644
index 000000000000..260d3ea1cab3
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_adapter.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (c) 2005-2009 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/* messages define for BFA_AEN_CAT_ADAPTER Module */
19#ifndef __bfa_aen_adapter_h__
20#define __bfa_aen_adapter_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_ADAPTER_ADD \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ADAPTER, BFA_ADAPTER_AEN_ADD)
27#define BFA_AEN_ADAPTER_REMOVE \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ADAPTER, BFA_ADAPTER_AEN_REMOVE)
29
30#endif
31
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_audit.h b/drivers/scsi/bfa/include/aen/bfa_aen_audit.h
new file mode 100644
index 000000000000..12cd7aab5d53
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_audit.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (c) 2005-2009 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/* messages define for BFA_AEN_CAT_AUDIT Module */
19#ifndef __bfa_aen_audit_h__
20#define __bfa_aen_audit_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_AUDIT_AUTH_ENABLE \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_AUDIT, BFA_AUDIT_AEN_AUTH_ENABLE)
27#define BFA_AEN_AUDIT_AUTH_DISABLE \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_AUDIT, BFA_AUDIT_AEN_AUTH_DISABLE)
29
30#endif
31
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_ethport.h b/drivers/scsi/bfa/include/aen/bfa_aen_ethport.h
new file mode 100644
index 000000000000..507d0b58d149
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_ethport.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (c) 2005-2009 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/* messages define for BFA_AEN_CAT_ETHPORT Module */
19#ifndef __bfa_aen_ethport_h__
20#define __bfa_aen_ethport_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_ETHPORT_LINKUP \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ETHPORT, BFA_ETHPORT_AEN_LINKUP)
27#define BFA_AEN_ETHPORT_LINKDOWN \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ETHPORT, BFA_ETHPORT_AEN_LINKDOWN)
29#define BFA_AEN_ETHPORT_ENABLE \
30 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ETHPORT, BFA_ETHPORT_AEN_ENABLE)
31#define BFA_AEN_ETHPORT_DISABLE \
32 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ETHPORT, BFA_ETHPORT_AEN_DISABLE)
33
34#endif
35
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_ioc.h b/drivers/scsi/bfa/include/aen/bfa_aen_ioc.h
new file mode 100644
index 000000000000..71378b446b69
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_ioc.h
@@ -0,0 +1,37 @@
1/*
2 * Copyright (c) 2005-2009 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/* messages define for BFA_AEN_CAT_IOC Module */
19#ifndef __bfa_aen_ioc_h__
20#define __bfa_aen_ioc_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_IOC_HBGOOD \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_HBGOOD)
27#define BFA_AEN_IOC_HBFAIL \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_HBFAIL)
29#define BFA_AEN_IOC_ENABLE \
30 BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_ENABLE)
31#define BFA_AEN_IOC_DISABLE \
32 BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_DISABLE)
33#define BFA_AEN_IOC_FWMISMATCH \
34 BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_FWMISMATCH)
35
36#endif
37
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_itnim.h b/drivers/scsi/bfa/include/aen/bfa_aen_itnim.h
new file mode 100644
index 000000000000..a7d8ddcfef99
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_itnim.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (c) 2005-2009 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/* messages define for BFA_AEN_CAT_ITNIM Module */
19#ifndef __bfa_aen_itnim_h__
20#define __bfa_aen_itnim_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_ITNIM_ONLINE \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, BFA_ITNIM_AEN_ONLINE)
27#define BFA_AEN_ITNIM_OFFLINE \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, BFA_ITNIM_AEN_OFFLINE)
29#define BFA_AEN_ITNIM_DISCONNECT \
30 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, BFA_ITNIM_AEN_DISCONNECT)
31
32#endif
33
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_lport.h b/drivers/scsi/bfa/include/aen/bfa_aen_lport.h
new file mode 100644
index 000000000000..5a8ebb65193f
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_lport.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright (c) 2005-2009 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/* messages define for BFA_AEN_CAT_LPORT Module */
19#ifndef __bfa_aen_lport_h__
20#define __bfa_aen_lport_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_LPORT_NEW \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NEW)
27#define BFA_AEN_LPORT_DELETE \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_DELETE)
29#define BFA_AEN_LPORT_ONLINE \
30 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_ONLINE)
31#define BFA_AEN_LPORT_OFFLINE \
32 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_OFFLINE)
33#define BFA_AEN_LPORT_DISCONNECT \
34 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_DISCONNECT)
35#define BFA_AEN_LPORT_NEW_PROP \
36 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NEW_PROP)
37#define BFA_AEN_LPORT_DELETE_PROP \
38 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_DELETE_PROP)
39#define BFA_AEN_LPORT_NEW_STANDARD \
40 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NEW_STANDARD)
41#define BFA_AEN_LPORT_DELETE_STANDARD \
42 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_DELETE_STANDARD)
43#define BFA_AEN_LPORT_NPIV_DUP_WWN \
44 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NPIV_DUP_WWN)
45#define BFA_AEN_LPORT_NPIV_FABRIC_MAX \
46 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NPIV_FABRIC_MAX)
47#define BFA_AEN_LPORT_NPIV_UNKNOWN \
48 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NPIV_UNKNOWN)
49
50#endif
51
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_port.h b/drivers/scsi/bfa/include/aen/bfa_aen_port.h
new file mode 100644
index 000000000000..9add905a622d
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_port.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (c) 2005-2009 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/* messages define for BFA_AEN_CAT_PORT Module */
19#ifndef __bfa_aen_port_h__
20#define __bfa_aen_port_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_PORT_ONLINE \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_ONLINE)
27#define BFA_AEN_PORT_OFFLINE \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_OFFLINE)
29#define BFA_AEN_PORT_RLIR \
30 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_RLIR)
31#define BFA_AEN_PORT_SFP_INSERT \
32 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_INSERT)
33#define BFA_AEN_PORT_SFP_REMOVE \
34 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_REMOVE)
35#define BFA_AEN_PORT_SFP_POM \
36 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_POM)
37#define BFA_AEN_PORT_ENABLE \
38 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_ENABLE)
39#define BFA_AEN_PORT_DISABLE \
40 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_DISABLE)
41#define BFA_AEN_PORT_AUTH_ON \
42 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_AUTH_ON)
43#define BFA_AEN_PORT_AUTH_OFF \
44 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_AUTH_OFF)
45#define BFA_AEN_PORT_DISCONNECT \
46 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_DISCONNECT)
47#define BFA_AEN_PORT_QOS_NEG \
48 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_QOS_NEG)
49#define BFA_AEN_PORT_FABRIC_NAME_CHANGE \
50 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_FABRIC_NAME_CHANGE)
51#define BFA_AEN_PORT_SFP_ACCESS_ERROR \
52 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_ACCESS_ERROR)
53#define BFA_AEN_PORT_SFP_UNSUPPORT \
54 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_UNSUPPORT)
55
56#endif
57
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_rport.h b/drivers/scsi/bfa/include/aen/bfa_aen_rport.h
new file mode 100644
index 000000000000..7e4be1fd5e15
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_rport.h
@@ -0,0 +1,37 @@
1/*
2 * Copyright (c) 2005-2009 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/* messages define for BFA_AEN_CAT_RPORT Module */
19#ifndef __bfa_aen_rport_h__
20#define __bfa_aen_rport_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_RPORT_ONLINE \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_ONLINE)
27#define BFA_AEN_RPORT_OFFLINE \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_OFFLINE)
29#define BFA_AEN_RPORT_DISCONNECT \
30 BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_DISCONNECT)
31#define BFA_AEN_RPORT_QOS_PRIO \
32 BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_QOS_PRIO)
33#define BFA_AEN_RPORT_QOS_FLOWID \
34 BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_QOS_FLOWID)
35
36#endif
37
diff --git a/drivers/scsi/bfa/include/bfa.h b/drivers/scsi/bfa/include/bfa.h
new file mode 100644
index 000000000000..64c1412c5703
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfa.h
@@ -0,0 +1,177 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_H__
18#define __BFA_H__
19
20#include <bfa_os_inc.h>
21#include <cs/bfa_debug.h>
22#include <cs/bfa_q.h>
23#include <cs/bfa_trc.h>
24#include <cs/bfa_log.h>
25#include <cs/bfa_plog.h>
26#include <defs/bfa_defs_status.h>
27#include <defs/bfa_defs_ioc.h>
28#include <defs/bfa_defs_iocfc.h>
29#include <aen/bfa_aen.h>
30#include <bfi/bfi.h>
31
32struct bfa_s;
33#include <bfa_intr_priv.h>
34
35struct bfa_pcidev_s;
36
37/**
38 * PCI devices supported by the current BFA
39 */
40struct bfa_pciid_s {
41 u16 device_id;
42 u16 vendor_id;
43};
44
45extern char bfa_version[];
46
47/**
48 * BFA Power Mgmt Commands
49 */
50enum bfa_pm_cmd {
51 BFA_PM_CTL_D0 = 0,
52 BFA_PM_CTL_D1 = 1,
53 BFA_PM_CTL_D2 = 2,
54 BFA_PM_CTL_D3 = 3,
55};
56
57/**
58 * BFA memory resources
59 */
60enum bfa_mem_type {
61 BFA_MEM_TYPE_KVA = 1, /*! Kernel Virtual Memory *(non-dma-able) */
62 BFA_MEM_TYPE_DMA = 2, /*! DMA-able memory */
63 BFA_MEM_TYPE_MAX = BFA_MEM_TYPE_DMA,
64};
65
66struct bfa_mem_elem_s {
67 enum bfa_mem_type mem_type; /* see enum bfa_mem_type */
68 u32 mem_len; /* Total Length in Bytes */
69 u8 *kva; /* kernel virtual address */
70 u64 dma; /* dma address if DMA memory */
71 u8 *kva_curp; /* kva allocation cursor */
72 u64 dma_curp; /* dma allocation cursor */
73};
74
75struct bfa_meminfo_s {
76 struct bfa_mem_elem_s meminfo[BFA_MEM_TYPE_MAX];
77};
78#define bfa_meminfo_kva(_m) \
79 (_m)->meminfo[BFA_MEM_TYPE_KVA - 1].kva_curp
80#define bfa_meminfo_dma_virt(_m) \
81 (_m)->meminfo[BFA_MEM_TYPE_DMA - 1].kva_curp
82#define bfa_meminfo_dma_phys(_m) \
83 (_m)->meminfo[BFA_MEM_TYPE_DMA - 1].dma_curp
84
85/**
86 * Generic Scatter Gather Element used by driver
87 */
88struct bfa_sge_s {
89 u32 sg_len;
90 void *sg_addr;
91};
92
93#define bfa_sge_to_be(__sge) do { \
94 ((u32 *)(__sge))[0] = bfa_os_htonl(((u32 *)(__sge))[0]); \
95 ((u32 *)(__sge))[1] = bfa_os_htonl(((u32 *)(__sge))[1]); \
96 ((u32 *)(__sge))[2] = bfa_os_htonl(((u32 *)(__sge))[2]); \
97} while (0)
98
99
100/*
101 * bfa stats interfaces
102 */
103#define bfa_stats(_mod, _stats) (_mod)->stats._stats ++
104
105#define bfa_ioc_get_stats(__bfa, __ioc_stats) \
106 bfa_ioc_fetch_stats(&(__bfa)->ioc, __ioc_stats)
107#define bfa_ioc_clear_stats(__bfa) \
108 bfa_ioc_clr_stats(&(__bfa)->ioc)
109
110/*
111 * bfa API functions
112 */
113void bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids);
114void bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg);
115void bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg);
116void bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg,
117 struct bfa_meminfo_s *meminfo);
118void bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
119 struct bfa_meminfo_s *meminfo,
120 struct bfa_pcidev_s *pcidev);
121void bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod);
122void bfa_init_log(struct bfa_s *bfa, struct bfa_log_mod_s *logmod);
123void bfa_init_aen(struct bfa_s *bfa, struct bfa_aen_s *aen);
124void bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog);
125void bfa_detach(struct bfa_s *bfa);
126void bfa_init(struct bfa_s *bfa);
127void bfa_start(struct bfa_s *bfa);
128void bfa_stop(struct bfa_s *bfa);
129void bfa_attach_fcs(struct bfa_s *bfa);
130void bfa_cb_init(void *bfad, bfa_status_t status);
131void bfa_cb_stop(void *bfad, bfa_status_t status);
132void bfa_cb_updateq(void *bfad, bfa_status_t status);
133
134bfa_boolean_t bfa_intx(struct bfa_s *bfa);
135void bfa_isr_enable(struct bfa_s *bfa);
136void bfa_isr_disable(struct bfa_s *bfa);
137void bfa_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
138 u32 *num_vecs, u32 *max_vec_bit);
139#define bfa_msix(__bfa, __vec) (__bfa)->msix.handler[__vec](__bfa, __vec)
140
141void bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q);
142void bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q);
143void bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q);
144
145typedef void (*bfa_cb_ioc_t) (void *cbarg, enum bfa_status status);
146void bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr);
147bfa_status_t bfa_iocfc_get_stats(struct bfa_s *bfa,
148 struct bfa_iocfc_stats_s *stats,
149 bfa_cb_ioc_t cbfn, void *cbarg);
150bfa_status_t bfa_iocfc_clear_stats(struct bfa_s *bfa,
151 bfa_cb_ioc_t cbfn, void *cbarg);
152void bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr);
153
154void bfa_adapter_get_attr(struct bfa_s *bfa,
155 struct bfa_adapter_attr_s *ad_attr);
156u64 bfa_adapter_get_id(struct bfa_s *bfa);
157
158bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa,
159 struct bfa_iocfc_intr_attr_s *attr);
160
161void bfa_iocfc_enable(struct bfa_s *bfa);
162void bfa_iocfc_disable(struct bfa_s *bfa);
163void bfa_ioc_auto_recover(bfa_boolean_t auto_recover);
164void bfa_cb_ioc_disable(void *bfad);
165void bfa_timer_tick(struct bfa_s *bfa);
166#define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \
167 bfa_timer_begin(&(_bfa)->timer_mod, _timer, _timercb, _arg, _timeout)
168
169/*
170 * BFA debug API functions
171 */
172bfa_status_t bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen);
173bfa_status_t bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen);
174
175#include "bfa_priv.h"
176
177#endif /* __BFA_H__ */
diff --git a/drivers/scsi/bfa/include/bfa_fcpim.h b/drivers/scsi/bfa/include/bfa_fcpim.h
new file mode 100644
index 000000000000..04789795fa53
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfa_fcpim.h
@@ -0,0 +1,159 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_FCPIM_H__
19#define __BFA_FCPIM_H__
20
21#include <bfa.h>
22#include <bfa_svc.h>
23#include <bfi/bfi_fcpim.h>
24#include <defs/bfa_defs_fcpim.h>
25
26/*
27 * forward declarations
28 */
29struct bfa_itnim_s;
30struct bfa_ioim_s;
31struct bfa_tskim_s;
32struct bfad_ioim_s;
33struct bfad_tskim_s;
34
35/*
36 * bfa fcpim module API functions
37 */
38void bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov);
39u16 bfa_fcpim_path_tov_get(struct bfa_s *bfa);
40void bfa_fcpim_qdepth_set(struct bfa_s *bfa, u16 q_depth);
41u16 bfa_fcpim_qdepth_get(struct bfa_s *bfa);
42bfa_status_t bfa_fcpim_get_modstats(struct bfa_s *bfa,
43 struct bfa_fcpim_stats_s *modstats);
44bfa_status_t bfa_fcpim_clr_modstats(struct bfa_s *bfa);
45
46/*
47 * bfa itnim API functions
48 */
49struct bfa_itnim_s *bfa_itnim_create(struct bfa_s *bfa,
50 struct bfa_rport_s *rport, void *itnim);
51void bfa_itnim_delete(struct bfa_itnim_s *itnim);
52void bfa_itnim_online(struct bfa_itnim_s *itnim,
53 bfa_boolean_t seq_rec);
54void bfa_itnim_offline(struct bfa_itnim_s *itnim);
55void bfa_itnim_get_stats(struct bfa_itnim_s *itnim,
56 struct bfa_itnim_hal_stats_s *stats);
57void bfa_itnim_clear_stats(struct bfa_itnim_s *itnim);
58
59
60/**
61 * BFA completion callback for bfa_itnim_online().
62 *
63 * @param[in] itnim FCS or driver itnim instance
64 *
65 * return None
66 */
67void bfa_cb_itnim_online(void *itnim);
68
69/**
70 * BFA completion callback for bfa_itnim_offline().
71 *
72 * @param[in] itnim FCS or driver itnim instance
73 *
74 * return None
75 */
76void bfa_cb_itnim_offline(void *itnim);
77void bfa_cb_itnim_tov_begin(void *itnim);
78void bfa_cb_itnim_tov(void *itnim);
79
80/**
81 * BFA notification to FCS/driver for second level error recovery.
82 *
83 * Atleast one I/O request has timedout and target is unresponsive to
84 * repeated abort requests. Second level error recovery should be initiated
85 * by starting implicit logout and recovery procedures.
86 *
87 * @param[in] itnim FCS or driver itnim instance
88 *
89 * return None
90 */
91void bfa_cb_itnim_sler(void *itnim);
92
93/*
94 * bfa ioim API functions
95 */
96struct bfa_ioim_s *bfa_ioim_alloc(struct bfa_s *bfa,
97 struct bfad_ioim_s *dio,
98 struct bfa_itnim_s *itnim,
99 u16 nsgles);
100
101void bfa_ioim_free(struct bfa_ioim_s *ioim);
102void bfa_ioim_start(struct bfa_ioim_s *ioim);
103void bfa_ioim_abort(struct bfa_ioim_s *ioim);
104void bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim,
105 bfa_boolean_t iotov);
106
107
108/**
109 * I/O completion notification.
110 *
111 * @param[in] dio driver IO structure
112 * @param[in] io_status IO completion status
113 * @param[in] scsi_status SCSI status returned by target
114 * @param[in] sns_len SCSI sense length, 0 if none
115 * @param[in] sns_info SCSI sense data, if any
116 * @param[in] residue Residual length
117 *
118 * @return None
119 */
120void bfa_cb_ioim_done(void *bfad, struct bfad_ioim_s *dio,
121 enum bfi_ioim_status io_status,
122 u8 scsi_status, int sns_len,
123 u8 *sns_info, s32 residue);
124
125/**
126 * I/O good completion notification.
127 *
128 * @param[in] dio driver IO structure
129 *
130 * @return None
131 */
132void bfa_cb_ioim_good_comp(void *bfad, struct bfad_ioim_s *dio);
133
134/**
135 * I/O abort completion notification
136 *
137 * @param[in] dio driver IO that was aborted
138 *
139 * @return None
140 */
141void bfa_cb_ioim_abort(void *bfad, struct bfad_ioim_s *dio);
142void bfa_cb_ioim_resfree(void *hcb_bfad);
143
144void bfa_cb_ioim_resfree(void *hcb_bfad);
145
146/*
147 * bfa tskim API functions
148 */
149struct bfa_tskim_s *bfa_tskim_alloc(struct bfa_s *bfa,
150 struct bfad_tskim_s *dtsk);
151void bfa_tskim_free(struct bfa_tskim_s *tskim);
152void bfa_tskim_start(struct bfa_tskim_s *tskim,
153 struct bfa_itnim_s *itnim, lun_t lun,
154 enum fcp_tm_cmnd tm, u8 t_secs);
155void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
156 enum bfi_tskim_status tsk_status);
157
158#endif /* __BFA_FCPIM_H__ */
159
diff --git a/drivers/scsi/bfa/include/bfa_fcptm.h b/drivers/scsi/bfa/include/bfa_fcptm.h
new file mode 100644
index 000000000000..5f5ffe0bb1bb
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfa_fcptm.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_FCPTM_H__
19#define __BFA_FCPTM_H__
20
21#include <bfa.h>
22#include <bfa_svc.h>
23#include <bfi/bfi_fcptm.h>
24
25/*
26 * forward declarations
27 */
28struct bfa_tin_s;
29struct bfa_iotm_s;
30struct bfa_tsktm_s;
31
32/*
33 * bfa fcptm module API functions
34 */
35void bfa_fcptm_path_tov_set(struct bfa_s *bfa, u16 path_tov);
36u16 bfa_fcptm_path_tov_get(struct bfa_s *bfa);
37void bfa_fcptm_qdepth_set(struct bfa_s *bfa, u16 q_depth);
38u16 bfa_fcptm_qdepth_get(struct bfa_s *bfa);
39
40/*
41 * bfa tin API functions
42 */
43void bfa_tin_get_stats(struct bfa_tin_s *tin, struct bfa_tin_stats_s *stats);
44void bfa_tin_clear_stats(struct bfa_tin_s *tin);
45
46#endif /* __BFA_FCPTM_H__ */
47
diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h
new file mode 100644
index 000000000000..0c80b74f72ef
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfa_svc.h
@@ -0,0 +1,324 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_SVC_H__
18#define __BFA_SVC_H__
19
20/*
21 * forward declarations
22 */
23struct bfa_fcxp_s;
24
25#include <defs/bfa_defs_status.h>
26#include <defs/bfa_defs_pport.h>
27#include <defs/bfa_defs_rport.h>
28#include <defs/bfa_defs_qos.h>
29#include <cs/bfa_sm.h>
30#include <bfa.h>
31
32/**
33 * BFA rport information.
34 */
35struct bfa_rport_info_s {
36 u16 max_frmsz; /* max rcv pdu size */
37 u32 pid : 24, /* remote port ID */
38 lp_tag : 8;
39 u32 local_pid : 24, /* local port ID */
40 cisc : 8; /* CIRO supported */
41 u8 fc_class; /* supported FC classes. enum fc_cos */
42 u8 vf_en; /* virtual fabric enable */
43 u16 vf_id; /* virtual fabric ID */
44 enum bfa_pport_speed speed; /* Rport's current speed */
45};
46
47/**
48 * BFA rport data structure
49 */
50struct bfa_rport_s {
51 struct list_head qe; /* queue element */
52 bfa_sm_t sm; /* state machine */
53 struct bfa_s *bfa; /* backpointer to BFA */
54 void *rport_drv; /* fcs/driver rport object */
55 u16 fw_handle; /* firmware rport handle */
56 u16 rport_tag; /* BFA rport tag */
57 struct bfa_rport_info_s rport_info; /* rport info from *fcs/driver */
58 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
59 struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */
60 struct bfa_rport_hal_stats_s stats; /* BFA rport statistics */
61 struct bfa_rport_qos_attr_s qos_attr;
62 union a {
63 bfa_status_t status; /* f/w status */
64 void *fw_msg; /* QoS scn event */
65 } event_arg;
66};
67#define BFA_RPORT_FC_COS(_rport) ((_rport)->rport_info.fc_class)
68
69/**
70 * Send completion callback.
71 */
72typedef void (*bfa_cb_fcxp_send_t) (void *bfad_fcxp, struct bfa_fcxp_s *fcxp,
73 void *cbarg, enum bfa_status req_status,
74 u32 rsp_len, u32 resid_len,
75 struct fchs_s *rsp_fchs);
76
77/**
78 * BFA fcxp allocation (asynchronous)
79 */
80typedef void (*bfa_fcxp_alloc_cbfn_t) (void *cbarg, struct bfa_fcxp_s *fcxp);
81
82struct bfa_fcxp_wqe_s {
83 struct list_head qe;
84 bfa_fcxp_alloc_cbfn_t alloc_cbfn;
85 void *alloc_cbarg;
86};
87
88typedef u64 (*bfa_fcxp_get_sgaddr_t) (void *bfad_fcxp, int sgeid);
89typedef u32 (*bfa_fcxp_get_sglen_t) (void *bfad_fcxp, int sgeid);
90
91#define BFA_UF_BUFSZ (2 * 1024 + 256)
92
93/**
94 * @todo private
95 */
96struct bfa_uf_buf_s {
97 u8 d[BFA_UF_BUFSZ];
98};
99
100
101struct bfa_uf_s {
102 struct list_head qe; /* queue element */
103 struct bfa_s *bfa; /* bfa instance */
104 u16 uf_tag; /* identifying tag f/w messages */
105 u16 vf_id;
106 u16 src_rport_handle;
107 u16 rsvd;
108 u8 *data_ptr;
109 u16 data_len; /* actual receive length */
110 u16 pb_len; /* posted buffer length */
111 void *buf_kva; /* buffer virtual address */
112 u64 buf_pa; /* buffer physical address */
113 struct bfa_cb_qe_s hcb_qe; /* comp: BFA comp qelem */
114 struct bfa_sge_s sges[BFI_SGE_INLINE_MAX];
115};
116
117typedef void (*bfa_cb_pport_t) (void *cbarg, enum bfa_status status);
118
119/**
120 * bfa lport login/logout service interface
121 */
122struct bfa_lps_s {
123 struct list_head qe; /* queue element */
124 struct bfa_s *bfa; /* parent bfa instance */
125 bfa_sm_t sm; /* finite state machine */
126 u8 lp_tag; /* lport tag */
127 u8 reqq; /* lport request queue */
128 u8 alpa; /* ALPA for loop topologies */
129 u32 lp_pid; /* lport port ID */
130 bfa_boolean_t fdisc; /* send FDISC instead of FLOGI*/
131 bfa_boolean_t auth_en; /* enable authentication */
132 bfa_boolean_t auth_req; /* authentication required */
133 bfa_boolean_t npiv_en; /* NPIV is allowed by peer */
134 bfa_boolean_t fport; /* attached peer is F_PORT */
135 bfa_boolean_t brcd_switch;/* attached peer is brcd switch */
136 bfa_status_t status; /* login status */
137 u16 pdusz; /* max receive PDU size */
138 u16 pr_bbcred; /* BB_CREDIT from peer */
139 u8 lsrjt_rsn; /* LSRJT reason */
140 u8 lsrjt_expl; /* LSRJT explanation */
141 wwn_t pwwn; /* port wwn of lport */
142 wwn_t nwwn; /* node wwn of lport */
143 wwn_t pr_pwwn; /* port wwn of lport peer */
144 wwn_t pr_nwwn; /* node wwn of lport peer */
145 mac_t lp_mac; /* fpma/spma MAC for lport */
146 mac_t fcf_mac; /* FCF MAC of lport */
147 struct bfa_reqq_wait_s wqe; /* request wait queue element */
148 void *uarg; /* user callback arg */
149 struct bfa_cb_qe_s hcb_qe; /* comp: callback qelem */
150 struct bfi_lps_login_rsp_s *loginrsp;
151 bfa_eproto_status_t ext_status;
152};
153
154/*
155 * bfa pport API functions
156 */
157bfa_status_t bfa_pport_enable(struct bfa_s *bfa);
158bfa_status_t bfa_pport_disable(struct bfa_s *bfa);
159bfa_status_t bfa_pport_cfg_speed(struct bfa_s *bfa,
160 enum bfa_pport_speed speed);
161enum bfa_pport_speed bfa_pport_get_speed(struct bfa_s *bfa);
162bfa_status_t bfa_pport_cfg_topology(struct bfa_s *bfa,
163 enum bfa_pport_topology topo);
164enum bfa_pport_topology bfa_pport_get_topology(struct bfa_s *bfa);
165bfa_status_t bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa);
166bfa_boolean_t bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa);
167u8 bfa_pport_get_myalpa(struct bfa_s *bfa);
168bfa_status_t bfa_pport_clr_hardalpa(struct bfa_s *bfa);
169bfa_status_t bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize);
170u16 bfa_pport_get_maxfrsize(struct bfa_s *bfa);
171u32 bfa_pport_mypid(struct bfa_s *bfa);
172u8 bfa_pport_get_rx_bbcredit(struct bfa_s *bfa);
173bfa_status_t bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap);
174bfa_status_t bfa_pport_trunk_disable(struct bfa_s *bfa);
175bfa_boolean_t bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap);
176void bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr);
177wwn_t bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node);
178bfa_status_t bfa_pport_get_stats(struct bfa_s *bfa,
179 union bfa_pport_stats_u *stats,
180 bfa_cb_pport_t cbfn, void *cbarg);
181bfa_status_t bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
182 void *cbarg);
183void bfa_pport_event_register(struct bfa_s *bfa,
184 void (*event_cbfn) (void *cbarg,
185 bfa_pport_event_t event), void *event_cbarg);
186bfa_boolean_t bfa_pport_is_disabled(struct bfa_s *bfa);
187void bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off);
188void bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off);
189bfa_status_t bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa,
190 enum bfa_pport_speed speed);
191enum bfa_pport_speed bfa_pport_get_ratelim_speed(struct bfa_s *bfa);
192
193void bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit);
194void bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status);
195void bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
196 bfa_boolean_t link_e2e_beacon);
197void bfa_cb_pport_event(void *cbarg, bfa_pport_event_t event);
198void bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr);
199void bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
200 struct bfa_qos_vc_attr_s *qos_vc_attr);
201bfa_status_t bfa_pport_get_qos_stats(struct bfa_s *bfa,
202 union bfa_pport_stats_u *stats,
203 bfa_cb_pport_t cbfn, void *cbarg);
204bfa_status_t bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
205 void *cbarg);
206bfa_boolean_t bfa_pport_is_ratelim(struct bfa_s *bfa);
207bfa_boolean_t bfa_pport_is_linkup(struct bfa_s *bfa);
208
209/*
210 * bfa rport API functions
211 */
212struct bfa_rport_s *bfa_rport_create(struct bfa_s *bfa, void *rport_drv);
213void bfa_rport_delete(struct bfa_rport_s *rport);
214void bfa_rport_online(struct bfa_rport_s *rport,
215 struct bfa_rport_info_s *rport_info);
216void bfa_rport_offline(struct bfa_rport_s *rport);
217void bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_pport_speed speed);
218void bfa_rport_get_stats(struct bfa_rport_s *rport,
219 struct bfa_rport_hal_stats_s *stats);
220void bfa_rport_clear_stats(struct bfa_rport_s *rport);
221void bfa_cb_rport_online(void *rport);
222void bfa_cb_rport_offline(void *rport);
223void bfa_cb_rport_qos_scn_flowid(void *rport,
224 struct bfa_rport_qos_attr_s old_qos_attr,
225 struct bfa_rport_qos_attr_s new_qos_attr);
226void bfa_cb_rport_qos_scn_prio(void *rport,
227 struct bfa_rport_qos_attr_s old_qos_attr,
228 struct bfa_rport_qos_attr_s new_qos_attr);
229void bfa_rport_get_qos_attr(struct bfa_rport_s *rport,
230 struct bfa_rport_qos_attr_s *qos_attr);
231
232/*
233 * bfa fcxp API functions
234 */
235struct bfa_fcxp_s *bfa_fcxp_alloc(void *bfad_fcxp, struct bfa_s *bfa,
236 int nreq_sgles, int nrsp_sgles,
237 bfa_fcxp_get_sgaddr_t get_req_sga,
238 bfa_fcxp_get_sglen_t get_req_sglen,
239 bfa_fcxp_get_sgaddr_t get_rsp_sga,
240 bfa_fcxp_get_sglen_t get_rsp_sglen);
241void bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
242 bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *cbarg);
243void bfa_fcxp_walloc_cancel(struct bfa_s *bfa,
244 struct bfa_fcxp_wqe_s *wqe);
245void bfa_fcxp_discard(struct bfa_fcxp_s *fcxp);
246
247void *bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp);
248void *bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp);
249
250void bfa_fcxp_free(struct bfa_fcxp_s *fcxp);
251
252void bfa_fcxp_send(struct bfa_fcxp_s *fcxp,
253 struct bfa_rport_s *rport, u16 vf_id, u8 lp_tag,
254 bfa_boolean_t cts, enum fc_cos cos,
255 u32 reqlen, struct fchs_s *fchs,
256 bfa_cb_fcxp_send_t cbfn,
257 void *cbarg,
258 u32 rsp_maxlen, u8 rsp_timeout);
259bfa_status_t bfa_fcxp_abort(struct bfa_fcxp_s *fcxp);
260u32 bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp);
261u32 bfa_fcxp_get_maxrsp(struct bfa_s *bfa);
262
263static inline void *
264bfa_uf_get_frmbuf(struct bfa_uf_s *uf)
265{
266 return uf->data_ptr;
267}
268
269static inline u16
270bfa_uf_get_frmlen(struct bfa_uf_s *uf)
271{
272 return uf->data_len;
273}
274
275/**
276 * Callback prototype for unsolicited frame receive handler.
277 *
278 * @param[in] cbarg callback arg for receive handler
279 * @param[in] uf unsolicited frame descriptor
280 *
281 * @return None
282 */
283typedef void (*bfa_cb_uf_recv_t) (void *cbarg, struct bfa_uf_s *uf);
284
285/*
286 * bfa uf API functions
287 */
288void bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv,
289 void *cbarg);
290void bfa_uf_free(struct bfa_uf_s *uf);
291
292/**
293 * bfa lport service api
294 */
295
296struct bfa_lps_s *bfa_lps_alloc(struct bfa_s *bfa);
297void bfa_lps_delete(struct bfa_lps_s *lps);
298void bfa_lps_discard(struct bfa_lps_s *lps);
299void bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz,
300 wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en);
301void bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn,
302 wwn_t nwwn);
303void bfa_lps_flogo(struct bfa_lps_s *lps);
304void bfa_lps_fdisclogo(struct bfa_lps_s *lps);
305u8 bfa_lps_get_tag(struct bfa_lps_s *lps);
306bfa_boolean_t bfa_lps_is_npiv_en(struct bfa_lps_s *lps);
307bfa_boolean_t bfa_lps_is_fport(struct bfa_lps_s *lps);
308bfa_boolean_t bfa_lps_is_brcd_fabric(struct bfa_lps_s *lps);
309bfa_boolean_t bfa_lps_is_authreq(struct bfa_lps_s *lps);
310bfa_eproto_status_t bfa_lps_get_extstatus(struct bfa_lps_s *lps);
311u32 bfa_lps_get_pid(struct bfa_lps_s *lps);
312u8 bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid);
313u16 bfa_lps_get_peer_bbcredit(struct bfa_lps_s *lps);
314wwn_t bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps);
315wwn_t bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps);
316u8 bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps);
317u8 bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps);
318void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status);
319void bfa_cb_lps_flogo_comp(void *bfad, void *uarg);
320void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status);
321void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg);
322
323#endif /* __BFA_SVC_H__ */
324
diff --git a/drivers/scsi/bfa/include/bfa_timer.h b/drivers/scsi/bfa/include/bfa_timer.h
new file mode 100644
index 000000000000..e407103fa565
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfa_timer.h
@@ -0,0 +1,53 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_TIMER_H__
18#define __BFA_TIMER_H__
19
20#include <bfa_os_inc.h>
21#include <cs/bfa_q.h>
22
23struct bfa_s;
24
25typedef void (*bfa_timer_cbfn_t)(void *);
26
27/**
28 * BFA timer data structure
29 */
30struct bfa_timer_s {
31 struct list_head qe;
32 bfa_timer_cbfn_t timercb;
33 void *arg;
34 int timeout; /**< in millisecs. */
35};
36
37/**
38 * Timer module structure
39 */
40struct bfa_timer_mod_s {
41 struct list_head timer_q;
42};
43
44#define BFA_TIMER_FREQ 500 /**< specified in millisecs */
45
46void bfa_timer_beat(struct bfa_timer_mod_s *mod);
47void bfa_timer_init(struct bfa_timer_mod_s *mod);
48void bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
49 bfa_timer_cbfn_t timercb, void *arg,
50 unsigned int timeout);
51void bfa_timer_stop(struct bfa_timer_s *timer);
52
53#endif /* __BFA_TIMER_H__ */
diff --git a/drivers/scsi/bfa/include/bfi/bfi.h b/drivers/scsi/bfa/include/bfi/bfi.h
new file mode 100644
index 000000000000..6cadfe0d4ba1
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi.h
@@ -0,0 +1,174 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFI_H__
19#define __BFI_H__
20
21#include <bfa_os_inc.h>
22#include <defs/bfa_defs_status.h>
23
24#pragma pack(1)
25
26/**
27 * Msg header common to all msgs
28 */
29struct bfi_mhdr_s {
30 u8 msg_class; /* @ref bfi_mclass_t */
31 u8 msg_id; /* msg opcode with in the class */
32 union {
33 struct {
34 u8 rsvd;
35 u8 lpu_id; /* msg destination */
36 } h2i;
37 u16 i2htok; /* token in msgs to host */
38 } mtag;
39};
40
41#define bfi_h2i_set(_mh, _mc, _op, _lpuid) do { \
42 (_mh).msg_class = (_mc); \
43 (_mh).msg_id = (_op); \
44 (_mh).mtag.h2i.lpu_id = (_lpuid); \
45} while (0)
46
47#define bfi_i2h_set(_mh, _mc, _op, _i2htok) do { \
48 (_mh).msg_class = (_mc); \
49 (_mh).msg_id = (_op); \
50 (_mh).mtag.i2htok = (_i2htok); \
51} while (0)
52
53/*
54 * Message opcodes: 0-127 to firmware, 128-255 to host
55 */
56#define BFI_I2H_OPCODE_BASE 128
57#define BFA_I2HM(_x) ((_x) + BFI_I2H_OPCODE_BASE)
58
59/**
60 ****************************************************************************
61 *
62 * Scatter Gather Element and Page definition
63 *
64 ****************************************************************************
65 */
66
67#define BFI_SGE_INLINE 1
68#define BFI_SGE_INLINE_MAX (BFI_SGE_INLINE + 1)
69
70/**
71 * SG Flags
72 */
73enum {
74 BFI_SGE_DATA = 0, /* data address, not last */
75 BFI_SGE_DATA_CPL = 1, /* data addr, last in current page */
76 BFI_SGE_DATA_LAST = 3, /* data address, last */
77 BFI_SGE_LINK = 2, /* link address */
78 BFI_SGE_PGDLEN = 2, /* cumulative data length for page */
79};
80
81/**
82 * DMA addresses
83 */
84union bfi_addr_u {
85 struct {
86 u32 addr_lo;
87 u32 addr_hi;
88 } a32;
89};
90
91/**
92 * Scatter Gather Element
93 */
94struct bfi_sge_s {
95#ifdef __BIGENDIAN
96 u32 flags : 2,
97 rsvd : 2,
98 sg_len : 28;
99#else
100 u32 sg_len : 28,
101 rsvd : 2,
102 flags : 2;
103#endif
104 union bfi_addr_u sga;
105};
106
107/**
108 * Scatter Gather Page
109 */
110#define BFI_SGPG_DATA_SGES 7
111#define BFI_SGPG_SGES_MAX (BFI_SGPG_DATA_SGES + 1)
112#define BFI_SGPG_RSVD_WD_LEN 8
113struct bfi_sgpg_s {
114 struct bfi_sge_s sges[BFI_SGPG_SGES_MAX];
115 u32 rsvd[BFI_SGPG_RSVD_WD_LEN];
116};
117
118/*
119 * Large Message structure - 128 Bytes size Msgs
120 */
121#define BFI_LMSG_SZ 128
122#define BFI_LMSG_PL_WSZ \
123 ((BFI_LMSG_SZ - sizeof(struct bfi_mhdr_s)) / 4)
124
125struct bfi_msg_s {
126 struct bfi_mhdr_s mhdr;
127 u32 pl[BFI_LMSG_PL_WSZ];
128};
129
130/**
131 * Mailbox message structure
132 */
133#define BFI_MBMSG_SZ 7
134struct bfi_mbmsg_s {
135 struct bfi_mhdr_s mh;
136 u32 pl[BFI_MBMSG_SZ];
137};
138
139/**
140 * Message Classes
141 */
142enum bfi_mclass {
143 BFI_MC_IOC = 1, /* IO Controller (IOC) */
144 BFI_MC_DIAG = 2, /* Diagnostic Msgs */
145 BFI_MC_FLASH = 3, /* Flash message class */
146 BFI_MC_CEE = 4,
147 BFI_MC_FC_PORT = 5, /* FC port */
148 BFI_MC_IOCFC = 6, /* FC - IO Controller (IOC) */
149 BFI_MC_LL = 7, /* Link Layer */
150 BFI_MC_UF = 8, /* Unsolicited frame receive */
151 BFI_MC_FCXP = 9, /* FC Transport */
152 BFI_MC_LPS = 10, /* lport fc login services */
153 BFI_MC_RPORT = 11, /* Remote port */
154 BFI_MC_ITNIM = 12, /* I-T nexus (Initiator mode) */
155 BFI_MC_IOIM_READ = 13, /* read IO (Initiator mode) */
156 BFI_MC_IOIM_WRITE = 14, /* write IO (Initiator mode) */
157 BFI_MC_IOIM_IO = 15, /* IO (Initiator mode) */
158 BFI_MC_IOIM = 16, /* IO (Initiator mode) */
159 BFI_MC_IOIM_IOCOM = 17, /* good IO completion */
160 BFI_MC_TSKIM = 18, /* Initiator Task management */
161 BFI_MC_SBOOT = 19, /* SAN boot services */
162 BFI_MC_IPFC = 20, /* IP over FC Msgs */
163 BFI_MC_PORT = 21, /* Physical port */
164 BFI_MC_MAX = 32
165};
166
167#define BFI_IOC_MAX_CQS 4
168#define BFI_IOC_MAX_CQS_ASIC 8
169#define BFI_IOC_MSGLEN_MAX 32 /* 32 bytes */
170
171#pragma pack()
172
173#endif /* __BFI_H__ */
174
diff --git a/drivers/scsi/bfa/include/bfi/bfi_boot.h b/drivers/scsi/bfa/include/bfi/bfi_boot.h
new file mode 100644
index 000000000000..5955afe7d108
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_boot.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 2005-2009 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 * bfi_boot.h
19 */
20
21#ifndef __BFI_BOOT_H__
22#define __BFI_BOOT_H__
23
24#define BFI_BOOT_TYPE_OFF 8
25#define BFI_BOOT_PARAM_OFF 12
26
27#define BFI_BOOT_TYPE_NORMAL 0 /* param is device id */
28#define BFI_BOOT_TYPE_FLASH 1
29#define BFI_BOOT_TYPE_MEMTEST 2
30
31#define BFI_BOOT_MEMTEST_RES_ADDR 0x900
32#define BFI_BOOT_MEMTEST_RES_SIG 0xA0A1A2A3
33
34#endif
diff --git a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
new file mode 100644
index 000000000000..b3bb52b565b1
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
@@ -0,0 +1,305 @@
1/*
2 * Copyright (c) 2005-2009 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/*
19 * bfi_cbreg.h crossbow host block register definitions
20 *
21 * !!! Do not edit. Auto generated. !!!
22 */
23
24#ifndef __BFI_CBREG_H__
25#define __BFI_CBREG_H__
26
27
28#define HOSTFN0_INT_STATUS 0x00014000
29#define __HOSTFN0_INT_STATUS_LVL_MK 0x00f00000
30#define __HOSTFN0_INT_STATUS_LVL_SH 20
31#define __HOSTFN0_INT_STATUS_LVL(_v) ((_v) << __HOSTFN0_INT_STATUS_LVL_SH)
32#define __HOSTFN0_INT_STATUS_P 0x000fffff
33#define HOSTFN0_INT_MSK 0x00014004
34#define HOST_PAGE_NUM_FN0 0x00014008
35#define __HOST_PAGE_NUM_FN 0x000001ff
36#define HOSTFN1_INT_STATUS 0x00014100
37#define __HOSTFN1_INT_STAT_LVL_MK 0x00f00000
38#define __HOSTFN1_INT_STAT_LVL_SH 20
39#define __HOSTFN1_INT_STAT_LVL(_v) ((_v) << __HOSTFN1_INT_STAT_LVL_SH)
40#define __HOSTFN1_INT_STAT_P 0x000fffff
41#define HOSTFN1_INT_MSK 0x00014104
42#define HOST_PAGE_NUM_FN1 0x00014108
43#define APP_PLL_400_CTL_REG 0x00014204
44#define __P_400_PLL_LOCK 0x80000000
45#define __APP_PLL_400_SRAM_USE_100MHZ 0x00100000
46#define __APP_PLL_400_RESET_TIMER_MK 0x000e0000
47#define __APP_PLL_400_RESET_TIMER_SH 17
48#define __APP_PLL_400_RESET_TIMER(_v) ((_v) << __APP_PLL_400_RESET_TIMER_SH)
49#define __APP_PLL_400_LOGIC_SOFT_RESET 0x00010000
50#define __APP_PLL_400_CNTLMT0_1_MK 0x0000c000
51#define __APP_PLL_400_CNTLMT0_1_SH 14
52#define __APP_PLL_400_CNTLMT0_1(_v) ((_v) << __APP_PLL_400_CNTLMT0_1_SH)
53#define __APP_PLL_400_JITLMT0_1_MK 0x00003000
54#define __APP_PLL_400_JITLMT0_1_SH 12
55#define __APP_PLL_400_JITLMT0_1(_v) ((_v) << __APP_PLL_400_JITLMT0_1_SH)
56#define __APP_PLL_400_HREF 0x00000800
57#define __APP_PLL_400_HDIV 0x00000400
58#define __APP_PLL_400_P0_1_MK 0x00000300
59#define __APP_PLL_400_P0_1_SH 8
60#define __APP_PLL_400_P0_1(_v) ((_v) << __APP_PLL_400_P0_1_SH)
61#define __APP_PLL_400_Z0_2_MK 0x000000e0
62#define __APP_PLL_400_Z0_2_SH 5
63#define __APP_PLL_400_Z0_2(_v) ((_v) << __APP_PLL_400_Z0_2_SH)
64#define __APP_PLL_400_RSEL200500 0x00000010
65#define __APP_PLL_400_ENARST 0x00000008
66#define __APP_PLL_400_BYPASS 0x00000004
67#define __APP_PLL_400_LRESETN 0x00000002
68#define __APP_PLL_400_ENABLE 0x00000001
69#define APP_PLL_212_CTL_REG 0x00014208
70#define __P_212_PLL_LOCK 0x80000000
71#define __APP_PLL_212_RESET_TIMER_MK 0x000e0000
72#define __APP_PLL_212_RESET_TIMER_SH 17
73#define __APP_PLL_212_RESET_TIMER(_v) ((_v) << __APP_PLL_212_RESET_TIMER_SH)
74#define __APP_PLL_212_LOGIC_SOFT_RESET 0x00010000
75#define __APP_PLL_212_CNTLMT0_1_MK 0x0000c000
76#define __APP_PLL_212_CNTLMT0_1_SH 14
77#define __APP_PLL_212_CNTLMT0_1(_v) ((_v) << __APP_PLL_212_CNTLMT0_1_SH)
78#define __APP_PLL_212_JITLMT0_1_MK 0x00003000
79#define __APP_PLL_212_JITLMT0_1_SH 12
80#define __APP_PLL_212_JITLMT0_1(_v) ((_v) << __APP_PLL_212_JITLMT0_1_SH)
81#define __APP_PLL_212_HREF 0x00000800
82#define __APP_PLL_212_HDIV 0x00000400
83#define __APP_PLL_212_P0_1_MK 0x00000300
84#define __APP_PLL_212_P0_1_SH 8
85#define __APP_PLL_212_P0_1(_v) ((_v) << __APP_PLL_212_P0_1_SH)
86#define __APP_PLL_212_Z0_2_MK 0x000000e0
87#define __APP_PLL_212_Z0_2_SH 5
88#define __APP_PLL_212_Z0_2(_v) ((_v) << __APP_PLL_212_Z0_2_SH)
89#define __APP_PLL_212_RSEL200500 0x00000010
90#define __APP_PLL_212_ENARST 0x00000008
91#define __APP_PLL_212_BYPASS 0x00000004
92#define __APP_PLL_212_LRESETN 0x00000002
93#define __APP_PLL_212_ENABLE 0x00000001
94#define HOST_SEM0_REG 0x00014230
95#define __HOST_SEMAPHORE 0x00000001
96#define HOST_SEM1_REG 0x00014234
97#define HOST_SEM2_REG 0x00014238
98#define HOST_SEM3_REG 0x0001423c
99#define HOST_SEM0_INFO_REG 0x00014240
100#define HOST_SEM1_INFO_REG 0x00014244
101#define HOST_SEM2_INFO_REG 0x00014248
102#define HOST_SEM3_INFO_REG 0x0001424c
103#define HOSTFN0_LPU0_CMD_STAT 0x00019000
104#define __HOSTFN0_LPU0_MBOX_INFO_MK 0xfffffffe
105#define __HOSTFN0_LPU0_MBOX_INFO_SH 1
106#define __HOSTFN0_LPU0_MBOX_INFO(_v) ((_v) << __HOSTFN0_LPU0_MBOX_INFO_SH)
107#define __HOSTFN0_LPU0_MBOX_CMD_STATUS 0x00000001
108#define LPU0_HOSTFN0_CMD_STAT 0x00019008
109#define __LPU0_HOSTFN0_MBOX_INFO_MK 0xfffffffe
110#define __LPU0_HOSTFN0_MBOX_INFO_SH 1
111#define __LPU0_HOSTFN0_MBOX_INFO(_v) ((_v) << __LPU0_HOSTFN0_MBOX_INFO_SH)
112#define __LPU0_HOSTFN0_MBOX_CMD_STATUS 0x00000001
113#define HOSTFN1_LPU1_CMD_STAT 0x00019014
114#define __HOSTFN1_LPU1_MBOX_INFO_MK 0xfffffffe
115#define __HOSTFN1_LPU1_MBOX_INFO_SH 1
116#define __HOSTFN1_LPU1_MBOX_INFO(_v) ((_v) << __HOSTFN1_LPU1_MBOX_INFO_SH)
117#define __HOSTFN1_LPU1_MBOX_CMD_STATUS 0x00000001
118#define LPU1_HOSTFN1_CMD_STAT 0x0001901c
119#define __LPU1_HOSTFN1_MBOX_INFO_MK 0xfffffffe
120#define __LPU1_HOSTFN1_MBOX_INFO_SH 1
121#define __LPU1_HOSTFN1_MBOX_INFO(_v) ((_v) << __LPU1_HOSTFN1_MBOX_INFO_SH)
122#define __LPU1_HOSTFN1_MBOX_CMD_STATUS 0x00000001
123#define CPE_Q0_DEPTH 0x00010014
124#define CPE_Q0_PI 0x0001001c
125#define CPE_Q0_CI 0x00010020
126#define CPE_Q1_DEPTH 0x00010034
127#define CPE_Q1_PI 0x0001003c
128#define CPE_Q1_CI 0x00010040
129#define CPE_Q2_DEPTH 0x00010054
130#define CPE_Q2_PI 0x0001005c
131#define CPE_Q2_CI 0x00010060
132#define CPE_Q3_DEPTH 0x00010074
133#define CPE_Q3_PI 0x0001007c
134#define CPE_Q3_CI 0x00010080
135#define CPE_Q4_DEPTH 0x00010094
136#define CPE_Q4_PI 0x0001009c
137#define CPE_Q4_CI 0x000100a0
138#define CPE_Q5_DEPTH 0x000100b4
139#define CPE_Q5_PI 0x000100bc
140#define CPE_Q5_CI 0x000100c0
141#define CPE_Q6_DEPTH 0x000100d4
142#define CPE_Q6_PI 0x000100dc
143#define CPE_Q6_CI 0x000100e0
144#define CPE_Q7_DEPTH 0x000100f4
145#define CPE_Q7_PI 0x000100fc
146#define CPE_Q7_CI 0x00010100
147#define RME_Q0_DEPTH 0x00011014
148#define RME_Q0_PI 0x0001101c
149#define RME_Q0_CI 0x00011020
150#define RME_Q1_DEPTH 0x00011034
151#define RME_Q1_PI 0x0001103c
152#define RME_Q1_CI 0x00011040
153#define RME_Q2_DEPTH 0x00011054
154#define RME_Q2_PI 0x0001105c
155#define RME_Q2_CI 0x00011060
156#define RME_Q3_DEPTH 0x00011074
157#define RME_Q3_PI 0x0001107c
158#define RME_Q3_CI 0x00011080
159#define RME_Q4_DEPTH 0x00011094
160#define RME_Q4_PI 0x0001109c
161#define RME_Q4_CI 0x000110a0
162#define RME_Q5_DEPTH 0x000110b4
163#define RME_Q5_PI 0x000110bc
164#define RME_Q5_CI 0x000110c0
165#define RME_Q6_DEPTH 0x000110d4
166#define RME_Q6_PI 0x000110dc
167#define RME_Q6_CI 0x000110e0
168#define RME_Q7_DEPTH 0x000110f4
169#define RME_Q7_PI 0x000110fc
170#define RME_Q7_CI 0x00011100
171#define PSS_CTL_REG 0x00018800
172#define __PSS_I2C_CLK_DIV_MK 0x00030000
173#define __PSS_I2C_CLK_DIV_SH 16
174#define __PSS_I2C_CLK_DIV(_v) ((_v) << __PSS_I2C_CLK_DIV_SH)
175#define __PSS_LMEM_INIT_DONE 0x00001000
176#define __PSS_LMEM_RESET 0x00000200
177#define __PSS_LMEM_INIT_EN 0x00000100
178#define __PSS_LPU1_RESET 0x00000002
179#define __PSS_LPU0_RESET 0x00000001
180
181
182/*
183 * These definitions are either in error/missing in spec. Its auto-generated
184 * from hard coded values in regparse.pl.
185 */
186#define __EMPHPOST_AT_4G_MK_FIX 0x0000001c
187#define __EMPHPOST_AT_4G_SH_FIX 0x00000002
188#define __EMPHPRE_AT_4G_FIX 0x00000003
189#define __SFP_TXRATE_EN_FIX 0x00000100
190#define __SFP_RXRATE_EN_FIX 0x00000080
191
192
193/*
194 * These register definitions are auto-generated from hard coded values
195 * in regparse.pl.
196 */
197#define HOSTFN0_LPU_MBOX0_0 0x00019200
198#define HOSTFN1_LPU_MBOX0_8 0x00019260
199#define LPU_HOSTFN0_MBOX0_0 0x00019280
200#define LPU_HOSTFN1_MBOX0_8 0x000192e0
201
202
203/*
204 * These register mapping definitions are auto-generated from mapping tables
205 * in regparse.pl.
206 */
207#define BFA_IOC0_HBEAT_REG HOST_SEM0_INFO_REG
208#define BFA_IOC0_STATE_REG HOST_SEM1_INFO_REG
209#define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG
210#define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG
211#define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG
212
213#define CPE_Q_DEPTH(__n) \
214 (CPE_Q0_DEPTH + (__n) * (CPE_Q1_DEPTH - CPE_Q0_DEPTH))
215#define CPE_Q_PI(__n) \
216 (CPE_Q0_PI + (__n) * (CPE_Q1_PI - CPE_Q0_PI))
217#define CPE_Q_CI(__n) \
218 (CPE_Q0_CI + (__n) * (CPE_Q1_CI - CPE_Q0_CI))
219#define RME_Q_DEPTH(__n) \
220 (RME_Q0_DEPTH + (__n) * (RME_Q1_DEPTH - RME_Q0_DEPTH))
221#define RME_Q_PI(__n) \
222 (RME_Q0_PI + (__n) * (RME_Q1_PI - RME_Q0_PI))
223#define RME_Q_CI(__n) \
224 (RME_Q0_CI + (__n) * (RME_Q1_CI - RME_Q0_CI))
225
226#define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
227#define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
228#define CPE_Q_MASK(__q) ((__q) & 0x3)
229#define RME_Q_MASK(__q) ((__q) & 0x3)
230
231
232/*
233 * PCI MSI-X vector defines
234 */
235enum {
236 BFA_MSIX_CPE_Q0 = 0,
237 BFA_MSIX_CPE_Q1 = 1,
238 BFA_MSIX_CPE_Q2 = 2,
239 BFA_MSIX_CPE_Q3 = 3,
240 BFA_MSIX_CPE_Q4 = 4,
241 BFA_MSIX_CPE_Q5 = 5,
242 BFA_MSIX_CPE_Q6 = 6,
243 BFA_MSIX_CPE_Q7 = 7,
244 BFA_MSIX_RME_Q0 = 8,
245 BFA_MSIX_RME_Q1 = 9,
246 BFA_MSIX_RME_Q2 = 10,
247 BFA_MSIX_RME_Q3 = 11,
248 BFA_MSIX_RME_Q4 = 12,
249 BFA_MSIX_RME_Q5 = 13,
250 BFA_MSIX_RME_Q6 = 14,
251 BFA_MSIX_RME_Q7 = 15,
252 BFA_MSIX_ERR_EMC = 16,
253 BFA_MSIX_ERR_LPU0 = 17,
254 BFA_MSIX_ERR_LPU1 = 18,
255 BFA_MSIX_ERR_PSS = 19,
256 BFA_MSIX_MBOX_LPU0 = 20,
257 BFA_MSIX_MBOX_LPU1 = 21,
258 BFA_MSIX_CB_MAX = 22,
259};
260
261/*
262 * And corresponding host interrupt status bit field defines
263 */
264#define __HFN_INT_CPE_Q0 0x00000001U
265#define __HFN_INT_CPE_Q1 0x00000002U
266#define __HFN_INT_CPE_Q2 0x00000004U
267#define __HFN_INT_CPE_Q3 0x00000008U
268#define __HFN_INT_CPE_Q4 0x00000010U
269#define __HFN_INT_CPE_Q5 0x00000020U
270#define __HFN_INT_CPE_Q6 0x00000040U
271#define __HFN_INT_CPE_Q7 0x00000080U
272#define __HFN_INT_RME_Q0 0x00000100U
273#define __HFN_INT_RME_Q1 0x00000200U
274#define __HFN_INT_RME_Q2 0x00000400U
275#define __HFN_INT_RME_Q3 0x00000800U
276#define __HFN_INT_RME_Q4 0x00001000U
277#define __HFN_INT_RME_Q5 0x00002000U
278#define __HFN_INT_RME_Q6 0x00004000U
279#define __HFN_INT_RME_Q7 0x00008000U
280#define __HFN_INT_ERR_EMC 0x00010000U
281#define __HFN_INT_ERR_LPU0 0x00020000U
282#define __HFN_INT_ERR_LPU1 0x00040000U
283#define __HFN_INT_ERR_PSS 0x00080000U
284#define __HFN_INT_MBOX_LPU0 0x00100000U
285#define __HFN_INT_MBOX_LPU1 0x00200000U
286#define __HFN_INT_MBOX1_LPU0 0x00400000U
287#define __HFN_INT_MBOX1_LPU1 0x00800000U
288#define __HFN_INT_CPE_MASK 0x000000ffU
289#define __HFN_INT_RME_MASK 0x0000ff00U
290
291
292/*
293 * crossbow memory map.
294 */
295#define PSS_SMEM_PAGE_START 0x8000
296#define PSS_SMEM_PGNUM(_pg0, _ma) ((_pg0) + ((_ma) >> 15))
297#define PSS_SMEM_PGOFF(_ma) ((_ma) & 0x7fff)
298
299/*
300 * End of crossbow memory map
301 */
302
303
304#endif /* __BFI_CBREG_H__ */
305
diff --git a/drivers/scsi/bfa/include/bfi/bfi_cee.h b/drivers/scsi/bfa/include/bfi/bfi_cee.h
new file mode 100644
index 000000000000..0970596583ea
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_cee.h
@@ -0,0 +1,119 @@
1/*
2 * Copyright (c) 2005-2009 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 * Copyright (c) 2006-2009 Brocade Communications Systems, Inc.
19 * All rights reserved.
20 *
21 * bfi_dcbx.h BFI Interface (Mailbox commands and related structures)
22 * between host driver and DCBX/LLDP firmware module.
23 *
24**/
25
26#ifndef __BFI_CEE_H__
27#define __BFI_CEE_H__
28
29#include <bfi/bfi.h>
30
31#pragma pack(1)
32
33
34enum bfi_cee_h2i_msgs_e {
35 BFI_CEE_H2I_GET_CFG_REQ = 1,
36 BFI_CEE_H2I_RESET_STATS = 2,
37 BFI_CEE_H2I_GET_STATS_REQ = 3,
38};
39
40
41enum bfi_cee_i2h_msgs_e {
42 BFI_CEE_I2H_GET_CFG_RSP = BFA_I2HM(1),
43 BFI_CEE_I2H_RESET_STATS_RSP = BFA_I2HM(2),
44 BFI_CEE_I2H_GET_STATS_RSP = BFA_I2HM(3),
45};
46
47
48/* Data structures */
49
50/*
51 * BFI_CEE_H2I_RESET_STATS
52 */
53struct bfi_lldp_reset_stats_s {
54 struct bfi_mhdr_s mh;
55};
56
57/*
58 * BFI_CEE_H2I_RESET_STATS
59 */
60struct bfi_cee_reset_stats_s {
61 struct bfi_mhdr_s mh;
62};
63
64/*
65 * BFI_CEE_H2I_GET_CFG_REQ
66 */
67struct bfi_cee_get_req_s {
68 struct bfi_mhdr_s mh;
69 union bfi_addr_u dma_addr;
70};
71
72
73/*
74 * BFI_CEE_I2H_GET_CFG_RSP
75 */
76struct bfi_cee_get_rsp_s {
77 struct bfi_mhdr_s mh;
78 u8 cmd_status;
79 u8 rsvd[3];
80};
81
82/*
83 * BFI_CEE_H2I_GET_STATS_REQ
84 */
85struct bfi_cee_stats_req_s {
86 struct bfi_mhdr_s mh;
87 union bfi_addr_u dma_addr;
88};
89
90
91/*
92 * BFI_CEE_I2H_GET_STATS_RSP
93 */
94struct bfi_cee_stats_rsp_s {
95 struct bfi_mhdr_s mh;
96 u8 cmd_status;
97 u8 rsvd[3];
98};
99
100
101
102union bfi_cee_h2i_msg_u {
103 struct bfi_mhdr_s mh;
104 struct bfi_cee_get_req_s get_req;
105 struct bfi_cee_stats_req_s stats_req;
106};
107
108
109union bfi_cee_i2h_msg_u {
110 struct bfi_mhdr_s mh;
111 struct bfi_cee_get_rsp_s get_rsp;
112 struct bfi_cee_stats_rsp_s stats_rsp;
113};
114
115#pragma pack()
116
117
118#endif /* __BFI_CEE_H__ */
119
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
new file mode 100644
index 000000000000..d3caa58c0a0a
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
@@ -0,0 +1,611 @@
1/*
2 * Copyright (c) 2005-2009 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/*
19 * bfi_ctreg.h catapult host block register definitions
20 *
21 * !!! Do not edit. Auto generated. !!!
22 */
23
24#ifndef __BFI_CTREG_H__
25#define __BFI_CTREG_H__
26
27
28#define HOSTFN0_LPU_MBOX0_0 0x00019200
29#define HOSTFN1_LPU_MBOX0_8 0x00019260
30#define LPU_HOSTFN0_MBOX0_0 0x00019280
31#define LPU_HOSTFN1_MBOX0_8 0x000192e0
32#define HOSTFN2_LPU_MBOX0_0 0x00019400
33#define HOSTFN3_LPU_MBOX0_8 0x00019460
34#define LPU_HOSTFN2_MBOX0_0 0x00019480
35#define LPU_HOSTFN3_MBOX0_8 0x000194e0
36#define HOSTFN0_INT_STATUS 0x00014000
37#define __HOSTFN0_HALT_OCCURRED 0x01000000
38#define __HOSTFN0_INT_STATUS_LVL_MK 0x00f00000
39#define __HOSTFN0_INT_STATUS_LVL_SH 20
40#define __HOSTFN0_INT_STATUS_LVL(_v) ((_v) << __HOSTFN0_INT_STATUS_LVL_SH)
41#define __HOSTFN0_INT_STATUS_P_MK 0x000f0000
42#define __HOSTFN0_INT_STATUS_P_SH 16
43#define __HOSTFN0_INT_STATUS_P(_v) ((_v) << __HOSTFN0_INT_STATUS_P_SH)
44#define __HOSTFN0_INT_STATUS_F 0x0000ffff
45#define HOSTFN0_INT_MSK 0x00014004
46#define HOST_PAGE_NUM_FN0 0x00014008
47#define __HOST_PAGE_NUM_FN 0x000001ff
48#define HOST_MSIX_ERR_INDEX_FN0 0x0001400c
49#define __MSIX_ERR_INDEX_FN 0x000001ff
50#define HOSTFN1_INT_STATUS 0x00014100
51#define __HOSTFN1_HALT_OCCURRED 0x01000000
52#define __HOSTFN1_INT_STATUS_LVL_MK 0x00f00000
53#define __HOSTFN1_INT_STATUS_LVL_SH 20
54#define __HOSTFN1_INT_STATUS_LVL(_v) ((_v) << __HOSTFN1_INT_STATUS_LVL_SH)
55#define __HOSTFN1_INT_STATUS_P_MK 0x000f0000
56#define __HOSTFN1_INT_STATUS_P_SH 16
57#define __HOSTFN1_INT_STATUS_P(_v) ((_v) << __HOSTFN1_INT_STATUS_P_SH)
58#define __HOSTFN1_INT_STATUS_F 0x0000ffff
59#define HOSTFN1_INT_MSK 0x00014104
60#define HOST_PAGE_NUM_FN1 0x00014108
61#define HOST_MSIX_ERR_INDEX_FN1 0x0001410c
62#define APP_PLL_425_CTL_REG 0x00014204
63#define __P_425_PLL_LOCK 0x80000000
64#define __APP_PLL_425_SRAM_USE_100MHZ 0x00100000
65#define __APP_PLL_425_RESET_TIMER_MK 0x000e0000
66#define __APP_PLL_425_RESET_TIMER_SH 17
67#define __APP_PLL_425_RESET_TIMER(_v) ((_v) << __APP_PLL_425_RESET_TIMER_SH)
68#define __APP_PLL_425_LOGIC_SOFT_RESET 0x00010000
69#define __APP_PLL_425_CNTLMT0_1_MK 0x0000c000
70#define __APP_PLL_425_CNTLMT0_1_SH 14
71#define __APP_PLL_425_CNTLMT0_1(_v) ((_v) << __APP_PLL_425_CNTLMT0_1_SH)
72#define __APP_PLL_425_JITLMT0_1_MK 0x00003000
73#define __APP_PLL_425_JITLMT0_1_SH 12
74#define __APP_PLL_425_JITLMT0_1(_v) ((_v) << __APP_PLL_425_JITLMT0_1_SH)
75#define __APP_PLL_425_HREF 0x00000800
76#define __APP_PLL_425_HDIV 0x00000400
77#define __APP_PLL_425_P0_1_MK 0x00000300
78#define __APP_PLL_425_P0_1_SH 8
79#define __APP_PLL_425_P0_1(_v) ((_v) << __APP_PLL_425_P0_1_SH)
80#define __APP_PLL_425_Z0_2_MK 0x000000e0
81#define __APP_PLL_425_Z0_2_SH 5
82#define __APP_PLL_425_Z0_2(_v) ((_v) << __APP_PLL_425_Z0_2_SH)
83#define __APP_PLL_425_RSEL200500 0x00000010
84#define __APP_PLL_425_ENARST 0x00000008
85#define __APP_PLL_425_BYPASS 0x00000004
86#define __APP_PLL_425_LRESETN 0x00000002
87#define __APP_PLL_425_ENABLE 0x00000001
88#define APP_PLL_312_CTL_REG 0x00014208
89#define __P_312_PLL_LOCK 0x80000000
90#define __ENABLE_MAC_AHB_1 0x00800000
91#define __ENABLE_MAC_AHB_0 0x00400000
92#define __ENABLE_MAC_1 0x00200000
93#define __ENABLE_MAC_0 0x00100000
94#define __APP_PLL_312_RESET_TIMER_MK 0x000e0000
95#define __APP_PLL_312_RESET_TIMER_SH 17
96#define __APP_PLL_312_RESET_TIMER(_v) ((_v) << __APP_PLL_312_RESET_TIMER_SH)
97#define __APP_PLL_312_LOGIC_SOFT_RESET 0x00010000
98#define __APP_PLL_312_CNTLMT0_1_MK 0x0000c000
99#define __APP_PLL_312_CNTLMT0_1_SH 14
100#define __APP_PLL_312_CNTLMT0_1(_v) ((_v) << __APP_PLL_312_CNTLMT0_1_SH)
101#define __APP_PLL_312_JITLMT0_1_MK 0x00003000
102#define __APP_PLL_312_JITLMT0_1_SH 12
103#define __APP_PLL_312_JITLMT0_1(_v) ((_v) << __APP_PLL_312_JITLMT0_1_SH)
104#define __APP_PLL_312_HREF 0x00000800
105#define __APP_PLL_312_HDIV 0x00000400
106#define __APP_PLL_312_P0_1_MK 0x00000300
107#define __APP_PLL_312_P0_1_SH 8
108#define __APP_PLL_312_P0_1(_v) ((_v) << __APP_PLL_312_P0_1_SH)
109#define __APP_PLL_312_Z0_2_MK 0x000000e0
110#define __APP_PLL_312_Z0_2_SH 5
111#define __APP_PLL_312_Z0_2(_v) ((_v) << __APP_PLL_312_Z0_2_SH)
112#define __APP_PLL_312_RSEL200500 0x00000010
113#define __APP_PLL_312_ENARST 0x00000008
114#define __APP_PLL_312_BYPASS 0x00000004
115#define __APP_PLL_312_LRESETN 0x00000002
116#define __APP_PLL_312_ENABLE 0x00000001
117#define MBIST_CTL_REG 0x00014220
118#define __EDRAM_BISTR_START 0x00000004
119#define __MBIST_RESET 0x00000002
120#define __MBIST_START 0x00000001
121#define MBIST_STAT_REG 0x00014224
122#define __EDRAM_BISTR_STATUS 0x00000008
123#define __EDRAM_BISTR_DONE 0x00000004
124#define __MEM_BIT_STATUS 0x00000002
125#define __MBIST_DONE 0x00000001
126#define HOST_SEM0_REG 0x00014230
127#define __HOST_SEMAPHORE 0x00000001
128#define HOST_SEM1_REG 0x00014234
129#define HOST_SEM2_REG 0x00014238
130#define HOST_SEM3_REG 0x0001423c
131#define HOST_SEM0_INFO_REG 0x00014240
132#define HOST_SEM1_INFO_REG 0x00014244
133#define HOST_SEM2_INFO_REG 0x00014248
134#define HOST_SEM3_INFO_REG 0x0001424c
135#define ETH_MAC_SER_REG 0x00014288
136#define __APP_EMS_CKBUFAMPIN 0x00000020
137#define __APP_EMS_REFCLKSEL 0x00000010
138#define __APP_EMS_CMLCKSEL 0x00000008
139#define __APP_EMS_REFCKBUFEN2 0x00000004
140#define __APP_EMS_REFCKBUFEN1 0x00000002
141#define __APP_EMS_CHANNEL_SEL 0x00000001
142#define HOSTFN2_INT_STATUS 0x00014300
143#define __HOSTFN2_HALT_OCCURRED 0x01000000
144#define __HOSTFN2_INT_STATUS_LVL_MK 0x00f00000
145#define __HOSTFN2_INT_STATUS_LVL_SH 20
146#define __HOSTFN2_INT_STATUS_LVL(_v) ((_v) << __HOSTFN2_INT_STATUS_LVL_SH)
147#define __HOSTFN2_INT_STATUS_P_MK 0x000f0000
148#define __HOSTFN2_INT_STATUS_P_SH 16
149#define __HOSTFN2_INT_STATUS_P(_v) ((_v) << __HOSTFN2_INT_STATUS_P_SH)
150#define __HOSTFN2_INT_STATUS_F 0x0000ffff
151#define HOSTFN2_INT_MSK 0x00014304
152#define HOST_PAGE_NUM_FN2 0x00014308
153#define HOST_MSIX_ERR_INDEX_FN2 0x0001430c
154#define HOSTFN3_INT_STATUS 0x00014400
155#define __HALT_OCCURRED 0x01000000
156#define __HOSTFN3_INT_STATUS_LVL_MK 0x00f00000
157#define __HOSTFN3_INT_STATUS_LVL_SH 20
158#define __HOSTFN3_INT_STATUS_LVL(_v) ((_v) << __HOSTFN3_INT_STATUS_LVL_SH)
159#define __HOSTFN3_INT_STATUS_P_MK 0x000f0000
160#define __HOSTFN3_INT_STATUS_P_SH 16
161#define __HOSTFN3_INT_STATUS_P(_v) ((_v) << __HOSTFN3_INT_STATUS_P_SH)
162#define __HOSTFN3_INT_STATUS_F 0x0000ffff
163#define HOSTFN3_INT_MSK 0x00014404
164#define HOST_PAGE_NUM_FN3 0x00014408
165#define HOST_MSIX_ERR_INDEX_FN3 0x0001440c
166#define FNC_ID_REG 0x00014600
167#define __FUNCTION_NUMBER 0x00000007
168#define FNC_PERS_REG 0x00014604
169#define __F3_FUNCTION_ACTIVE 0x80000000
170#define __F3_FUNCTION_MODE 0x40000000
171#define __F3_PORT_MAP_MK 0x30000000
172#define __F3_PORT_MAP_SH 28
173#define __F3_PORT_MAP(_v) ((_v) << __F3_PORT_MAP_SH)
174#define __F3_VM_MODE 0x08000000
175#define __F3_INTX_STATUS_MK 0x07000000
176#define __F3_INTX_STATUS_SH 24
177#define __F3_INTX_STATUS(_v) ((_v) << __F3_INTX_STATUS_SH)
178#define __F2_FUNCTION_ACTIVE 0x00800000
179#define __F2_FUNCTION_MODE 0x00400000
180#define __F2_PORT_MAP_MK 0x00300000
181#define __F2_PORT_MAP_SH 20
182#define __F2_PORT_MAP(_v) ((_v) << __F2_PORT_MAP_SH)
183#define __F2_VM_MODE 0x00080000
184#define __F2_INTX_STATUS_MK 0x00070000
185#define __F2_INTX_STATUS_SH 16
186#define __F2_INTX_STATUS(_v) ((_v) << __F2_INTX_STATUS_SH)
187#define __F1_FUNCTION_ACTIVE 0x00008000
188#define __F1_FUNCTION_MODE 0x00004000
189#define __F1_PORT_MAP_MK 0x00003000
190#define __F1_PORT_MAP_SH 12
191#define __F1_PORT_MAP(_v) ((_v) << __F1_PORT_MAP_SH)
192#define __F1_VM_MODE 0x00000800
193#define __F1_INTX_STATUS_MK 0x00000700
194#define __F1_INTX_STATUS_SH 8
195#define __F1_INTX_STATUS(_v) ((_v) << __F1_INTX_STATUS_SH)
196#define __F0_FUNCTION_ACTIVE 0x00000080
197#define __F0_FUNCTION_MODE 0x00000040
198#define __F0_PORT_MAP_MK 0x00000030
199#define __F0_PORT_MAP_SH 4
200#define __F0_PORT_MAP(_v) ((_v) << __F0_PORT_MAP_SH)
201#define __F0_VM_MODE 0x00000008
202#define __F0_INTX_STATUS 0x00000007
203enum {
204 __F0_INTX_STATUS_MSIX = 0x0,
205 __F0_INTX_STATUS_INTA = 0x1,
206 __F0_INTX_STATUS_INTB = 0x2,
207 __F0_INTX_STATUS_INTC = 0x3,
208 __F0_INTX_STATUS_INTD = 0x4,
209};
210#define OP_MODE 0x0001460c
211#define __APP_ETH_CLK_LOWSPEED 0x00000004
212#define __GLOBAL_CORECLK_HALFSPEED 0x00000002
213#define __GLOBAL_FCOE_MODE 0x00000001
214#define HOST_SEM4_REG 0x00014610
215#define HOST_SEM5_REG 0x00014614
216#define HOST_SEM6_REG 0x00014618
217#define HOST_SEM7_REG 0x0001461c
218#define HOST_SEM4_INFO_REG 0x00014620
219#define HOST_SEM5_INFO_REG 0x00014624
220#define HOST_SEM6_INFO_REG 0x00014628
221#define HOST_SEM7_INFO_REG 0x0001462c
222#define HOSTFN0_LPU0_MBOX0_CMD_STAT 0x00019000
223#define __HOSTFN0_LPU0_MBOX0_INFO_MK 0xfffffffe
224#define __HOSTFN0_LPU0_MBOX0_INFO_SH 1
225#define __HOSTFN0_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU0_MBOX0_INFO_SH)
226#define __HOSTFN0_LPU0_MBOX0_CMD_STATUS 0x00000001
227#define HOSTFN0_LPU1_MBOX0_CMD_STAT 0x00019004
228#define __HOSTFN0_LPU1_MBOX0_INFO_MK 0xfffffffe
229#define __HOSTFN0_LPU1_MBOX0_INFO_SH 1
230#define __HOSTFN0_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU1_MBOX0_INFO_SH)
231#define __HOSTFN0_LPU1_MBOX0_CMD_STATUS 0x00000001
232#define LPU0_HOSTFN0_MBOX0_CMD_STAT 0x00019008
233#define __LPU0_HOSTFN0_MBOX0_INFO_MK 0xfffffffe
234#define __LPU0_HOSTFN0_MBOX0_INFO_SH 1
235#define __LPU0_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN0_MBOX0_INFO_SH)
236#define __LPU0_HOSTFN0_MBOX0_CMD_STATUS 0x00000001
237#define LPU1_HOSTFN0_MBOX0_CMD_STAT 0x0001900c
238#define __LPU1_HOSTFN0_MBOX0_INFO_MK 0xfffffffe
239#define __LPU1_HOSTFN0_MBOX0_INFO_SH 1
240#define __LPU1_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN0_MBOX0_INFO_SH)
241#define __LPU1_HOSTFN0_MBOX0_CMD_STATUS 0x00000001
242#define HOSTFN1_LPU0_MBOX0_CMD_STAT 0x00019010
243#define __HOSTFN1_LPU0_MBOX0_INFO_MK 0xfffffffe
244#define __HOSTFN1_LPU0_MBOX0_INFO_SH 1
245#define __HOSTFN1_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU0_MBOX0_INFO_SH)
246#define __HOSTFN1_LPU0_MBOX0_CMD_STATUS 0x00000001
247#define HOSTFN1_LPU1_MBOX0_CMD_STAT 0x00019014
248#define __HOSTFN1_LPU1_MBOX0_INFO_MK 0xfffffffe
249#define __HOSTFN1_LPU1_MBOX0_INFO_SH 1
250#define __HOSTFN1_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU1_MBOX0_INFO_SH)
251#define __HOSTFN1_LPU1_MBOX0_CMD_STATUS 0x00000001
252#define LPU0_HOSTFN1_MBOX0_CMD_STAT 0x00019018
253#define __LPU0_HOSTFN1_MBOX0_INFO_MK 0xfffffffe
254#define __LPU0_HOSTFN1_MBOX0_INFO_SH 1
255#define __LPU0_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN1_MBOX0_INFO_SH)
256#define __LPU0_HOSTFN1_MBOX0_CMD_STATUS 0x00000001
257#define LPU1_HOSTFN1_MBOX0_CMD_STAT 0x0001901c
258#define __LPU1_HOSTFN1_MBOX0_INFO_MK 0xfffffffe
259#define __LPU1_HOSTFN1_MBOX0_INFO_SH 1
260#define __LPU1_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN1_MBOX0_INFO_SH)
261#define __LPU1_HOSTFN1_MBOX0_CMD_STATUS 0x00000001
262#define HOSTFN2_LPU0_MBOX0_CMD_STAT 0x00019150
263#define __HOSTFN2_LPU0_MBOX0_INFO_MK 0xfffffffe
264#define __HOSTFN2_LPU0_MBOX0_INFO_SH 1
265#define __HOSTFN2_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU0_MBOX0_INFO_SH)
266#define __HOSTFN2_LPU0_MBOX0_CMD_STATUS 0x00000001
267#define HOSTFN2_LPU1_MBOX0_CMD_STAT 0x00019154
268#define __HOSTFN2_LPU1_MBOX0_INFO_MK 0xfffffffe
269#define __HOSTFN2_LPU1_MBOX0_INFO_SH 1
270#define __HOSTFN2_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU1_MBOX0_INFO_SH)
271#define __HOSTFN2_LPU1_MBOX0BOX0_CMD_STATUS 0x00000001
272#define LPU0_HOSTFN2_MBOX0_CMD_STAT 0x00019158
273#define __LPU0_HOSTFN2_MBOX0_INFO_MK 0xfffffffe
274#define __LPU0_HOSTFN2_MBOX0_INFO_SH 1
275#define __LPU0_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN2_MBOX0_INFO_SH)
276#define __LPU0_HOSTFN2_MBOX0_CMD_STATUS 0x00000001
277#define LPU1_HOSTFN2_MBOX0_CMD_STAT 0x0001915c
278#define __LPU1_HOSTFN2_MBOX0_INFO_MK 0xfffffffe
279#define __LPU1_HOSTFN2_MBOX0_INFO_SH 1
280#define __LPU1_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN2_MBOX0_INFO_SH)
281#define __LPU1_HOSTFN2_MBOX0_CMD_STATUS 0x00000001
282#define HOSTFN3_LPU0_MBOX0_CMD_STAT 0x00019160
283#define __HOSTFN3_LPU0_MBOX0_INFO_MK 0xfffffffe
284#define __HOSTFN3_LPU0_MBOX0_INFO_SH 1
285#define __HOSTFN3_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU0_MBOX0_INFO_SH)
286#define __HOSTFN3_LPU0_MBOX0_CMD_STATUS 0x00000001
287#define HOSTFN3_LPU1_MBOX0_CMD_STAT 0x00019164
288#define __HOSTFN3_LPU1_MBOX0_INFO_MK 0xfffffffe
289#define __HOSTFN3_LPU1_MBOX0_INFO_SH 1
290#define __HOSTFN3_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU1_MBOX0_INFO_SH)
291#define __HOSTFN3_LPU1_MBOX0_CMD_STATUS 0x00000001
292#define LPU0_HOSTFN3_MBOX0_CMD_STAT 0x00019168
293#define __LPU0_HOSTFN3_MBOX0_INFO_MK 0xfffffffe
294#define __LPU0_HOSTFN3_MBOX0_INFO_SH 1
295#define __LPU0_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN3_MBOX0_INFO_SH)
296#define __LPU0_HOSTFN3_MBOX0_CMD_STATUS 0x00000001
297#define LPU1_HOSTFN3_MBOX0_CMD_STAT 0x0001916c
298#define __LPU1_HOSTFN3_MBOX0_INFO_MK 0xfffffffe
299#define __LPU1_HOSTFN3_MBOX0_INFO_SH 1
300#define __LPU1_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN3_MBOX0_INFO_SH)
301#define __LPU1_HOSTFN3_MBOX0_CMD_STATUS 0x00000001
302#define FW_INIT_HALT_P0 0x000191ac
303#define __FW_INIT_HALT_P 0x00000001
304#define FW_INIT_HALT_P1 0x000191bc
305#define CPE_PI_PTR_Q0 0x00038000
306#define __CPE_PI_UNUSED_MK 0xffff0000
307#define __CPE_PI_UNUSED_SH 16
308#define __CPE_PI_UNUSED(_v) ((_v) << __CPE_PI_UNUSED_SH)
309#define __CPE_PI_PTR 0x0000ffff
310#define CPE_PI_PTR_Q1 0x00038040
311#define CPE_CI_PTR_Q0 0x00038004
312#define __CPE_CI_UNUSED_MK 0xffff0000
313#define __CPE_CI_UNUSED_SH 16
314#define __CPE_CI_UNUSED(_v) ((_v) << __CPE_CI_UNUSED_SH)
315#define __CPE_CI_PTR 0x0000ffff
316#define CPE_CI_PTR_Q1 0x00038044
317#define CPE_DEPTH_Q0 0x00038008
318#define __CPE_DEPTH_UNUSED_MK 0xf8000000
319#define __CPE_DEPTH_UNUSED_SH 27
320#define __CPE_DEPTH_UNUSED(_v) ((_v) << __CPE_DEPTH_UNUSED_SH)
321#define __CPE_MSIX_VEC_INDEX_MK 0x07ff0000
322#define __CPE_MSIX_VEC_INDEX_SH 16
323#define __CPE_MSIX_VEC_INDEX(_v) ((_v) << __CPE_MSIX_VEC_INDEX_SH)
324#define __CPE_DEPTH 0x0000ffff
325#define CPE_DEPTH_Q1 0x00038048
326#define CPE_QCTRL_Q0 0x0003800c
327#define __CPE_CTRL_UNUSED30_MK 0xfc000000
328#define __CPE_CTRL_UNUSED30_SH 26
329#define __CPE_CTRL_UNUSED30(_v) ((_v) << __CPE_CTRL_UNUSED30_SH)
330#define __CPE_FUNC_INT_CTRL_MK 0x03000000
331#define __CPE_FUNC_INT_CTRL_SH 24
332#define __CPE_FUNC_INT_CTRL(_v) ((_v) << __CPE_FUNC_INT_CTRL_SH)
333enum {
334 __CPE_FUNC_INT_CTRL_DISABLE = 0x0,
335 __CPE_FUNC_INT_CTRL_F2NF = 0x1,
336 __CPE_FUNC_INT_CTRL_3QUART = 0x2,
337 __CPE_FUNC_INT_CTRL_HALF = 0x3,
338};
339#define __CPE_CTRL_UNUSED20_MK 0x00f00000
340#define __CPE_CTRL_UNUSED20_SH 20
341#define __CPE_CTRL_UNUSED20(_v) ((_v) << __CPE_CTRL_UNUSED20_SH)
342#define __CPE_SCI_TH_MK 0x000f0000
343#define __CPE_SCI_TH_SH 16
344#define __CPE_SCI_TH(_v) ((_v) << __CPE_SCI_TH_SH)
345#define __CPE_CTRL_UNUSED10_MK 0x0000c000
346#define __CPE_CTRL_UNUSED10_SH 14
347#define __CPE_CTRL_UNUSED10(_v) ((_v) << __CPE_CTRL_UNUSED10_SH)
348#define __CPE_ACK_PENDING 0x00002000
349#define __CPE_CTRL_UNUSED40_MK 0x00001c00
350#define __CPE_CTRL_UNUSED40_SH 10
351#define __CPE_CTRL_UNUSED40(_v) ((_v) << __CPE_CTRL_UNUSED40_SH)
352#define __CPE_PCIEID_MK 0x00000300
353#define __CPE_PCIEID_SH 8
354#define __CPE_PCIEID(_v) ((_v) << __CPE_PCIEID_SH)
355#define __CPE_CTRL_UNUSED00_MK 0x000000fe
356#define __CPE_CTRL_UNUSED00_SH 1
357#define __CPE_CTRL_UNUSED00(_v) ((_v) << __CPE_CTRL_UNUSED00_SH)
358#define __CPE_ESIZE 0x00000001
359#define CPE_QCTRL_Q1 0x0003804c
360#define __CPE_CTRL_UNUSED31_MK 0xfc000000
361#define __CPE_CTRL_UNUSED31_SH 26
362#define __CPE_CTRL_UNUSED31(_v) ((_v) << __CPE_CTRL_UNUSED31_SH)
363#define __CPE_CTRL_UNUSED21_MK 0x00f00000
364#define __CPE_CTRL_UNUSED21_SH 20
365#define __CPE_CTRL_UNUSED21(_v) ((_v) << __CPE_CTRL_UNUSED21_SH)
366#define __CPE_CTRL_UNUSED11_MK 0x0000c000
367#define __CPE_CTRL_UNUSED11_SH 14
368#define __CPE_CTRL_UNUSED11(_v) ((_v) << __CPE_CTRL_UNUSED11_SH)
369#define __CPE_CTRL_UNUSED41_MK 0x00001c00
370#define __CPE_CTRL_UNUSED41_SH 10
371#define __CPE_CTRL_UNUSED41(_v) ((_v) << __CPE_CTRL_UNUSED41_SH)
372#define __CPE_CTRL_UNUSED01_MK 0x000000fe
373#define __CPE_CTRL_UNUSED01_SH 1
374#define __CPE_CTRL_UNUSED01(_v) ((_v) << __CPE_CTRL_UNUSED01_SH)
375#define RME_PI_PTR_Q0 0x00038020
376#define __LATENCY_TIME_STAMP_MK 0xffff0000
377#define __LATENCY_TIME_STAMP_SH 16
378#define __LATENCY_TIME_STAMP(_v) ((_v) << __LATENCY_TIME_STAMP_SH)
379#define __RME_PI_PTR 0x0000ffff
380#define RME_PI_PTR_Q1 0x00038060
381#define RME_CI_PTR_Q0 0x00038024
382#define __DELAY_TIME_STAMP_MK 0xffff0000
383#define __DELAY_TIME_STAMP_SH 16
384#define __DELAY_TIME_STAMP(_v) ((_v) << __DELAY_TIME_STAMP_SH)
385#define __RME_CI_PTR 0x0000ffff
386#define RME_CI_PTR_Q1 0x00038064
387#define RME_DEPTH_Q0 0x00038028
388#define __RME_DEPTH_UNUSED_MK 0xf8000000
389#define __RME_DEPTH_UNUSED_SH 27
390#define __RME_DEPTH_UNUSED(_v) ((_v) << __RME_DEPTH_UNUSED_SH)
391#define __RME_MSIX_VEC_INDEX_MK 0x07ff0000
392#define __RME_MSIX_VEC_INDEX_SH 16
393#define __RME_MSIX_VEC_INDEX(_v) ((_v) << __RME_MSIX_VEC_INDEX_SH)
394#define __RME_DEPTH 0x0000ffff
395#define RME_DEPTH_Q1 0x00038068
396#define RME_QCTRL_Q0 0x0003802c
397#define __RME_INT_LATENCY_TIMER_MK 0xff000000
398#define __RME_INT_LATENCY_TIMER_SH 24
399#define __RME_INT_LATENCY_TIMER(_v) ((_v) << __RME_INT_LATENCY_TIMER_SH)
400#define __RME_INT_DELAY_TIMER_MK 0x00ff0000
401#define __RME_INT_DELAY_TIMER_SH 16
402#define __RME_INT_DELAY_TIMER(_v) ((_v) << __RME_INT_DELAY_TIMER_SH)
403#define __RME_INT_DELAY_DISABLE 0x00008000
404#define __RME_DLY_DELAY_DISABLE 0x00004000
405#define __RME_ACK_PENDING 0x00002000
406#define __RME_FULL_INTERRUPT_DISABLE 0x00001000
407#define __RME_CTRL_UNUSED10_MK 0x00000c00
408#define __RME_CTRL_UNUSED10_SH 10
409#define __RME_CTRL_UNUSED10(_v) ((_v) << __RME_CTRL_UNUSED10_SH)
410#define __RME_PCIEID_MK 0x00000300
411#define __RME_PCIEID_SH 8
412#define __RME_PCIEID(_v) ((_v) << __RME_PCIEID_SH)
413#define __RME_CTRL_UNUSED00_MK 0x000000fe
414#define __RME_CTRL_UNUSED00_SH 1
415#define __RME_CTRL_UNUSED00(_v) ((_v) << __RME_CTRL_UNUSED00_SH)
416#define __RME_ESIZE 0x00000001
417#define RME_QCTRL_Q1 0x0003806c
418#define __RME_CTRL_UNUSED11_MK 0x00000c00
419#define __RME_CTRL_UNUSED11_SH 10
420#define __RME_CTRL_UNUSED11(_v) ((_v) << __RME_CTRL_UNUSED11_SH)
421#define __RME_CTRL_UNUSED01_MK 0x000000fe
422#define __RME_CTRL_UNUSED01_SH 1
423#define __RME_CTRL_UNUSED01(_v) ((_v) << __RME_CTRL_UNUSED01_SH)
424#define PSS_CTL_REG 0x00018800
425#define __PSS_I2C_CLK_DIV_MK 0x007f0000
426#define __PSS_I2C_CLK_DIV_SH 16
427#define __PSS_I2C_CLK_DIV(_v) ((_v) << __PSS_I2C_CLK_DIV_SH)
428#define __PSS_LMEM_INIT_DONE 0x00001000
429#define __PSS_LMEM_RESET 0x00000200
430#define __PSS_LMEM_INIT_EN 0x00000100
431#define __PSS_LPU1_RESET 0x00000002
432#define __PSS_LPU0_RESET 0x00000001
433#define HQM_QSET0_RXQ_DRBL_P0 0x00038000
434#define __RXQ0_ADD_VECTORS_P 0x80000000
435#define __RXQ0_STOP_P 0x40000000
436#define __RXQ0_PRD_PTR_P 0x0000ffff
437#define HQM_QSET1_RXQ_DRBL_P0 0x00038080
438#define __RXQ1_ADD_VECTORS_P 0x80000000
439#define __RXQ1_STOP_P 0x40000000
440#define __RXQ1_PRD_PTR_P 0x0000ffff
441#define HQM_QSET0_RXQ_DRBL_P1 0x0003c000
442#define HQM_QSET1_RXQ_DRBL_P1 0x0003c080
443#define HQM_QSET0_TXQ_DRBL_P0 0x00038020
444#define __TXQ0_ADD_VECTORS_P 0x80000000
445#define __TXQ0_STOP_P 0x40000000
446#define __TXQ0_PRD_PTR_P 0x0000ffff
447#define HQM_QSET1_TXQ_DRBL_P0 0x000380a0
448#define __TXQ1_ADD_VECTORS_P 0x80000000
449#define __TXQ1_STOP_P 0x40000000
450#define __TXQ1_PRD_PTR_P 0x0000ffff
451#define HQM_QSET0_TXQ_DRBL_P1 0x0003c020
452#define HQM_QSET1_TXQ_DRBL_P1 0x0003c0a0
453#define HQM_QSET0_IB_DRBL_1_P0 0x00038040
454#define __IB1_0_ACK_P 0x80000000
455#define __IB1_0_DISABLE_P 0x40000000
456#define __IB1_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff
457#define HQM_QSET1_IB_DRBL_1_P0 0x000380c0
458#define __IB1_1_ACK_P 0x80000000
459#define __IB1_1_DISABLE_P 0x40000000
460#define __IB1_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff
461#define HQM_QSET0_IB_DRBL_1_P1 0x0003c040
462#define HQM_QSET1_IB_DRBL_1_P1 0x0003c0c0
463#define HQM_QSET0_IB_DRBL_2_P0 0x00038060
464#define __IB2_0_ACK_P 0x80000000
465#define __IB2_0_DISABLE_P 0x40000000
466#define __IB2_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff
467#define HQM_QSET1_IB_DRBL_2_P0 0x000380e0
468#define __IB2_1_ACK_P 0x80000000
469#define __IB2_1_DISABLE_P 0x40000000
470#define __IB2_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff
471#define HQM_QSET0_IB_DRBL_2_P1 0x0003c060
472#define HQM_QSET1_IB_DRBL_2_P1 0x0003c0e0
473
474
475/*
476 * These definitions are either in error/missing in spec. Its auto-generated
477 * from hard coded values in regparse.pl.
478 */
479#define __EMPHPOST_AT_4G_MK_FIX 0x0000001c
480#define __EMPHPOST_AT_4G_SH_FIX 0x00000002
481#define __EMPHPRE_AT_4G_FIX 0x00000003
482#define __SFP_TXRATE_EN_FIX 0x00000100
483#define __SFP_RXRATE_EN_FIX 0x00000080
484
485
486/*
487 * These register definitions are auto-generated from hard coded values
488 * in regparse.pl.
489 */
490
491
492/*
493 * These register mapping definitions are auto-generated from mapping tables
494 * in regparse.pl.
495 */
496#define BFA_IOC0_HBEAT_REG HOST_SEM0_INFO_REG
497#define BFA_IOC0_STATE_REG HOST_SEM1_INFO_REG
498#define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG
499#define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG
500#define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG
501
502#define CPE_DEPTH_Q(__n) \
503 (CPE_DEPTH_Q0 + (__n) * (CPE_DEPTH_Q1 - CPE_DEPTH_Q0))
504#define CPE_QCTRL_Q(__n) \
505 (CPE_QCTRL_Q0 + (__n) * (CPE_QCTRL_Q1 - CPE_QCTRL_Q0))
506#define CPE_PI_PTR_Q(__n) \
507 (CPE_PI_PTR_Q0 + (__n) * (CPE_PI_PTR_Q1 - CPE_PI_PTR_Q0))
508#define CPE_CI_PTR_Q(__n) \
509 (CPE_CI_PTR_Q0 + (__n) * (CPE_CI_PTR_Q1 - CPE_CI_PTR_Q0))
510#define RME_DEPTH_Q(__n) \
511 (RME_DEPTH_Q0 + (__n) * (RME_DEPTH_Q1 - RME_DEPTH_Q0))
512#define RME_QCTRL_Q(__n) \
513 (RME_QCTRL_Q0 + (__n) * (RME_QCTRL_Q1 - RME_QCTRL_Q0))
514#define RME_PI_PTR_Q(__n) \
515 (RME_PI_PTR_Q0 + (__n) * (RME_PI_PTR_Q1 - RME_PI_PTR_Q0))
516#define RME_CI_PTR_Q(__n) \
517 (RME_CI_PTR_Q0 + (__n) * (RME_CI_PTR_Q1 - RME_CI_PTR_Q0))
518#define HQM_QSET_RXQ_DRBL_P0(__n) \
519 (HQM_QSET0_RXQ_DRBL_P0 + (__n) * (HQM_QSET1_RXQ_DRBL_P0 - \
520 HQM_QSET0_RXQ_DRBL_P0))
521#define HQM_QSET_TXQ_DRBL_P0(__n) \
522 (HQM_QSET0_TXQ_DRBL_P0 + (__n) * (HQM_QSET1_TXQ_DRBL_P0 - \
523 HQM_QSET0_TXQ_DRBL_P0))
524#define HQM_QSET_IB_DRBL_1_P0(__n) \
525 (HQM_QSET0_IB_DRBL_1_P0 + (__n) * (HQM_QSET1_IB_DRBL_1_P0 - \
526 HQM_QSET0_IB_DRBL_1_P0))
527#define HQM_QSET_IB_DRBL_2_P0(__n) \
528 (HQM_QSET0_IB_DRBL_2_P0 + (__n) * (HQM_QSET1_IB_DRBL_2_P0 - \
529 HQM_QSET0_IB_DRBL_2_P0))
530#define HQM_QSET_RXQ_DRBL_P1(__n) \
531 (HQM_QSET0_RXQ_DRBL_P1 + (__n) * (HQM_QSET1_RXQ_DRBL_P1 - \
532 HQM_QSET0_RXQ_DRBL_P1))
533#define HQM_QSET_TXQ_DRBL_P1(__n) \
534 (HQM_QSET0_TXQ_DRBL_P1 + (__n) * (HQM_QSET1_TXQ_DRBL_P1 - \
535 HQM_QSET0_TXQ_DRBL_P1))
536#define HQM_QSET_IB_DRBL_1_P1(__n) \
537 (HQM_QSET0_IB_DRBL_1_P1 + (__n) * (HQM_QSET1_IB_DRBL_1_P1 - \
538 HQM_QSET0_IB_DRBL_1_P1))
539#define HQM_QSET_IB_DRBL_2_P1(__n) \
540 (HQM_QSET0_IB_DRBL_2_P1 + (__n) * (HQM_QSET1_IB_DRBL_2_P1 - \
541 HQM_QSET0_IB_DRBL_2_P1))
542
543#define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
544#define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
545#define CPE_Q_MASK(__q) ((__q) & 0x3)
546#define RME_Q_MASK(__q) ((__q) & 0x3)
547
548
549/*
550 * PCI MSI-X vector defines
551 */
552enum {
553 BFA_MSIX_CPE_Q0 = 0,
554 BFA_MSIX_CPE_Q1 = 1,
555 BFA_MSIX_CPE_Q2 = 2,
556 BFA_MSIX_CPE_Q3 = 3,
557 BFA_MSIX_RME_Q0 = 4,
558 BFA_MSIX_RME_Q1 = 5,
559 BFA_MSIX_RME_Q2 = 6,
560 BFA_MSIX_RME_Q3 = 7,
561 BFA_MSIX_LPU_ERR = 8,
562 BFA_MSIX_CT_MAX = 9,
563};
564
565/*
566 * And corresponding host interrupt status bit field defines
567 */
568#define __HFN_INT_CPE_Q0 0x00000001U
569#define __HFN_INT_CPE_Q1 0x00000002U
570#define __HFN_INT_CPE_Q2 0x00000004U
571#define __HFN_INT_CPE_Q3 0x00000008U
572#define __HFN_INT_CPE_Q4 0x00000010U
573#define __HFN_INT_CPE_Q5 0x00000020U
574#define __HFN_INT_CPE_Q6 0x00000040U
575#define __HFN_INT_CPE_Q7 0x00000080U
576#define __HFN_INT_RME_Q0 0x00000100U
577#define __HFN_INT_RME_Q1 0x00000200U
578#define __HFN_INT_RME_Q2 0x00000400U
579#define __HFN_INT_RME_Q3 0x00000800U
580#define __HFN_INT_RME_Q4 0x00001000U
581#define __HFN_INT_RME_Q5 0x00002000U
582#define __HFN_INT_RME_Q6 0x00004000U
583#define __HFN_INT_RME_Q7 0x00008000U
584#define __HFN_INT_ERR_EMC 0x00010000U
585#define __HFN_INT_ERR_LPU0 0x00020000U
586#define __HFN_INT_ERR_LPU1 0x00040000U
587#define __HFN_INT_ERR_PSS 0x00080000U
588#define __HFN_INT_MBOX_LPU0 0x00100000U
589#define __HFN_INT_MBOX_LPU1 0x00200000U
590#define __HFN_INT_MBOX1_LPU0 0x00400000U
591#define __HFN_INT_MBOX1_LPU1 0x00800000U
592#define __HFN_INT_CPE_MASK 0x000000ffU
593#define __HFN_INT_RME_MASK 0x0000ff00U
594
595
596/*
597 * catapult memory map.
598 */
599#define LL_PGN_HQM0 0x0096
600#define LL_PGN_HQM1 0x0097
601#define PSS_SMEM_PAGE_START 0x8000
602#define PSS_SMEM_PGNUM(_pg0, _ma) ((_pg0) + ((_ma) >> 15))
603#define PSS_SMEM_PGOFF(_ma) ((_ma) & 0x7fff)
604
605/*
606 * End of catapult memory map
607 */
608
609
610#endif /* __BFI_CTREG_H__ */
611
diff --git a/drivers/scsi/bfa/include/bfi/bfi_fabric.h b/drivers/scsi/bfa/include/bfi/bfi_fabric.h
new file mode 100644
index 000000000000..c0669ed41078
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_fabric.h
@@ -0,0 +1,92 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFI_FABRIC_H__
19#define __BFI_FABRIC_H__
20
21#include <bfi/bfi.h>
22
23#pragma pack(1)
24
25enum bfi_fabric_h2i_msgs {
26 BFI_FABRIC_H2I_CREATE_REQ = 1,
27 BFI_FABRIC_H2I_DELETE_REQ = 2,
28 BFI_FABRIC_H2I_SETAUTH = 3,
29};
30
31enum bfi_fabric_i2h_msgs {
32 BFI_FABRIC_I2H_CREATE_RSP = BFA_I2HM(1),
33 BFI_FABRIC_I2H_DELETE_RSP = BFA_I2HM(2),
34 BFI_FABRIC_I2H_SETAUTH_RSP = BFA_I2HM(3),
35 BFI_FABRIC_I2H_ONLINE = BFA_I2HM(4),
36 BFI_FABRIC_I2H_OFFLINE = BFA_I2HM(5),
37};
38
39struct bfi_fabric_create_req_s {
40 bfi_mhdr_t mh; /* common msg header */
41 u8 vf_en; /* virtual fabric enable */
42 u8 rsvd;
43 u16 vf_id; /* virtual fabric ID */
44 wwn_t pwwn; /* port name */
45 wwn_t nwwn; /* node name */
46};
47
48struct bfi_fabric_create_rsp_s {
49 bfi_mhdr_t mh; /* common msg header */
50 u16 bfa_handle; /* host fabric handle */
51 u8 status; /* fabric create status */
52 u8 rsvd;
53};
54
55struct bfi_fabric_delete_req_s {
56 bfi_mhdr_t mh; /* common msg header */
57 u16 fw_handle; /* firmware fabric handle */
58 u16 rsvd;
59};
60
61struct bfi_fabric_delete_rsp_s {
62 bfi_mhdr_t mh; /* common msg header */
63 u16 bfa_handle; /* host fabric handle */
64 u8 status; /* fabric deletion status */
65 u8 rsvd;
66};
67
68#define BFI_FABRIC_AUTHSECRET_LEN 64
69struct bfi_fabric_setauth_req_s {
70 bfi_mhdr_t mh; /* common msg header */
71 u16 fw_handle; /* f/w handle of fabric */
72 u8 algorithm;
73 u8 group;
74 u8 secret[BFI_FABRIC_AUTHSECRET_LEN];
75};
76
77union bfi_fabric_h2i_msg_u {
78 bfi_msg_t *msg;
79 struct bfi_fabric_create_req_s *create_req;
80 struct bfi_fabric_delete_req_s *delete_req;
81};
82
83union bfi_fabric_i2h_msg_u {
84 bfi_msg_t *msg;
85 struct bfi_fabric_create_rsp_s *create_rsp;
86 struct bfi_fabric_delete_rsp_s *delete_rsp;
87};
88
89#pragma pack()
90
91#endif /* __BFI_FABRIC_H__ */
92
diff --git a/drivers/scsi/bfa/include/bfi/bfi_fcpim.h b/drivers/scsi/bfa/include/bfi/bfi_fcpim.h
new file mode 100644
index 000000000000..52c059fb4c3a
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_fcpim.h
@@ -0,0 +1,301 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFI_FCPIM_H__
19#define __BFI_FCPIM_H__
20
21#include "bfi.h"
22#include <protocol/fcp.h>
23
24#pragma pack(1)
25
26/*
27 * Initiator mode I-T nexus interface defines.
28 */
29
30enum bfi_itnim_h2i {
31 BFI_ITNIM_H2I_CREATE_REQ = 1, /* i-t nexus creation */
32 BFI_ITNIM_H2I_DELETE_REQ = 2, /* i-t nexus deletion */
33};
34
35enum bfi_itnim_i2h {
36 BFI_ITNIM_I2H_CREATE_RSP = BFA_I2HM(1),
37 BFI_ITNIM_I2H_DELETE_RSP = BFA_I2HM(2),
38 BFI_ITNIM_I2H_SLER_EVENT = BFA_I2HM(3),
39};
40
41struct bfi_itnim_create_req_s {
42 struct bfi_mhdr_s mh; /* common msg header */
43 u16 fw_handle; /* f/w handle for itnim */
44 u8 class; /* FC class for IO */
45 u8 seq_rec; /* sequence recovery support */
46 u8 msg_no; /* seq id of the msg */
47};
48
49struct bfi_itnim_create_rsp_s {
50 struct bfi_mhdr_s mh; /* common msg header */
51 u16 bfa_handle; /* bfa handle for itnim */
52 u8 status; /* fcp request status */
53 u8 seq_id; /* seq id of the msg */
54};
55
56struct bfi_itnim_delete_req_s {
57 struct bfi_mhdr_s mh; /* common msg header */
58 u16 fw_handle; /* f/w itnim handle */
59 u8 seq_id; /* seq id of the msg */
60 u8 rsvd;
61};
62
63struct bfi_itnim_delete_rsp_s {
64 struct bfi_mhdr_s mh; /* common msg header */
65 u16 bfa_handle; /* bfa handle for itnim */
66 u8 status; /* fcp request status */
67 u8 seq_id; /* seq id of the msg */
68};
69
70struct bfi_itnim_sler_event_s {
71 struct bfi_mhdr_s mh; /* common msg header */
72 u16 bfa_handle; /* bfa handle for itnim */
73 u16 rsvd;
74};
75
76union bfi_itnim_h2i_msg_u {
77 struct bfi_itnim_create_req_s *create_req;
78 struct bfi_itnim_delete_req_s *delete_req;
79 struct bfi_msg_s *msg;
80};
81
82union bfi_itnim_i2h_msg_u {
83 struct bfi_itnim_create_rsp_s *create_rsp;
84 struct bfi_itnim_delete_rsp_s *delete_rsp;
85 struct bfi_itnim_sler_event_s *sler_event;
86 struct bfi_msg_s *msg;
87};
88
89/*
90 * Initiator mode IO interface defines.
91 */
92
93enum bfi_ioim_h2i {
94 BFI_IOIM_H2I_IOABORT_REQ = 1, /* IO abort request */
95 BFI_IOIM_H2I_IOCLEANUP_REQ = 2, /* IO cleanup request */
96};
97
98enum bfi_ioim_i2h {
99 BFI_IOIM_I2H_IO_RSP = BFA_I2HM(1), /* non-fp IO response */
100 BFI_IOIM_I2H_IOABORT_RSP = BFA_I2HM(2),/* ABORT rsp */
101};
102
103/**
104 * IO command DIF info
105 */
106struct bfi_ioim_dif_s {
107 u32 dif_info[4];
108};
109
110/**
111 * FCP IO messages overview
112 *
113 * @note
114 * - Max CDB length supported is 64 bytes.
115 * - SCSI Linked commands and SCSI bi-directional Commands not
116 * supported.
117 *
118 */
119struct bfi_ioim_req_s {
120 struct bfi_mhdr_s mh; /* Common msg header */
121 u16 io_tag; /* I/O tag */
122 u16 rport_hdl; /* itnim/rport firmware handle */
123 struct fcp_cmnd_s cmnd; /* IO request info */
124
125 /**
126 * SG elements array within the IO request must be double word
127 * aligned. This aligment is required to optimize SGM setup for the IO.
128 */
129 struct bfi_sge_s sges[BFI_SGE_INLINE_MAX];
130 u8 io_timeout;
131 u8 dif_en;
132 u8 rsvd_a[2];
133 struct bfi_ioim_dif_s dif;
134};
135
136/**
137 * This table shows various IO status codes from firmware and their
138 * meaning. Host driver can use these status codes to further process
139 * IO completions.
140 *
141 * BFI_IOIM_STS_OK : IO completed with error free SCSI &
142 * transport status.
143 * - io-tag can be reused.
144 *
145 * BFA_IOIM_STS_SCSI_ERR : IO completed with scsi error.
146 * - io-tag can be reused.
147 *
148 * BFI_IOIM_STS_HOST_ABORTED : IO was aborted successfully due to
149 * host request.
150 * - io-tag cannot be reused yet.
151 *
152 * BFI_IOIM_STS_ABORTED : IO was aborted successfully
153 * internally by f/w.
154 * - io-tag cannot be reused yet.
155 *
156 * BFI_IOIM_STS_TIMEDOUT : IO timedout and ABTS/RRQ is happening
157 * in the firmware and
158 * - io-tag cannot be reused yet.
159 *
160 * BFI_IOIM_STS_SQER_NEEDED : Firmware could not recover the IO
161 * with sequence level error
162 * logic and hence host needs to retry
163 * this IO with a different IO tag
164 * - io-tag cannot be used yet.
165 *
166 * BFI_IOIM_STS_NEXUS_ABORT : Second Level Error Recovery from host
167 * is required because 2 consecutive ABTS
168 * timedout and host needs logout and
169 * re-login with the target
170 * - io-tag cannot be used yet.
171 *
172 * BFI_IOIM_STS_UNDERRUN : IO completed with SCSI status good,
173 * but the data tranferred is less than
174 * the fcp data length in the command.
175 * ex. SCSI INQUIRY where transferred
176 * data length and residue count in FCP
177 * response accounts for total fcp-dl
178 * - io-tag can be reused.
179 *
180 * BFI_IOIM_STS_OVERRUN : IO completed with SCSI status good,
181 * but the data transerred is more than
182 * fcp data length in the command. ex.
183 * TAPE IOs where blocks can of unequal
184 * lengths.
185 * - io-tag can be reused.
186 *
187 * BFI_IOIM_STS_RES_FREE : Firmware has completed using io-tag
188 * during abort process
189 * - io-tag can be reused.
190 *
191 * BFI_IOIM_STS_PROTO_ERR : Firmware detected a protocol error.
192 * ex target sent more data than
193 * requested, or there was data frame
194 * loss and other reasons
195 * - io-tag cannot be used yet.
196 *
197 * BFI_IOIM_STS_DIF_ERR : Firwmare detected DIF error. ex: DIF
198 * CRC err or Ref Tag err or App tag err.
199 * - io-tag can be reused.
200 *
201 * BFA_IOIM_STS_TSK_MGT_ABORT : IO was aborted because of Task
202 * Management command from the host
203 * - io-tag can be reused.
204 *
205 * BFI_IOIM_STS_UTAG : Firmware does not know about this
206 * io_tag.
207 * - io-tag can be reused.
208 */
209enum bfi_ioim_status {
210 BFI_IOIM_STS_OK = 0,
211 BFI_IOIM_STS_HOST_ABORTED = 1,
212 BFI_IOIM_STS_ABORTED = 2,
213 BFI_IOIM_STS_TIMEDOUT = 3,
214 BFI_IOIM_STS_RES_FREE = 4,
215 BFI_IOIM_STS_SQER_NEEDED = 5,
216 BFI_IOIM_STS_PROTO_ERR = 6,
217 BFI_IOIM_STS_UTAG = 7,
218 BFI_IOIM_STS_PATHTOV = 8,
219};
220
221#define BFI_IOIM_SNSLEN (256)
222/**
223 * I/O response message
224 */
225struct bfi_ioim_rsp_s {
226 struct bfi_mhdr_s mh; /* common msg header */
227 u16 io_tag; /* completed IO tag */
228 u16 bfa_rport_hndl; /* releated rport handle */
229 u8 io_status; /* IO completion status */
230 u8 reuse_io_tag; /* IO tag can be reused */
231 u16 abort_tag; /* host abort request tag */
232 u8 scsi_status; /* scsi status from target */
233 u8 sns_len; /* scsi sense length */
234 u8 resid_flags; /* IO residue flags */
235 u8 rsvd_a;
236 u32 residue; /* IO residual length in bytes */
237 u32 rsvd_b[3];
238};
239
240struct bfi_ioim_abort_req_s {
241 struct bfi_mhdr_s mh; /* Common msg header */
242 u16 io_tag; /* I/O tag */
243 u16 abort_tag; /* unique request tag */
244};
245
246/*
247 * Initiator mode task management command interface defines.
248 */
249
250enum bfi_tskim_h2i {
251 BFI_TSKIM_H2I_TM_REQ = 1, /* task-mgmt command */
252 BFI_TSKIM_H2I_ABORT_REQ = 2, /* task-mgmt command */
253};
254
255enum bfi_tskim_i2h {
256 BFI_TSKIM_I2H_TM_RSP = BFA_I2HM(1),
257};
258
259struct bfi_tskim_req_s {
260 struct bfi_mhdr_s mh; /* Common msg header */
261 u16 tsk_tag; /* task management tag */
262 u16 itn_fhdl; /* itn firmware handle */
263 lun_t lun; /* LU number */
264 u8 tm_flags; /* see fcp_tm_cmnd_t */
265 u8 t_secs; /* Timeout value in seconds */
266 u8 rsvd[2];
267};
268
269struct bfi_tskim_abortreq_s {
270 struct bfi_mhdr_s mh; /* Common msg header */
271 u16 tsk_tag; /* task management tag */
272 u16 rsvd;
273};
274
275enum bfi_tskim_status {
276 /*
277 * Following are FCP-4 spec defined status codes,
278 * **DO NOT CHANGE THEM **
279 */
280 BFI_TSKIM_STS_OK = 0,
281 BFI_TSKIM_STS_NOT_SUPP = 4,
282 BFI_TSKIM_STS_FAILED = 5,
283
284 /**
285 * Defined by BFA
286 */
287 BFI_TSKIM_STS_TIMEOUT = 10, /* TM request timedout */
288 BFI_TSKIM_STS_ABORTED = 11, /* Aborted on host request */
289};
290
291struct bfi_tskim_rsp_s {
292 struct bfi_mhdr_s mh; /* Common msg header */
293 u16 tsk_tag; /* task mgmt cmnd tag */
294 u8 tsk_status; /* @ref bfi_tskim_status */
295 u8 rsvd;
296};
297
298#pragma pack()
299
300#endif /* __BFI_FCPIM_H__ */
301
diff --git a/drivers/scsi/bfa/include/bfi/bfi_fcxp.h b/drivers/scsi/bfa/include/bfi/bfi_fcxp.h
new file mode 100644
index 000000000000..e0e995a32828
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_fcxp.h
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFI_FCXP_H__
19#define __BFI_FCXP_H__
20
21#include "bfi.h"
22
23#pragma pack(1)
24
25enum bfi_fcxp_h2i {
26 BFI_FCXP_H2I_SEND_REQ = 1,
27};
28
29enum bfi_fcxp_i2h {
30 BFI_FCXP_I2H_SEND_RSP = BFA_I2HM(1),
31};
32
33#define BFA_FCXP_MAX_SGES 2
34
35/**
36 * FCXP send request structure
37 */
38struct bfi_fcxp_send_req_s {
39 struct bfi_mhdr_s mh; /* Common msg header */
40 u16 fcxp_tag; /* driver request tag */
41 u16 max_frmsz; /* max send frame size */
42 u16 vf_id; /* vsan tag if applicable */
43 u16 rport_fw_hndl; /* FW Handle for the remote port */
44 u8 class; /* FC class used for req/rsp */
45 u8 rsp_timeout; /* timeout in secs, 0-no response */
46 u8 cts; /* continue sequence */
47 u8 lp_tag; /* lport tag */
48 struct fchs_s fchs; /* request FC header structure */
49 u32 req_len; /* request payload length */
50 u32 rsp_maxlen; /* max response length expected */
51 struct bfi_sge_s req_sge[BFA_FCXP_MAX_SGES]; /* request buf */
52 struct bfi_sge_s rsp_sge[BFA_FCXP_MAX_SGES]; /* response buf */
53};
54
55/**
56 * FCXP send response structure
57 */
58struct bfi_fcxp_send_rsp_s {
59 struct bfi_mhdr_s mh; /* Common msg header */
60 u16 fcxp_tag; /* send request tag */
61 u8 req_status; /* request status */
62 u8 rsvd;
63 u32 rsp_len; /* actual response length */
64 u32 residue_len; /* residual response length */
65 struct fchs_s fchs; /* response FC header structure */
66};
67
68#pragma pack()
69
70#endif /* __BFI_FCXP_H__ */
71
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ioc.h b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
new file mode 100644
index 000000000000..026e9c06ae97
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
@@ -0,0 +1,202 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFI_IOC_H__
19#define __BFI_IOC_H__
20
21#include "bfi.h"
22#include <defs/bfa_defs_ioc.h>
23
24#pragma pack(1)
25
26enum bfi_ioc_h2i_msgs {
27 BFI_IOC_H2I_ENABLE_REQ = 1,
28 BFI_IOC_H2I_DISABLE_REQ = 2,
29 BFI_IOC_H2I_GETATTR_REQ = 3,
30 BFI_IOC_H2I_DBG_SYNC = 4,
31 BFI_IOC_H2I_DBG_DUMP = 5,
32};
33
34enum bfi_ioc_i2h_msgs {
35 BFI_IOC_I2H_ENABLE_REPLY = BFA_I2HM(1),
36 BFI_IOC_I2H_DISABLE_REPLY = BFA_I2HM(2),
37 BFI_IOC_I2H_GETATTR_REPLY = BFA_I2HM(3),
38 BFI_IOC_I2H_READY_EVENT = BFA_I2HM(4),
39 BFI_IOC_I2H_HBEAT = BFA_I2HM(5),
40};
41
42/**
43 * BFI_IOC_H2I_GETATTR_REQ message
44 */
45struct bfi_ioc_getattr_req_s {
46 struct bfi_mhdr_s mh;
47 union bfi_addr_u attr_addr;
48};
49
50struct bfi_ioc_attr_s {
51 wwn_t mfg_wwn;
52 mac_t mfg_mac;
53 u16 rsvd_a;
54 char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)];
55 u8 pcie_gen;
56 u8 pcie_lanes_orig;
57 u8 pcie_lanes;
58 u8 rx_bbcredit; /* receive buffer credits */
59 u32 adapter_prop; /* adapter properties */
60 u16 maxfrsize; /* max receive frame size */
61 char asic_rev;
62 u8 rsvd_b;
63 char fw_version[BFA_VERSION_LEN];
64 char optrom_version[BFA_VERSION_LEN];
65 struct bfa_mfg_vpd_s vpd;
66};
67
68/**
69 * BFI_IOC_I2H_GETATTR_REPLY message
70 */
71struct bfi_ioc_getattr_reply_s {
72 struct bfi_mhdr_s mh; /* Common msg header */
73 u8 status; /* cfg reply status */
74 u8 rsvd[3];
75};
76
77/**
78 * Firmware memory page offsets
79 */
80#define BFI_IOC_SMEM_PG0_CB (0x40)
81#define BFI_IOC_SMEM_PG0_CT (0x180)
82
83/**
84 * Firmware trace offset
85 */
86#define BFI_IOC_TRC_OFF (0x4b00)
87#define BFI_IOC_TRC_ENTS 256
88
89#define BFI_IOC_FW_SIGNATURE (0xbfadbfad)
90#define BFI_IOC_MD5SUM_SZ 4
91struct bfi_ioc_image_hdr_s {
92 u32 signature; /* constant signature */
93 u32 rsvd_a;
94 u32 exec; /* exec vector */
95 u32 param; /* parameters */
96 u32 rsvd_b[4];
97 u32 md5sum[BFI_IOC_MD5SUM_SZ];
98};
99
100/**
101 * BFI_IOC_I2H_READY_EVENT message
102 */
103struct bfi_ioc_rdy_event_s {
104 struct bfi_mhdr_s mh; /* common msg header */
105 u8 init_status; /* init event status */
106 u8 rsvd[3];
107};
108
109struct bfi_ioc_hbeat_s {
110 struct bfi_mhdr_s mh; /* common msg header */
111 u32 hb_count; /* current heart beat count */
112};
113
114/**
115 * IOC hardware/firmware state
116 */
117enum bfi_ioc_state {
118 BFI_IOC_UNINIT = 0, /* not initialized */
119 BFI_IOC_INITING = 1, /* h/w is being initialized */
120 BFI_IOC_HWINIT = 2, /* h/w is initialized */
121 BFI_IOC_CFG = 3, /* IOC configuration in progress */
122 BFI_IOC_OP = 4, /* IOC is operational */
123 BFI_IOC_DISABLING = 5, /* IOC is being disabled */
124 BFI_IOC_DISABLED = 6, /* IOC is disabled */
125 BFI_IOC_CFG_DISABLED = 7, /* IOC is being disabled;transient */
126 BFI_IOC_HBFAIL = 8, /* IOC heart-beat failure */
127 BFI_IOC_MEMTEST = 9, /* IOC is doing memtest */
128};
129
130#define BFI_IOC_ENDIAN_SIG 0x12345678
131
132enum {
133 BFI_ADAPTER_TYPE_FC = 0x01, /* FC adapters */
134 BFI_ADAPTER_TYPE_MK = 0x0f0000, /* adapter type mask */
135 BFI_ADAPTER_TYPE_SH = 16, /* adapter type shift */
136 BFI_ADAPTER_NPORTS_MK = 0xff00, /* number of ports mask */
137 BFI_ADAPTER_NPORTS_SH = 8, /* number of ports shift */
138 BFI_ADAPTER_SPEED_MK = 0xff, /* adapter speed mask */
139 BFI_ADAPTER_SPEED_SH = 0, /* adapter speed shift */
140 BFI_ADAPTER_PROTO = 0x100000, /* prototype adapaters */
141 BFI_ADAPTER_TTV = 0x200000, /* TTV debug capable */
142 BFI_ADAPTER_UNSUPP = 0x400000, /* unknown adapter type */
143};
144
145#define BFI_ADAPTER_GETP(__prop,__adap_prop) \
146 (((__adap_prop) & BFI_ADAPTER_ ## __prop ## _MK) >> \
147 BFI_ADAPTER_ ## __prop ## _SH)
148#define BFI_ADAPTER_SETP(__prop, __val) \
149 ((__val) << BFI_ADAPTER_ ## __prop ## _SH)
150#define BFI_ADAPTER_IS_PROTO(__adap_type) \
151 ((__adap_type) & BFI_ADAPTER_PROTO)
152#define BFI_ADAPTER_IS_TTV(__adap_type) \
153 ((__adap_type) & BFI_ADAPTER_TTV)
154#define BFI_ADAPTER_IS_UNSUPP(__adap_type) \
155 ((__adap_type) & BFI_ADAPTER_UNSUPP)
156#define BFI_ADAPTER_IS_SPECIAL(__adap_type) \
157 ((__adap_type) & (BFI_ADAPTER_TTV | BFI_ADAPTER_PROTO | \
158 BFI_ADAPTER_UNSUPP))
159
160/**
161 * BFI_IOC_H2I_ENABLE_REQ & BFI_IOC_H2I_DISABLE_REQ messages
162 */
163struct bfi_ioc_ctrl_req_s {
164 struct bfi_mhdr_s mh;
165 u8 ioc_class;
166 u8 rsvd[3];
167};
168
169/**
170 * BFI_IOC_I2H_ENABLE_REPLY & BFI_IOC_I2H_DISABLE_REPLY messages
171 */
172struct bfi_ioc_ctrl_reply_s {
173 struct bfi_mhdr_s mh; /* Common msg header */
174 u8 status; /* enable/disable status */
175 u8 rsvd[3];
176};
177
178#define BFI_IOC_MSGSZ 8
179/**
180 * H2I Messages
181 */
182union bfi_ioc_h2i_msg_u {
183 struct bfi_mhdr_s mh;
184 struct bfi_ioc_ctrl_req_s enable_req;
185 struct bfi_ioc_ctrl_req_s disable_req;
186 struct bfi_ioc_getattr_req_s getattr_req;
187 u32 mboxmsg[BFI_IOC_MSGSZ];
188};
189
190/**
191 * I2H Messages
192 */
193union bfi_ioc_i2h_msg_u {
194 struct bfi_mhdr_s mh;
195 struct bfi_ioc_rdy_event_s rdy_event;
196 u32 mboxmsg[BFI_IOC_MSGSZ];
197};
198
199#pragma pack()
200
201#endif /* __BFI_IOC_H__ */
202
diff --git a/drivers/scsi/bfa/include/bfi/bfi_iocfc.h b/drivers/scsi/bfa/include/bfi/bfi_iocfc.h
new file mode 100644
index 000000000000..c3760df72575
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_iocfc.h
@@ -0,0 +1,177 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFI_IOCFC_H__
19#define __BFI_IOCFC_H__
20
21#include "bfi.h"
22#include <defs/bfa_defs_ioc.h>
23#include <defs/bfa_defs_iocfc.h>
24#include <defs/bfa_defs_boot.h>
25
26#pragma pack(1)
27
28enum bfi_iocfc_h2i_msgs {
29 BFI_IOCFC_H2I_CFG_REQ = 1,
30 BFI_IOCFC_H2I_GET_STATS_REQ = 2,
31 BFI_IOCFC_H2I_CLEAR_STATS_REQ = 3,
32 BFI_IOCFC_H2I_SET_INTR_REQ = 4,
33 BFI_IOCFC_H2I_UPDATEQ_REQ = 5,
34};
35
36enum bfi_iocfc_i2h_msgs {
37 BFI_IOCFC_I2H_CFG_REPLY = BFA_I2HM(1),
38 BFI_IOCFC_I2H_GET_STATS_RSP = BFA_I2HM(2),
39 BFI_IOCFC_I2H_CLEAR_STATS_RSP = BFA_I2HM(3),
40 BFI_IOCFC_I2H_UPDATEQ_RSP = BFA_I2HM(5),
41};
42
43struct bfi_iocfc_cfg_s {
44 u8 num_cqs; /* Number of CQs to be used */
45 u8 sense_buf_len; /* SCSI sense length */
46 u8 trunk_enabled; /* port trunking enabled */
47 u8 trunk_ports; /* trunk ports bit map */
48 u32 endian_sig; /* endian signature of host */
49
50 /**
51 * Request and response circular queue base addresses, size and
52 * shadow index pointers.
53 */
54 union bfi_addr_u req_cq_ba[BFI_IOC_MAX_CQS];
55 union bfi_addr_u req_shadow_ci[BFI_IOC_MAX_CQS];
56 u16 req_cq_elems[BFI_IOC_MAX_CQS];
57 union bfi_addr_u rsp_cq_ba[BFI_IOC_MAX_CQS];
58 union bfi_addr_u rsp_shadow_pi[BFI_IOC_MAX_CQS];
59 u16 rsp_cq_elems[BFI_IOC_MAX_CQS];
60
61 union bfi_addr_u stats_addr; /* DMA-able address for stats */
62 union bfi_addr_u cfgrsp_addr; /* config response dma address */
63 union bfi_addr_u ioim_snsbase; /* IO sense buffer base address */
64 struct bfa_iocfc_intr_attr_s intr_attr; /* IOC interrupt attributes */
65};
66
67/**
68 * Boot target wwn information for this port. This contains either the stored
69 * or discovered boot target port wwns for the port.
70 */
71struct bfi_iocfc_bootwwns {
72 wwn_t wwn[BFA_BOOT_BOOTLUN_MAX];
73 u8 nwwns;
74 u8 rsvd[7];
75};
76
77struct bfi_iocfc_cfgrsp_s {
78 struct bfa_iocfc_fwcfg_s fwcfg;
79 struct bfa_iocfc_intr_attr_s intr_attr;
80 struct bfi_iocfc_bootwwns bootwwns;
81};
82
83/**
84 * BFI_IOCFC_H2I_CFG_REQ message
85 */
86struct bfi_iocfc_cfg_req_s {
87 struct bfi_mhdr_s mh;
88 union bfi_addr_u ioc_cfg_dma_addr;
89};
90
91/**
92 * BFI_IOCFC_I2H_CFG_REPLY message
93 */
94struct bfi_iocfc_cfg_reply_s {
95 struct bfi_mhdr_s mh; /* Common msg header */
96 u8 cfg_success; /* cfg reply status */
97 u8 lpu_bm; /* LPUs assigned for this IOC */
98 u8 rsvd[2];
99};
100
101/**
102 * BFI_IOCFC_H2I_GET_STATS_REQ & BFI_IOCFC_H2I_CLEAR_STATS_REQ messages
103 */
104struct bfi_iocfc_stats_req_s {
105 struct bfi_mhdr_s mh; /* msg header */
106 u32 msgtag; /* msgtag for reply */
107};
108
109/**
110 * BFI_IOCFC_I2H_GET_STATS_RSP & BFI_IOCFC_I2H_CLEAR_STATS_RSP messages
111 */
112struct bfi_iocfc_stats_rsp_s {
113 struct bfi_mhdr_s mh; /* common msg header */
114 u8 status; /* reply status */
115 u8 rsvd[3];
116 u32 msgtag; /* msgtag for reply */
117};
118
119/**
120 * BFI_IOCFC_H2I_SET_INTR_REQ message
121 */
122struct bfi_iocfc_set_intr_req_s {
123 struct bfi_mhdr_s mh; /* common msg header */
124 u8 coalesce; /* enable intr coalescing*/
125 u8 rsvd[3];
126 u16 delay; /* delay timer 0..1125us */
127 u16 latency; /* latency timer 0..225us */
128};
129
130/**
131 * BFI_IOCFC_H2I_UPDATEQ_REQ message
132 */
133struct bfi_iocfc_updateq_req_s {
134 struct bfi_mhdr_s mh; /* common msg header */
135 u32 reqq_ba; /* reqq base addr */
136 u32 rspq_ba; /* rspq base addr */
137 u32 reqq_sci; /* reqq shadow ci */
138 u32 rspq_spi; /* rspq shadow pi */
139};
140
141/**
142 * BFI_IOCFC_I2H_UPDATEQ_RSP message
143 */
144struct bfi_iocfc_updateq_rsp_s {
145 struct bfi_mhdr_s mh; /* common msg header */
146 u8 status; /* updateq status */
147 u8 rsvd[3];
148};
149
150/**
151 * H2I Messages
152 */
153union bfi_iocfc_h2i_msg_u {
154 struct bfi_mhdr_s mh;
155 struct bfi_iocfc_cfg_req_s cfg_req;
156 struct bfi_iocfc_stats_req_s stats_get;
157 struct bfi_iocfc_stats_req_s stats_clr;
158 struct bfi_iocfc_updateq_req_s updateq_req;
159 u32 mboxmsg[BFI_IOC_MSGSZ];
160};
161
162/**
163 * I2H Messages
164 */
165union bfi_iocfc_i2h_msg_u {
166 struct bfi_mhdr_s mh;
167 struct bfi_iocfc_cfg_reply_s cfg_reply;
168 struct bfi_iocfc_stats_rsp_s stats_get_rsp;
169 struct bfi_iocfc_stats_rsp_s stats_clr_rsp;
170 struct bfi_iocfc_updateq_rsp_s updateq_rsp;
171 u32 mboxmsg[BFI_IOC_MSGSZ];
172};
173
174#pragma pack()
175
176#endif /* __BFI_IOCFC_H__ */
177
diff --git a/drivers/scsi/bfa/include/bfi/bfi_lport.h b/drivers/scsi/bfa/include/bfi/bfi_lport.h
new file mode 100644
index 000000000000..29010614bac9
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_lport.h
@@ -0,0 +1,89 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFI_LPORT_H__
19#define __BFI_LPORT_H__
20
21#include <bfi/bfi.h>
22
23#pragma pack(1)
24
25enum bfi_lport_h2i_msgs {
26 BFI_LPORT_H2I_CREATE_REQ = 1,
27 BFI_LPORT_H2I_DELETE_REQ = 2,
28};
29
30enum bfi_lport_i2h_msgs {
31 BFI_LPORT_I2H_CREATE_RSP = BFA_I2HM(1),
32 BFI_LPORT_I2H_DELETE_RSP = BFA_I2HM(2),
33 BFI_LPORT_I2H_ONLINE = BFA_I2HM(3),
34 BFI_LPORT_I2H_OFFLINE = BFA_I2HM(4),
35};
36
37#define BFI_LPORT_MAX_SYNNAME 64
38
39enum bfi_lport_role_e {
40 BFI_LPORT_ROLE_FCPIM = 1,
41 BFI_LPORT_ROLE_FCPTM = 2,
42 BFI_LPORT_ROLE_IPFC = 4,
43};
44
45struct bfi_lport_create_req_s {
46 bfi_mhdr_t mh; /* common msg header */
47 u16 fabric_fwhdl; /* parent fabric instance */
48 u8 roles; /* lport FC-4 roles */
49 u8 rsvd;
50 wwn_t pwwn; /* port name */
51 wwn_t nwwn; /* node name */
52 u8 symname[BFI_LPORT_MAX_SYNNAME];
53};
54
55struct bfi_lport_create_rsp_s {
56 bfi_mhdr_t mh; /* common msg header */
57 u8 status; /* lport creation status */
58 u8 rsvd[3];
59};
60
61struct bfi_lport_delete_req_s {
62 bfi_mhdr_t mh; /* common msg header */
63 u16 fw_handle; /* firmware lport handle */
64 u16 rsvd;
65};
66
67struct bfi_lport_delete_rsp_s {
68 bfi_mhdr_t mh; /* common msg header */
69 u16 bfa_handle; /* host lport handle */
70 u8 status; /* lport deletion status */
71 u8 rsvd;
72};
73
74union bfi_lport_h2i_msg_u {
75 bfi_msg_t *msg;
76 struct bfi_lport_create_req_s *create_req;
77 struct bfi_lport_delete_req_s *delete_req;
78};
79
80union bfi_lport_i2h_msg_u {
81 bfi_msg_t *msg;
82 struct bfi_lport_create_rsp_s *create_rsp;
83 struct bfi_lport_delete_rsp_s *delete_rsp;
84};
85
86#pragma pack()
87
88#endif /* __BFI_LPORT_H__ */
89
diff --git a/drivers/scsi/bfa/include/bfi/bfi_lps.h b/drivers/scsi/bfa/include/bfi/bfi_lps.h
new file mode 100644
index 000000000000..414b0e30f6ef
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_lps.h
@@ -0,0 +1,96 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFI_LPS_H__
19#define __BFI_LPS_H__
20
21#include <bfi/bfi.h>
22
23#pragma pack(1)
24
25enum bfi_lps_h2i_msgs {
26 BFI_LPS_H2I_LOGIN_REQ = 1,
27 BFI_LPS_H2I_LOGOUT_REQ = 2,
28};
29
30enum bfi_lps_i2h_msgs {
31 BFI_LPS_H2I_LOGIN_RSP = BFA_I2HM(1),
32 BFI_LPS_H2I_LOGOUT_RSP = BFA_I2HM(2),
33};
34
35struct bfi_lps_login_req_s {
36 struct bfi_mhdr_s mh; /* common msg header */
37 u8 lp_tag;
38 u8 alpa;
39 u16 pdu_size;
40 wwn_t pwwn;
41 wwn_t nwwn;
42 u8 fdisc;
43 u8 auth_en;
44 u8 rsvd[2];
45};
46
47struct bfi_lps_login_rsp_s {
48 struct bfi_mhdr_s mh; /* common msg header */
49 u8 lp_tag;
50 u8 status;
51 u8 lsrjt_rsn;
52 u8 lsrjt_expl;
53 wwn_t port_name;
54 wwn_t node_name;
55 u16 bb_credit;
56 u8 f_port;
57 u8 npiv_en;
58 u32 lp_pid : 24;
59 u32 auth_req : 8;
60 mac_t lp_mac;
61 mac_t fcf_mac;
62 u8 ext_status;
63 u8 brcd_switch;/* attached peer is brcd switch */
64};
65
66struct bfi_lps_logout_req_s {
67 struct bfi_mhdr_s mh; /* common msg header */
68 u8 lp_tag;
69 u8 rsvd[3];
70 wwn_t port_name;
71};
72
73struct bfi_lps_logout_rsp_s {
74 struct bfi_mhdr_s mh; /* common msg header */
75 u8 lp_tag;
76 u8 status;
77 u8 rsvd[2];
78};
79
80union bfi_lps_h2i_msg_u {
81 struct bfi_mhdr_s *msg;
82 struct bfi_lps_login_req_s *login_req;
83 struct bfi_lps_logout_req_s *logout_req;
84};
85
86union bfi_lps_i2h_msg_u {
87 struct bfi_msg_s *msg;
88 struct bfi_lps_login_rsp_s *login_rsp;
89 struct bfi_lps_logout_rsp_s *logout_rsp;
90};
91
92#pragma pack()
93
94#endif /* __BFI_LPS_H__ */
95
96
diff --git a/drivers/scsi/bfa/include/bfi/bfi_port.h b/drivers/scsi/bfa/include/bfi/bfi_port.h
new file mode 100644
index 000000000000..3ec3bea110ba
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_port.h
@@ -0,0 +1,115 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFI_PORT_H__
18#define __BFI_PORT_H__
19
20#include <bfi/bfi.h>
21#include <defs/bfa_defs_pport.h>
22
23#pragma pack(1)
24
25enum bfi_port_h2i {
26 BFI_PORT_H2I_ENABLE_REQ = (1),
27 BFI_PORT_H2I_DISABLE_REQ = (2),
28 BFI_PORT_H2I_GET_STATS_REQ = (3),
29 BFI_PORT_H2I_CLEAR_STATS_REQ = (4),
30};
31
32enum bfi_port_i2h {
33 BFI_PORT_I2H_ENABLE_RSP = BFA_I2HM(1),
34 BFI_PORT_I2H_DISABLE_RSP = BFA_I2HM(2),
35 BFI_PORT_I2H_GET_STATS_RSP = BFA_I2HM(3),
36 BFI_PORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4),
37};
38
39/**
40 * Generic REQ type
41 */
42struct bfi_port_generic_req_s {
43 struct bfi_mhdr_s mh; /* msg header */
44 u32 msgtag; /* msgtag for reply */
45 u32 rsvd;
46};
47
48/**
49 * Generic RSP type
50 */
51struct bfi_port_generic_rsp_s {
52 struct bfi_mhdr_s mh; /* common msg header */
53 u8 status; /* port enable status */
54 u8 rsvd[3];
55 u32 msgtag; /* msgtag for reply */
56};
57
58/**
59 * @todo
60 * BFI_PORT_H2I_ENABLE_REQ
61 */
62
63/**
64 * @todo
65 * BFI_PORT_I2H_ENABLE_RSP
66 */
67
68/**
69 * BFI_PORT_H2I_DISABLE_REQ
70 */
71
72/**
73 * BFI_PORT_I2H_DISABLE_RSP
74 */
75
76/**
77 * BFI_PORT_H2I_GET_STATS_REQ
78 */
79struct bfi_port_get_stats_req_s {
80 struct bfi_mhdr_s mh; /* common msg header */
81 union bfi_addr_u dma_addr;
82};
83
84/**
85 * BFI_PORT_I2H_GET_STATS_RSP
86 */
87
88/**
89 * BFI_PORT_H2I_CLEAR_STATS_REQ
90 */
91
92/**
93 * BFI_PORT_I2H_CLEAR_STATS_RSP
94 */
95
96union bfi_port_h2i_msg_u {
97 struct bfi_mhdr_s mh;
98 struct bfi_port_generic_req_s enable_req;
99 struct bfi_port_generic_req_s disable_req;
100 struct bfi_port_get_stats_req_s getstats_req;
101 struct bfi_port_generic_req_s clearstats_req;
102};
103
104union bfi_port_i2h_msg_u {
105 struct bfi_mhdr_s mh;
106 struct bfi_port_generic_rsp_s enable_rsp;
107 struct bfi_port_generic_rsp_s disable_rsp;
108 struct bfi_port_generic_rsp_s getstats_rsp;
109 struct bfi_port_generic_rsp_s clearstats_rsp;
110};
111
112#pragma pack()
113
114#endif /* __BFI_PORT_H__ */
115
diff --git a/drivers/scsi/bfa/include/bfi/bfi_pport.h b/drivers/scsi/bfa/include/bfi/bfi_pport.h
new file mode 100644
index 000000000000..c96d246851af
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_pport.h
@@ -0,0 +1,184 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFI_PPORT_H__
18#define __BFI_PPORT_H__
19
20#include <bfi/bfi.h>
21#include <defs/bfa_defs_pport.h>
22
23#pragma pack(1)
24
25enum bfi_pport_h2i {
26 BFI_PPORT_H2I_ENABLE_REQ = (1),
27 BFI_PPORT_H2I_DISABLE_REQ = (2),
28 BFI_PPORT_H2I_GET_STATS_REQ = (3),
29 BFI_PPORT_H2I_CLEAR_STATS_REQ = (4),
30 BFI_PPORT_H2I_SET_SVC_PARAMS_REQ = (5),
31 BFI_PPORT_H2I_ENABLE_RX_VF_TAG_REQ = (6),
32 BFI_PPORT_H2I_ENABLE_TX_VF_TAG_REQ = (7),
33 BFI_PPORT_H2I_GET_QOS_STATS_REQ = (8),
34 BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ = (9),
35};
36
37enum bfi_pport_i2h {
38 BFI_PPORT_I2H_ENABLE_RSP = BFA_I2HM(1),
39 BFI_PPORT_I2H_DISABLE_RSP = BFA_I2HM(2),
40 BFI_PPORT_I2H_GET_STATS_RSP = BFA_I2HM(3),
41 BFI_PPORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4),
42 BFI_PPORT_I2H_SET_SVC_PARAMS_RSP = BFA_I2HM(5),
43 BFI_PPORT_I2H_ENABLE_RX_VF_TAG_RSP = BFA_I2HM(6),
44 BFI_PPORT_I2H_ENABLE_TX_VF_TAG_RSP = BFA_I2HM(7),
45 BFI_PPORT_I2H_EVENT = BFA_I2HM(8),
46 BFI_PPORT_I2H_GET_QOS_STATS_RSP = BFA_I2HM(9),
47 BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP = BFA_I2HM(10),
48};
49
50/**
51 * Generic REQ type
52 */
53struct bfi_pport_generic_req_s {
54 struct bfi_mhdr_s mh; /* msg header */
55 u32 msgtag; /* msgtag for reply */
56};
57
58/**
59 * Generic RSP type
60 */
61struct bfi_pport_generic_rsp_s {
62 struct bfi_mhdr_s mh; /* common msg header */
63 u8 status; /* port enable status */
64 u8 rsvd[3];
65 u32 msgtag; /* msgtag for reply */
66};
67
68/**
69 * BFI_PPORT_H2I_ENABLE_REQ
70 */
71struct bfi_pport_enable_req_s {
72 struct bfi_mhdr_s mh; /* msg header */
73 u32 rsvd1;
74 wwn_t nwwn; /* node wwn of physical port */
75 wwn_t pwwn; /* port wwn of physical port */
76 struct bfa_pport_cfg_s port_cfg; /* port configuration */
77 union bfi_addr_u stats_dma_addr; /* DMA address for stats */
78 u32 msgtag; /* msgtag for reply */
79 u32 rsvd2;
80};
81
82/**
83 * BFI_PPORT_I2H_ENABLE_RSP
84 */
85#define bfi_pport_enable_rsp_t struct bfi_pport_generic_rsp_s
86
87/**
88 * BFI_PPORT_H2I_DISABLE_REQ
89 */
90#define bfi_pport_disable_req_t struct bfi_pport_generic_req_s
91
92/**
93 * BFI_PPORT_I2H_DISABLE_RSP
94 */
95#define bfi_pport_disable_rsp_t struct bfi_pport_generic_rsp_s
96
97/**
98 * BFI_PPORT_H2I_GET_STATS_REQ
99 */
100#define bfi_pport_get_stats_req_t struct bfi_pport_generic_req_s
101
102/**
103 * BFI_PPORT_I2H_GET_STATS_RSP
104 */
105#define bfi_pport_get_stats_rsp_t struct bfi_pport_generic_rsp_s
106
107/**
108 * BFI_PPORT_H2I_CLEAR_STATS_REQ
109 */
110#define bfi_pport_clear_stats_req_t struct bfi_pport_generic_req_s
111
112/**
113 * BFI_PPORT_I2H_CLEAR_STATS_RSP
114 */
115#define bfi_pport_clear_stats_rsp_t struct bfi_pport_generic_rsp_s
116
117/**
118 * BFI_PPORT_H2I_GET_QOS_STATS_REQ
119 */
120#define bfi_pport_get_qos_stats_req_t struct bfi_pport_generic_req_s
121
122/**
123 * BFI_PPORT_H2I_GET_QOS_STATS_RSP
124 */
125#define bfi_pport_get_qos_stats_rsp_t struct bfi_pport_generic_rsp_s
126
127/**
128 * BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ
129 */
130#define bfi_pport_clear_qos_stats_req_t struct bfi_pport_generic_req_s
131
132/**
133 * BFI_PPORT_H2I_CLEAR_QOS_STATS_RSP
134 */
135#define bfi_pport_clear_qos_stats_rsp_t struct bfi_pport_generic_rsp_s
136
137/**
138 * BFI_PPORT_H2I_SET_SVC_PARAMS_REQ
139 */
140struct bfi_pport_set_svc_params_req_s {
141 struct bfi_mhdr_s mh; /* msg header */
142 u16 tx_bbcredit; /* Tx credits */
143 u16 rsvd;
144};
145
146/**
147 * BFI_PPORT_I2H_SET_SVC_PARAMS_RSP
148 */
149
150/**
151 * BFI_PPORT_I2H_EVENT
152 */
153struct bfi_pport_event_s {
154 struct bfi_mhdr_s mh; /* common msg header */
155 struct bfa_pport_link_s link_state;
156};
157
158union bfi_pport_h2i_msg_u {
159 struct bfi_mhdr_s *mhdr;
160 struct bfi_pport_enable_req_s *penable;
161 struct bfi_pport_generic_req_s *pdisable;
162 struct bfi_pport_generic_req_s *pgetstats;
163 struct bfi_pport_generic_req_s *pclearstats;
164 struct bfi_pport_set_svc_params_req_s *psetsvcparams;
165 struct bfi_pport_get_qos_stats_req_s *pgetqosstats;
166 struct bfi_pport_generic_req_s *pclearqosstats;
167};
168
169union bfi_pport_i2h_msg_u {
170 struct bfi_msg_s *msg;
171 struct bfi_pport_generic_rsp_s *enable_rsp;
172 struct bfi_pport_disable_rsp_s *disable_rsp;
173 struct bfi_pport_generic_rsp_s *getstats_rsp;
174 struct bfi_pport_clear_stats_rsp_s *clearstats_rsp;
175 struct bfi_pport_set_svc_params_rsp_s *setsvcparasm_rsp;
176 struct bfi_pport_get_qos_stats_rsp_s *getqosstats_rsp;
177 struct bfi_pport_clear_qos_stats_rsp_s *clearqosstats_rsp;
178 struct bfi_pport_event_s *event;
179};
180
181#pragma pack()
182
183#endif /* __BFI_PPORT_H__ */
184
diff --git a/drivers/scsi/bfa/include/bfi/bfi_rport.h b/drivers/scsi/bfa/include/bfi/bfi_rport.h
new file mode 100644
index 000000000000..3520f55f09d7
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_rport.h
@@ -0,0 +1,104 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFI_RPORT_H__
19#define __BFI_RPORT_H__
20
21#include <bfi/bfi.h>
22
23#pragma pack(1)
24
25enum bfi_rport_h2i_msgs {
26 BFI_RPORT_H2I_CREATE_REQ = 1,
27 BFI_RPORT_H2I_DELETE_REQ = 2,
28 BFI_RPORT_H2I_SET_SPEED_REQ = 3,
29};
30
31enum bfi_rport_i2h_msgs {
32 BFI_RPORT_I2H_CREATE_RSP = BFA_I2HM(1),
33 BFI_RPORT_I2H_DELETE_RSP = BFA_I2HM(2),
34 BFI_RPORT_I2H_QOS_SCN = BFA_I2HM(3),
35};
36
37struct bfi_rport_create_req_s {
38 struct bfi_mhdr_s mh; /* common msg header */
39 u16 bfa_handle; /* host rport handle */
40 u16 max_frmsz; /* max rcv pdu size */
41 u32 pid : 24, /* remote port ID */
42 lp_tag : 8; /* local port tag */
43 u32 local_pid : 24, /* local port ID */
44 cisc : 8;
45 u8 fc_class; /* supported FC classes */
46 u8 vf_en; /* virtual fabric enable */
47 u16 vf_id; /* virtual fabric ID */
48};
49
50struct bfi_rport_create_rsp_s {
51 struct bfi_mhdr_s mh; /* common msg header */
52 u8 status; /* rport creation status */
53 u8 rsvd[3];
54 u16 bfa_handle; /* host rport handle */
55 u16 fw_handle; /* firmware rport handle */
56 struct bfa_rport_qos_attr_s qos_attr; /* QoS Attributes */
57};
58
59struct bfa_rport_speed_req_s {
60 struct bfi_mhdr_s mh; /* common msg header */
61 u16 fw_handle; /* firmware rport handle */
62 u8 speed; /*! rport's speed via RPSC */
63 u8 rsvd;
64};
65
66struct bfi_rport_delete_req_s {
67 struct bfi_mhdr_s mh; /* common msg header */
68 u16 fw_handle; /* firmware rport handle */
69 u16 rsvd;
70};
71
72struct bfi_rport_delete_rsp_s {
73 struct bfi_mhdr_s mh; /* common msg header */
74 u16 bfa_handle; /* host rport handle */
75 u8 status; /* rport deletion status */
76 u8 rsvd;
77};
78
79struct bfi_rport_qos_scn_s {
80 struct bfi_mhdr_s mh; /* common msg header */
81 u16 bfa_handle; /* host rport handle */
82 u16 rsvd;
83 struct bfa_rport_qos_attr_s old_qos_attr; /* Old QoS Attributes */
84 struct bfa_rport_qos_attr_s new_qos_attr; /* New QoS Attributes */
85};
86
87union bfi_rport_h2i_msg_u {
88 struct bfi_msg_s *msg;
89 struct bfi_rport_create_req_s *create_req;
90 struct bfi_rport_delete_req_s *delete_req;
91 struct bfi_rport_speed_req_s *speed_req;
92};
93
94union bfi_rport_i2h_msg_u {
95 struct bfi_msg_s *msg;
96 struct bfi_rport_create_rsp_s *create_rsp;
97 struct bfi_rport_delete_rsp_s *delete_rsp;
98 struct bfi_rport_qos_scn_s *qos_scn_evt;
99};
100
101#pragma pack()
102
103#endif /* __BFI_RPORT_H__ */
104
diff --git a/drivers/scsi/bfa/include/bfi/bfi_uf.h b/drivers/scsi/bfa/include/bfi/bfi_uf.h
new file mode 100644
index 000000000000..f328a9e7e622
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_uf.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFI_UF_H__
19#define __BFI_UF_H__
20
21#include "bfi.h"
22
23#pragma pack(1)
24
25enum bfi_uf_h2i {
26 BFI_UF_H2I_BUF_POST = 1,
27};
28
29enum bfi_uf_i2h {
30 BFI_UF_I2H_FRM_RCVD = BFA_I2HM(1),
31};
32
33#define BFA_UF_MAX_SGES 2
34
35struct bfi_uf_buf_post_s {
36 struct bfi_mhdr_s mh; /* Common msg header */
37 u16 buf_tag; /* buffer tag */
38 u16 buf_len; /* total buffer length */
39 struct bfi_sge_s sge[BFA_UF_MAX_SGES]; /* buffer DMA SGEs */
40};
41
42struct bfi_uf_frm_rcvd_s {
43 struct bfi_mhdr_s mh; /* Common msg header */
44 u16 buf_tag; /* buffer tag */
45 u16 rsvd;
46 u16 frm_len; /* received frame length */
47 u16 xfr_len; /* tranferred length */
48};
49
50#pragma pack()
51
52#endif /* __BFI_UF_H__ */
diff --git a/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
new file mode 100644
index 000000000000..43ba7064e81a
--- /dev/null
+++ b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_cna_trcmod.h CNA trace modules
20 */
21
22#ifndef __BFA_CNA_TRCMOD_H__
23#define __BFA_CNA_TRCMOD_H__
24
25#include <cs/bfa_trc.h>
26
27/*
28 * !!! Only append to the enums defined here to avoid any versioning
29 * !!! needed between trace utility and driver version
30 */
31enum {
32 BFA_TRC_CNA_CEE = 1,
33 BFA_TRC_CNA_PORT = 2,
34};
35
36#endif /* __BFA_CNA_TRCMOD_H__ */
diff --git a/drivers/scsi/bfa/include/cna/cee/bfa_cee.h b/drivers/scsi/bfa/include/cna/cee/bfa_cee.h
new file mode 100644
index 000000000000..77f297f68046
--- /dev/null
+++ b/drivers/scsi/bfa/include/cna/cee/bfa_cee.h
@@ -0,0 +1,77 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_CEE_H__
19#define __BFA_CEE_H__
20
21#include <defs/bfa_defs_cee.h>
22#include <bfa_ioc.h>
23#include <cs/bfa_trc.h>
24#include <cs/bfa_log.h>
25
26typedef void (*bfa_cee_get_attr_cbfn_t) (void *dev, bfa_status_t status);
27typedef void (*bfa_cee_get_stats_cbfn_t) (void *dev, bfa_status_t status);
28typedef void (*bfa_cee_reset_stats_cbfn_t) (void *dev, bfa_status_t status);
29typedef void (*bfa_cee_hbfail_cbfn_t) (void *dev, bfa_status_t status);
30
31struct bfa_cee_cbfn_s {
32 bfa_cee_get_attr_cbfn_t get_attr_cbfn;
33 void *get_attr_cbarg;
34 bfa_cee_get_stats_cbfn_t get_stats_cbfn;
35 void *get_stats_cbarg;
36 bfa_cee_reset_stats_cbfn_t reset_stats_cbfn;
37 void *reset_stats_cbarg;
38};
39
40struct bfa_cee_s {
41 void *dev;
42 bfa_boolean_t get_attr_pending;
43 bfa_boolean_t get_stats_pending;
44 bfa_boolean_t reset_stats_pending;
45 bfa_status_t get_attr_status;
46 bfa_status_t get_stats_status;
47 bfa_status_t reset_stats_status;
48 struct bfa_cee_cbfn_s cbfn;
49 struct bfa_ioc_hbfail_notify_s hbfail;
50 struct bfa_trc_mod_s *trcmod;
51 struct bfa_log_mod_s *logmod;
52 struct bfa_cee_attr_s *attr;
53 struct bfa_cee_stats_s *stats;
54 struct bfa_dma_s attr_dma;
55 struct bfa_dma_s stats_dma;
56 struct bfa_ioc_s *ioc;
57 struct bfa_mbox_cmd_s get_cfg_mb;
58 struct bfa_mbox_cmd_s get_stats_mb;
59 struct bfa_mbox_cmd_s reset_stats_mb;
60};
61
62u32 bfa_cee_meminfo(void);
63void bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva,
64 u64 dma_pa);
65void bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc, void *dev,
66 struct bfa_trc_mod_s *trcmod,
67 struct bfa_log_mod_s *logmod);
68void bfa_cee_detach(struct bfa_cee_s *cee);
69bfa_status_t bfa_cee_get_attr(struct bfa_cee_s *cee,
70 struct bfa_cee_attr_s *attr,
71 bfa_cee_get_attr_cbfn_t cbfn, void *cbarg);
72bfa_status_t bfa_cee_get_stats(struct bfa_cee_s *cee,
73 struct bfa_cee_stats_s *stats,
74 bfa_cee_get_stats_cbfn_t cbfn, void *cbarg);
75bfa_status_t bfa_cee_reset_stats(struct bfa_cee_s *cee,
76 bfa_cee_reset_stats_cbfn_t cbfn, void *cbarg);
77#endif /* __BFA_CEE_H__ */
diff --git a/drivers/scsi/bfa/include/cna/port/bfa_port.h b/drivers/scsi/bfa/include/cna/port/bfa_port.h
new file mode 100644
index 000000000000..7cbf17d3141b
--- /dev/null
+++ b/drivers/scsi/bfa/include/cna/port/bfa_port.h
@@ -0,0 +1,69 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_PORT_H__
19#define __BFA_PORT_H__
20
21#include <defs/bfa_defs_port.h>
22#include <bfa_ioc.h>
23#include <cs/bfa_trc.h>
24#include <cs/bfa_log.h>
25
26typedef void (*bfa_port_stats_cbfn_t) (void *dev, bfa_status_t status);
27typedef void (*bfa_port_endis_cbfn_t) (void *dev, bfa_status_t status);
28
29struct bfa_port_s {
30 void *dev;
31 struct bfa_ioc_s *ioc;
32 struct bfa_trc_mod_s *trcmod;
33 struct bfa_log_mod_s *logmod;
34 u32 msgtag;
35 bfa_boolean_t stats_busy;
36 struct bfa_mbox_cmd_s stats_mb;
37 bfa_port_stats_cbfn_t stats_cbfn;
38 void *stats_cbarg;
39 bfa_status_t stats_status;
40 union bfa_pport_stats_u *stats;
41 struct bfa_dma_s stats_dma;
42 bfa_boolean_t endis_pending;
43 struct bfa_mbox_cmd_s endis_mb;
44 bfa_port_endis_cbfn_t endis_cbfn;
45 void *endis_cbarg;
46 bfa_status_t endis_status;
47 struct bfa_ioc_hbfail_notify_s hbfail;
48};
49
50void bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
51 void *dev, struct bfa_trc_mod_s *trcmod,
52 struct bfa_log_mod_s *logmod);
53void bfa_port_detach(struct bfa_port_s *port);
54void bfa_port_hbfail(void *arg);
55
56bfa_status_t bfa_port_get_stats(struct bfa_port_s *port,
57 union bfa_pport_stats_u *stats,
58 bfa_port_stats_cbfn_t cbfn, void *cbarg);
59bfa_status_t bfa_port_clear_stats(struct bfa_port_s *port,
60 bfa_port_stats_cbfn_t cbfn, void *cbarg);
61bfa_status_t bfa_port_enable(struct bfa_port_s *port,
62 bfa_port_endis_cbfn_t cbfn, void *cbarg);
63bfa_status_t bfa_port_disable(struct bfa_port_s *port,
64 bfa_port_endis_cbfn_t cbfn, void *cbarg);
65u32 bfa_port_meminfo(void);
66void bfa_port_mem_claim(struct bfa_port_s *port, u8 *dma_kva,
67 u64 dma_pa);
68
69#endif /* __BFA_PORT_H__ */
diff --git a/drivers/scsi/bfa/include/cna/pstats/ethport_defs.h b/drivers/scsi/bfa/include/cna/pstats/ethport_defs.h
new file mode 100644
index 000000000000..1563ee512218
--- /dev/null
+++ b/drivers/scsi/bfa/include/cna/pstats/ethport_defs.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved.
4 *
5 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License (GPL) Version 2 as
9 * published by the Free Software Foundation
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
16
17#ifndef __ETHPORT_DEFS_H__
18#define __ETHPORT_DEFS_H__
19
20struct bnad_drv_stats {
21 u64 netif_queue_stop;
22 u64 netif_queue_wakeup;
23 u64 tso4;
24 u64 tso6;
25 u64 tso_err;
26 u64 tcpcsum_offload;
27 u64 udpcsum_offload;
28 u64 csum_help;
29 u64 csum_help_err;
30
31 u64 hw_stats_updates;
32 u64 netif_rx_schedule;
33 u64 netif_rx_complete;
34 u64 netif_rx_dropped;
35};
36#endif
diff --git a/drivers/scsi/bfa/include/cna/pstats/phyport_defs.h b/drivers/scsi/bfa/include/cna/pstats/phyport_defs.h
new file mode 100644
index 000000000000..eb7548030d0f
--- /dev/null
+++ b/drivers/scsi/bfa/include/cna/pstats/phyport_defs.h
@@ -0,0 +1,218 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved.
4 *
5 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License (GPL) Version 2 as
9 * published by the Free Software Foundation
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
16
17#ifndef __PHYPORT_DEFS_H__
18#define __PHYPORT_DEFS_H__
19
20#define BNA_TXF_ID_MAX 64
21#define BNA_RXF_ID_MAX 64
22
23/*
24 * Statistics
25 */
26
27/*
28 * TxF Frame Statistics
29 */
30struct bna_stats_txf {
31 u64 ucast_octets;
32 u64 ucast;
33 u64 ucast_vlan;
34
35 u64 mcast_octets;
36 u64 mcast;
37 u64 mcast_vlan;
38
39 u64 bcast_octets;
40 u64 bcast;
41 u64 bcast_vlan;
42
43 u64 errors;
44 u64 filter_vlan; /* frames filtered due to VLAN */
45 u64 filter_mac_sa; /* frames filtered due to SA check */
46};
47
48/*
49 * RxF Frame Statistics
50 */
51struct bna_stats_rxf {
52 u64 ucast_octets;
53 u64 ucast;
54 u64 ucast_vlan;
55
56 u64 mcast_octets;
57 u64 mcast;
58 u64 mcast_vlan;
59
60 u64 bcast_octets;
61 u64 bcast;
62 u64 bcast_vlan;
63 u64 frame_drops;
64};
65
66/*
67 * FC Tx Frame Statistics
68 */
69struct bna_stats_fc_tx {
70 u64 txf_ucast_octets;
71 u64 txf_ucast;
72 u64 txf_ucast_vlan;
73
74 u64 txf_mcast_octets;
75 u64 txf_mcast;
76 u64 txf_mcast_vlan;
77
78 u64 txf_bcast_octets;
79 u64 txf_bcast;
80 u64 txf_bcast_vlan;
81
82 u64 txf_parity_errors;
83 u64 txf_timeout;
84 u64 txf_fid_parity_errors;
85};
86
87/*
88 * FC Rx Frame Statistics
89 */
90struct bna_stats_fc_rx {
91 u64 rxf_ucast_octets;
92 u64 rxf_ucast;
93 u64 rxf_ucast_vlan;
94
95 u64 rxf_mcast_octets;
96 u64 rxf_mcast;
97 u64 rxf_mcast_vlan;
98
99 u64 rxf_bcast_octets;
100 u64 rxf_bcast;
101 u64 rxf_bcast_vlan;
102};
103
104/*
105 * RAD Frame Statistics
106 */
107struct cna_stats_rad {
108 u64 rx_frames;
109 u64 rx_octets;
110 u64 rx_vlan_frames;
111
112 u64 rx_ucast;
113 u64 rx_ucast_octets;
114 u64 rx_ucast_vlan;
115
116 u64 rx_mcast;
117 u64 rx_mcast_octets;
118 u64 rx_mcast_vlan;
119
120 u64 rx_bcast;
121 u64 rx_bcast_octets;
122 u64 rx_bcast_vlan;
123
124 u64 rx_drops;
125};
126
127/*
128 * BPC Tx Registers
129 */
130struct cna_stats_bpc_tx {
131 u64 tx_pause[8];
132 u64 tx_zero_pause[8]; /* Pause cancellation */
133 u64 tx_first_pause[8]; /* Pause initiation rather
134 *than retention */
135};
136
137/*
138 * BPC Rx Registers
139 */
140struct cna_stats_bpc_rx {
141 u64 rx_pause[8];
142 u64 rx_zero_pause[8]; /* Pause cancellation */
143 u64 rx_first_pause[8]; /* Pause initiation rather
144 *than retention */
145};
146
147/*
148 * MAC Rx Statistics
149 */
150struct cna_stats_mac_rx {
151 u64 frame_64; /* both rx and tx counter */
152 u64 frame_65_127; /* both rx and tx counter */
153 u64 frame_128_255; /* both rx and tx counter */
154 u64 frame_256_511; /* both rx and tx counter */
155 u64 frame_512_1023; /* both rx and tx counter */
156 u64 frame_1024_1518; /* both rx and tx counter */
157 u64 frame_1518_1522; /* both rx and tx counter */
158 u64 rx_bytes;
159 u64 rx_packets;
160 u64 rx_fcs_error;
161 u64 rx_multicast;
162 u64 rx_broadcast;
163 u64 rx_control_frames;
164 u64 rx_pause;
165 u64 rx_unknown_opcode;
166 u64 rx_alignment_error;
167 u64 rx_frame_length_error;
168 u64 rx_code_error;
169 u64 rx_carrier_sense_error;
170 u64 rx_undersize;
171 u64 rx_oversize;
172 u64 rx_fragments;
173 u64 rx_jabber;
174 u64 rx_drop;
175};
176
177/*
178 * MAC Tx Statistics
179 */
180struct cna_stats_mac_tx {
181 u64 tx_bytes;
182 u64 tx_packets;
183 u64 tx_multicast;
184 u64 tx_broadcast;
185 u64 tx_pause;
186 u64 tx_deferral;
187 u64 tx_excessive_deferral;
188 u64 tx_single_collision;
189 u64 tx_muliple_collision;
190 u64 tx_late_collision;
191 u64 tx_excessive_collision;
192 u64 tx_total_collision;
193 u64 tx_pause_honored;
194 u64 tx_drop;
195 u64 tx_jabber;
196 u64 tx_fcs_error;
197 u64 tx_control_frame;
198 u64 tx_oversize;
199 u64 tx_undersize;
200 u64 tx_fragments;
201};
202
203/*
204 * Complete statistics
205 */
206struct bna_stats {
207 struct cna_stats_mac_rx mac_rx_stats;
208 struct cna_stats_bpc_rx bpc_rx_stats;
209 struct cna_stats_rad rad_stats;
210 struct bna_stats_fc_rx fc_rx_stats;
211 struct cna_stats_mac_tx mac_tx_stats;
212 struct cna_stats_bpc_tx bpc_tx_stats;
213 struct bna_stats_fc_tx fc_tx_stats;
214 struct bna_stats_rxf rxf_stats[BNA_TXF_ID_MAX];
215 struct bna_stats_txf txf_stats[BNA_RXF_ID_MAX];
216};
217
218#endif
diff --git a/drivers/scsi/bfa/include/cs/bfa_checksum.h b/drivers/scsi/bfa/include/cs/bfa_checksum.h
new file mode 100644
index 000000000000..af8c1d533ba8
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_checksum.h
@@ -0,0 +1,60 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_checksum.h BFA checksum utilities
20 */
21
22#ifndef __BFA_CHECKSUM_H__
23#define __BFA_CHECKSUM_H__
24
25static inline u32
26bfa_checksum_u32(u32 *buf, int sz)
27{
28 int i, m = sz >> 2;
29 u32 sum = 0;
30
31 for (i = 0; i < m; i++)
32 sum ^= buf[i];
33
34 return (sum);
35}
36
37static inline u16
38bfa_checksum_u16(u16 *buf, int sz)
39{
40 int i, m = sz >> 1;
41 u16 sum = 0;
42
43 for (i = 0; i < m; i++)
44 sum ^= buf[i];
45
46 return (sum);
47}
48
49static inline u8
50bfa_checksum_u8(u8 *buf, int sz)
51{
52 int i;
53 u8 sum = 0;
54
55 for (i = 0; i < sz; i++)
56 sum ^= buf[i];
57
58 return (sum);
59}
60#endif
diff --git a/drivers/scsi/bfa/include/cs/bfa_debug.h b/drivers/scsi/bfa/include/cs/bfa_debug.h
new file mode 100644
index 000000000000..441be86b1b0f
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_debug.h
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_debug.h BFA debug interfaces
20 */
21
22#ifndef __BFA_DEBUG_H__
23#define __BFA_DEBUG_H__
24
25#define bfa_assert(__cond) do { \
26 if (!(__cond)) \
27 bfa_panic(__LINE__, __FILE__, #__cond); \
28} while (0)
29
30#define bfa_sm_fault(__mod, __event) do { \
31 bfa_sm_panic((__mod)->logm, __LINE__, __FILE__, __event); \
32} while (0)
33
34#ifndef BFA_PERF_BUILD
35#define bfa_assert_fp(__cond) bfa_assert(__cond)
36#else
37#define bfa_assert_fp(__cond)
38#endif
39
40struct bfa_log_mod_s;
41void bfa_panic(int line, char *file, char *panicstr);
42void bfa_sm_panic(struct bfa_log_mod_s *logm, int line, char *file, int event);
43
44#endif /* __BFA_DEBUG_H__ */
diff --git a/drivers/scsi/bfa/include/cs/bfa_log.h b/drivers/scsi/bfa/include/cs/bfa_log.h
new file mode 100644
index 000000000000..761cbe22130a
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_log.h
@@ -0,0 +1,184 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_log.h BFA log library data structure and function definition
20 */
21
22#ifndef __BFA_LOG_H__
23#define __BFA_LOG_H__
24
25#include <bfa_os_inc.h>
26#include <defs/bfa_defs_status.h>
27#include <defs/bfa_defs_aen.h>
28
29/*
30 * BFA log module definition
31 *
32 * To create a new module id:
33 * Add a #define at the end of the list below. Select a value for your
34 * definition so that it is one (1) greater than the previous
35 * definition. Modify the definition of BFA_LOG_MODULE_ID_MAX to become
36 * your new definition.
37 * Should have no gaps in between the values because this is used in arrays.
38 * IMPORTANT: AEN_IDs must be at the begining, otherwise update bfa_defs_aen.h
39 */
40
41enum bfa_log_module_id {
42 BFA_LOG_UNUSED_ID = 0,
43
44 /* AEN defs begin */
45 BFA_LOG_AEN_MIN = BFA_LOG_UNUSED_ID,
46
47 BFA_LOG_AEN_ID_ADAPTER = BFA_LOG_AEN_MIN + BFA_AEN_CAT_ADAPTER,/* 1 */
48 BFA_LOG_AEN_ID_PORT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_PORT, /* 2 */
49 BFA_LOG_AEN_ID_LPORT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_LPORT, /* 3 */
50 BFA_LOG_AEN_ID_RPORT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_RPORT, /* 4 */
51 BFA_LOG_AEN_ID_ITNIM = BFA_LOG_AEN_MIN + BFA_AEN_CAT_ITNIM, /* 5 */
52 BFA_LOG_AEN_ID_TIN = BFA_LOG_AEN_MIN + BFA_AEN_CAT_TIN, /* 6 */
53 BFA_LOG_AEN_ID_IPFC = BFA_LOG_AEN_MIN + BFA_AEN_CAT_IPFC, /* 7 */
54 BFA_LOG_AEN_ID_AUDIT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_AUDIT, /* 8 */
55 BFA_LOG_AEN_ID_IOC = BFA_LOG_AEN_MIN + BFA_AEN_CAT_IOC, /* 9 */
56 BFA_LOG_AEN_ID_ETHPORT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_ETHPORT,/* 10 */
57
58 BFA_LOG_AEN_MAX = BFA_LOG_AEN_ID_ETHPORT,
59 /* AEN defs end */
60
61 BFA_LOG_MODULE_ID_MIN = BFA_LOG_AEN_MAX,
62
63 BFA_LOG_FW_ID = BFA_LOG_MODULE_ID_MIN + 1,
64 BFA_LOG_HAL_ID = BFA_LOG_MODULE_ID_MIN + 2,
65 BFA_LOG_FCS_ID = BFA_LOG_MODULE_ID_MIN + 3,
66 BFA_LOG_WDRV_ID = BFA_LOG_MODULE_ID_MIN + 4,
67 BFA_LOG_LINUX_ID = BFA_LOG_MODULE_ID_MIN + 5,
68 BFA_LOG_SOLARIS_ID = BFA_LOG_MODULE_ID_MIN + 6,
69
70 BFA_LOG_MODULE_ID_MAX = BFA_LOG_SOLARIS_ID,
71
72 /* Not part of any arrays */
73 BFA_LOG_MODULE_ID_ALL = BFA_LOG_MODULE_ID_MAX + 1,
74 BFA_LOG_AEN_ALL = BFA_LOG_MODULE_ID_MAX + 2,
75 BFA_LOG_DRV_ALL = BFA_LOG_MODULE_ID_MAX + 3,
76};
77
78/*
79 * BFA log catalog name
80 */
81#define BFA_LOG_CAT_NAME "BFA"
82
83/*
84 * bfa log severity values
85 */
86enum bfa_log_severity {
87 BFA_LOG_INVALID = 0,
88 BFA_LOG_CRITICAL = 1,
89 BFA_LOG_ERROR = 2,
90 BFA_LOG_WARNING = 3,
91 BFA_LOG_INFO = 4,
92 BFA_LOG_NONE = 5,
93 BFA_LOG_LEVEL_MAX = BFA_LOG_NONE
94};
95
96#define BFA_LOG_MODID_OFFSET 16
97
98
99struct bfa_log_msgdef_s {
100 u32 msg_id; /* message id */
101 int attributes; /* attributes */
102 int severity; /* severity level */
103 char *msg_value;
104 /* msg string */
105 char *message;
106 /* msg format string */
107 int arg_type; /* argument type */
108 int arg_num; /* number of argument */
109};
110
111/*
112 * supported argument type
113 */
114enum bfa_log_arg_type {
115 BFA_LOG_S = 0, /* string */
116 BFA_LOG_D, /* decimal */
117 BFA_LOG_I, /* integer */
118 BFA_LOG_O, /* oct number */
119 BFA_LOG_U, /* unsigned integer */
120 BFA_LOG_X, /* hex number */
121 BFA_LOG_F, /* floating */
122 BFA_LOG_C, /* character */
123 BFA_LOG_L, /* double */
124 BFA_LOG_P /* pointer */
125};
126
127#define BFA_LOG_ARG_TYPE 2
128#define BFA_LOG_ARG0 (0 * BFA_LOG_ARG_TYPE)
129#define BFA_LOG_ARG1 (1 * BFA_LOG_ARG_TYPE)
130#define BFA_LOG_ARG2 (2 * BFA_LOG_ARG_TYPE)
131#define BFA_LOG_ARG3 (3 * BFA_LOG_ARG_TYPE)
132
133#define BFA_LOG_GET_MOD_ID(msgid) ((msgid >> BFA_LOG_MODID_OFFSET) & 0xff)
134#define BFA_LOG_GET_MSG_IDX(msgid) (msgid & 0xffff)
135#define BFA_LOG_GET_MSG_ID(msgdef) ((msgdef)->msg_id)
136#define BFA_LOG_GET_MSG_FMT_STRING(msgdef) ((msgdef)->message)
137#define BFA_LOG_GET_SEVERITY(msgdef) ((msgdef)->severity)
138
139/*
140 * Event attributes
141 */
142#define BFA_LOG_ATTR_NONE 0
143#define BFA_LOG_ATTR_AUDIT 1
144#define BFA_LOG_ATTR_LOG 2
145#define BFA_LOG_ATTR_FFDC 4
146
147#define BFA_LOG_CREATE_ID(msw, lsw) \
148 (((u32)msw << BFA_LOG_MODID_OFFSET) | lsw)
149
150struct bfa_log_mod_s;
151
152/**
153 * callback function
154 */
155typedef void (*bfa_log_cb_t)(struct bfa_log_mod_s *log_mod, u32 msg_id,
156 const char *format, ...);
157
158
159struct bfa_log_mod_s {
160 char instance_info[16]; /* instance info */
161 int log_level[BFA_LOG_MODULE_ID_MAX + 1];
162 /* log level for modules */
163 bfa_log_cb_t cbfn; /* callback function */
164};
165
166extern int bfa_log_init(struct bfa_log_mod_s *log_mod,
167 char *instance_name, bfa_log_cb_t cbfn);
168extern int bfa_log(struct bfa_log_mod_s *log_mod, u32 msg_id, ...);
169extern bfa_status_t bfa_log_set_level(struct bfa_log_mod_s *log_mod,
170 int mod_id, enum bfa_log_severity log_level);
171extern bfa_status_t bfa_log_set_level_all(struct bfa_log_mod_s *log_mod,
172 enum bfa_log_severity log_level);
173extern bfa_status_t bfa_log_set_level_aen(struct bfa_log_mod_s *log_mod,
174 enum bfa_log_severity log_level);
175extern enum bfa_log_severity bfa_log_get_level(struct bfa_log_mod_s *log_mod,
176 int mod_id);
177extern enum bfa_log_severity bfa_log_get_msg_level(
178 struct bfa_log_mod_s *log_mod, u32 msg_id);
179/*
180 * array of messages generated from xml files
181 */
182extern struct bfa_log_msgdef_s bfa_log_msg_array[];
183
184#endif
diff --git a/drivers/scsi/bfa/include/cs/bfa_perf.h b/drivers/scsi/bfa/include/cs/bfa_perf.h
new file mode 100644
index 000000000000..45aa5f978ff5
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_perf.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFAD_PERF_H__
18#define __BFAD_PERF_H__
19
20#ifdef BFAD_PERF_BUILD
21
22#undef bfa_trc
23#undef bfa_trc32
24#undef bfa_assert
25#undef BFA_TRC_FILE
26
27#define bfa_trc(_trcp, _data)
28#define bfa_trc32(_trcp, _data)
29#define bfa_assert(__cond)
30#define BFA_TRC_FILE(__mod, __submod)
31
32#endif
33
34#endif /* __BFAD_PERF_H__ */
diff --git a/drivers/scsi/bfa/include/cs/bfa_plog.h b/drivers/scsi/bfa/include/cs/bfa_plog.h
new file mode 100644
index 000000000000..670f86e5fc6e
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_plog.h
@@ -0,0 +1,162 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_PORTLOG_H__
18#define __BFA_PORTLOG_H__
19
20#include "protocol/fc.h"
21#include <defs/bfa_defs_types.h>
22
23#define BFA_PL_NLOG_ENTS 256
24#define BFA_PL_LOG_REC_INCR(_x) ((_x)++, (_x) %= BFA_PL_NLOG_ENTS)
25
26#define BFA_PL_STRING_LOG_SZ 32 /* number of chars in string log */
27#define BFA_PL_INT_LOG_SZ 8 /* number of integers in the integer log */
28
29enum bfa_plog_log_type {
30 BFA_PL_LOG_TYPE_INVALID = 0,
31 BFA_PL_LOG_TYPE_INT = 1,
32 BFA_PL_LOG_TYPE_STRING = 2,
33};
34
35/*
36 * the (fixed size) record format for each entry in the portlog
37 */
38struct bfa_plog_rec_s {
39 u32 tv; /* Filled by the portlog driver when the *
40 * entry is added to the circular log. */
41 u8 port; /* Source port that logged this entry. CM
42 * entities will use 0xFF */
43 u8 mid; /* Integer value to be used by all entities *
44 * while logging. The module id to string *
45 * conversion will be done by BFAL. See
46 * enum bfa_plog_mid */
47 u8 eid; /* indicates Rx, Tx, IOCTL, etc. See
48 * enum bfa_plog_eid */
49 u8 log_type; /* indicates string log or integer log.
50 * see bfa_plog_log_type_t */
51 u8 log_num_ints;
52 /*
53 * interpreted only if log_type is INT_LOG. indicates number of
54 * integers in the int_log[] (0-PL_INT_LOG_SZ).
55 */
56 u8 rsvd;
57 u16 misc; /* can be used to indicate fc frame length,
58 *etc.. */
59 union {
60 char string_log[BFA_PL_STRING_LOG_SZ];
61 u32 int_log[BFA_PL_INT_LOG_SZ];
62 } log_entry;
63
64};
65
66/*
67 * the following #defines will be used by the logging entities to indicate
68 * their module id. BFAL will convert the integer value to string format
69 *
70* process to be used while changing the following #defines:
71 * - Always add new entries at the end
72 * - define corresponding string in BFAL
73 * - Do not remove any entry or rearrange the order.
74 */
75enum bfa_plog_mid {
76 BFA_PL_MID_INVALID = 0,
77 BFA_PL_MID_DEBUG = 1,
78 BFA_PL_MID_DRVR = 2,
79 BFA_PL_MID_HAL = 3,
80 BFA_PL_MID_HAL_FCXP = 4,
81 BFA_PL_MID_HAL_UF = 5,
82 BFA_PL_MID_FCS = 6,
83 BFA_PL_MID_MAX = 7
84};
85
86#define BFA_PL_MID_STRLEN 8
87struct bfa_plog_mid_strings_s {
88 char m_str[BFA_PL_MID_STRLEN];
89};
90
91/*
92 * the following #defines will be used by the logging entities to indicate
93 * their event type. BFAL will convert the integer value to string format
94 *
95* process to be used while changing the following #defines:
96 * - Always add new entries at the end
97 * - define corresponding string in BFAL
98 * - Do not remove any entry or rearrange the order.
99 */
100enum bfa_plog_eid {
101 BFA_PL_EID_INVALID = 0,
102 BFA_PL_EID_IOC_DISABLE = 1,
103 BFA_PL_EID_IOC_ENABLE = 2,
104 BFA_PL_EID_PORT_DISABLE = 3,
105 BFA_PL_EID_PORT_ENABLE = 4,
106 BFA_PL_EID_PORT_ST_CHANGE = 5,
107 BFA_PL_EID_TX = 6,
108 BFA_PL_EID_TX_ACK1 = 7,
109 BFA_PL_EID_TX_RJT = 8,
110 BFA_PL_EID_TX_BSY = 9,
111 BFA_PL_EID_RX = 10,
112 BFA_PL_EID_RX_ACK1 = 11,
113 BFA_PL_EID_RX_RJT = 12,
114 BFA_PL_EID_RX_BSY = 13,
115 BFA_PL_EID_CT_IN = 14,
116 BFA_PL_EID_CT_OUT = 15,
117 BFA_PL_EID_DRIVER_START = 16,
118 BFA_PL_EID_RSCN = 17,
119 BFA_PL_EID_DEBUG = 18,
120 BFA_PL_EID_MISC = 19,
121 BFA_PL_EID_MAX = 20
122};
123
124#define BFA_PL_ENAME_STRLEN 8
125struct bfa_plog_eid_strings_s {
126 char e_str[BFA_PL_ENAME_STRLEN];
127};
128
129#define BFA_PL_SIG_LEN 8
130#define BFA_PL_SIG_STR "12pl123"
131
132/*
133 * per port circular log buffer
134 */
135struct bfa_plog_s {
136 char plog_sig[BFA_PL_SIG_LEN]; /* Start signature */
137 u8 plog_enabled;
138 u8 rsvd[7];
139 u32 ticks;
140 u16 head;
141 u16 tail;
142 struct bfa_plog_rec_s plog_recs[BFA_PL_NLOG_ENTS];
143};
144
145void bfa_plog_init(struct bfa_plog_s *plog);
146void bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
147 enum bfa_plog_eid event, u16 misc, char *log_str);
148void bfa_plog_intarr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
149 enum bfa_plog_eid event, u16 misc,
150 u32 *intarr, u32 num_ints);
151void bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
152 enum bfa_plog_eid event, u16 misc,
153 struct fchs_s *fchdr);
154void bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
155 enum bfa_plog_eid event, u16 misc,
156 struct fchs_s *fchdr, u32 pld_w0);
157void bfa_plog_clear(struct bfa_plog_s *plog);
158void bfa_plog_enable(struct bfa_plog_s *plog);
159void bfa_plog_disable(struct bfa_plog_s *plog);
160bfa_boolean_t bfa_plog_get_setting(struct bfa_plog_s *plog);
161
162#endif /* __BFA_PORTLOG_H__ */
diff --git a/drivers/scsi/bfa/include/cs/bfa_q.h b/drivers/scsi/bfa/include/cs/bfa_q.h
new file mode 100644
index 000000000000..ea895facedbc
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_q.h
@@ -0,0 +1,81 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_q.h Circular queue definitions.
20 */
21
22#ifndef __BFA_Q_H__
23#define __BFA_Q_H__
24
25#define bfa_q_first(_q) ((void *)(((struct list_head *) (_q))->next))
26#define bfa_q_next(_qe) (((struct list_head *) (_qe))->next)
27#define bfa_q_prev(_qe) (((struct list_head *) (_qe))->prev)
28
29/*
30 * bfa_q_qe_init - to initialize a queue element
31 */
32#define bfa_q_qe_init(_qe) { \
33 bfa_q_next(_qe) = (struct list_head *) NULL; \
34 bfa_q_prev(_qe) = (struct list_head *) NULL; \
35}
36
37/*
38 * bfa_q_deq - dequeue an element from head of the queue
39 */
40#define bfa_q_deq(_q, _qe) { \
41 if (!list_empty(_q)) { \
42 (*((struct list_head **) (_qe))) = bfa_q_next(_q); \
43 bfa_q_prev(bfa_q_next(*((struct list_head **) _qe))) = \
44 (struct list_head *) (_q); \
45 bfa_q_next(_q) = bfa_q_next(*((struct list_head **) _qe)); \
46 BFA_Q_DBG_INIT(*((struct list_head **) _qe)); \
47 } else { \
48 *((struct list_head **) (_qe)) = (struct list_head *) NULL; \
49 } \
50}
51
52/*
53 * bfa_q_deq_tail - dequeue an element from tail of the queue
54 */
55#define bfa_q_deq_tail(_q, _qe) { \
56 if (!list_empty(_q)) { \
57 *((struct list_head **) (_qe)) = bfa_q_prev(_q); \
58 bfa_q_next(bfa_q_prev(*((struct list_head **) _qe))) = \
59 (struct list_head *) (_q); \
60 bfa_q_prev(_q) = bfa_q_prev(*(struct list_head **) _qe); \
61 BFA_Q_DBG_INIT(*((struct list_head **) _qe)); \
62 } else { \
63 *((struct list_head **) (_qe)) = (struct list_head *) NULL; \
64 } \
65}
66
67/*
68 * #ifdef BFA_DEBUG (Using bfa_assert to check for debug_build is not
69 * consistent across modules)
70 */
71#ifndef BFA_PERF_BUILD
72#define BFA_Q_DBG_INIT(_qe) bfa_q_qe_init(_qe)
73#else
74#define BFA_Q_DBG_INIT(_qe)
75#endif
76
77#define bfa_q_is_on_q(_q, _qe) \
78 bfa_q_is_on_q_func(_q, (struct list_head *)(_qe))
79extern int bfa_q_is_on_q_func(struct list_head *q, struct list_head *qe);
80
81#endif
diff --git a/drivers/scsi/bfa/include/cs/bfa_sm.h b/drivers/scsi/bfa/include/cs/bfa_sm.h
new file mode 100644
index 000000000000..9877066680a6
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_sm.h
@@ -0,0 +1,69 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfasm.h State machine defines
20 */
21
22#ifndef __BFA_SM_H__
23#define __BFA_SM_H__
24
25typedef void (*bfa_sm_t)(void *sm, int event);
26
27#define bfa_sm_set_state(_sm, _state) (_sm)->sm = (bfa_sm_t)(_state)
28#define bfa_sm_send_event(_sm, _event) (_sm)->sm((_sm), (_event))
29#define bfa_sm_get_state(_sm) ((_sm)->sm)
30#define bfa_sm_cmp_state(_sm, _state) ((_sm)->sm == (bfa_sm_t)(_state))
31
32/**
33 * For converting from state machine function to state encoding.
34 */
35struct bfa_sm_table_s {
36 bfa_sm_t sm; /* state machine function */
37 int state; /* state machine encoding */
38 char *name; /* state name for display */
39};
40#define BFA_SM(_sm) ((bfa_sm_t)(_sm))
41
42int bfa_sm_to_state(struct bfa_sm_table_s *smt, bfa_sm_t sm);
43
44/**
45 * State machine with entry actions.
46 */
47typedef void (*bfa_fsm_t)(void *fsm, int event);
48
49/**
50 * oc - object class eg. bfa_ioc
51 * st - state, eg. reset
52 * otype - object type, eg. struct bfa_ioc_s
53 * etype - object type, eg. enum ioc_event
54 */
55#define bfa_fsm_state_decl(oc, st, otype, etype) \
56 static void oc ## _sm_ ## st(otype * fsm, etype event); \
57 static void oc ## _sm_ ## st ## _entry(otype * fsm)
58
59#define bfa_fsm_set_state(_fsm, _state) do { \
60 (_fsm)->fsm = (bfa_fsm_t)(_state); \
61 _state ## _entry(_fsm); \
62} while (0)
63
64#define bfa_fsm_send_event(_fsm, _event) \
65 (_fsm)->fsm((_fsm), (_event))
66#define bfa_fsm_cmp_state(_fsm, _state) \
67 ((_fsm)->fsm == (bfa_fsm_t)(_state))
68
69#endif
diff --git a/drivers/scsi/bfa/include/cs/bfa_trc.h b/drivers/scsi/bfa/include/cs/bfa_trc.h
new file mode 100644
index 000000000000..3e743928c74c
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_trc.h
@@ -0,0 +1,176 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_TRC_H__
18#define __BFA_TRC_H__
19
20#include <bfa_os_inc.h>
21
22#ifndef BFA_TRC_MAX
23#define BFA_TRC_MAX (4 * 1024)
24#endif
25
26#ifndef BFA_TRC_TS
27#define BFA_TRC_TS(_trcm) ((_trcm)->ticks ++)
28#endif
29
30struct bfa_trc_s {
31#ifdef __BIGENDIAN
32 u16 fileno;
33 u16 line;
34#else
35 u16 line;
36 u16 fileno;
37#endif
38 u32 timestamp;
39 union {
40 struct {
41 u32 rsvd;
42 u32 u32;
43 } u32;
44 u64 u64;
45 } data;
46};
47
48
49struct bfa_trc_mod_s {
50 u32 head;
51 u32 tail;
52 u32 ntrc;
53 u32 stopped;
54 u32 ticks;
55 u32 rsvd[3];
56 struct bfa_trc_s trc[BFA_TRC_MAX];
57};
58
59
60enum {
61 BFA_TRC_FW = 1, /* firmware modules */
62 BFA_TRC_HAL = 2, /* BFA modules */
63 BFA_TRC_FCS = 3, /* BFA FCS modules */
64 BFA_TRC_LDRV = 4, /* Linux driver modules */
65 BFA_TRC_SDRV = 5, /* Solaris driver modules */
66 BFA_TRC_VDRV = 6, /* vmware driver modules */
67 BFA_TRC_WDRV = 7, /* windows driver modules */
68 BFA_TRC_AEN = 8, /* AEN module */
69 BFA_TRC_BIOS = 9, /* bios driver modules */
70 BFA_TRC_EFI = 10, /* EFI driver modules */
71 BNA_TRC_WDRV = 11, /* BNA windows driver modules */
72 BNA_TRC_VDRV = 12, /* BNA vmware driver modules */
73 BNA_TRC_SDRV = 13, /* BNA Solaris driver modules */
74 BNA_TRC_LDRV = 14, /* BNA Linux driver modules */
75 BNA_TRC_HAL = 15, /* BNA modules */
76 BFA_TRC_CNA = 16, /* Common modules */
77 BNA_TRC_IMDRV = 17 /* BNA windows intermediate driver modules */
78};
79#define BFA_TRC_MOD_SH 10
80#define BFA_TRC_MOD(__mod) ((BFA_TRC_ ## __mod) << BFA_TRC_MOD_SH)
81
82/**
83 * Define a new tracing file (module). Module should match one defined above.
84 */
85#define BFA_TRC_FILE(__mod, __submod) \
86 static int __trc_fileno = ((BFA_TRC_ ## __mod ## _ ## __submod) | \
87 BFA_TRC_MOD(__mod))
88
89
90#define bfa_trc32(_trcp, _data) \
91 __bfa_trc((_trcp)->trcmod, __trc_fileno, __LINE__, (u32)_data)
92
93
94#ifndef BFA_BOOT_BUILD
95#define bfa_trc(_trcp, _data) \
96 __bfa_trc((_trcp)->trcmod, __trc_fileno, __LINE__, (u64)_data)
97#else
98void bfa_boot_trc(struct bfa_trc_mod_s *trcmod, u16 fileno,
99 u16 line, u32 data);
100#define bfa_trc(_trcp, _data) \
101 bfa_boot_trc((_trcp)->trcmod, __trc_fileno, __LINE__, (u32)_data)
102#endif
103
104
105static inline void
106bfa_trc_init(struct bfa_trc_mod_s *trcm)
107{
108 trcm->head = trcm->tail = trcm->stopped = 0;
109 trcm->ntrc = BFA_TRC_MAX;
110}
111
112
113static inline void
114bfa_trc_stop(struct bfa_trc_mod_s *trcm)
115{
116 trcm->stopped = 1;
117}
118
119#ifdef FWTRC
120extern void dc_flush(void *data);
121#else
122#define dc_flush(data)
123#endif
124
125
126static inline void
127__bfa_trc(struct bfa_trc_mod_s *trcm, int fileno, int line, u64 data)
128{
129 int tail = trcm->tail;
130 struct bfa_trc_s *trc = &trcm->trc[tail];
131
132 if (trcm->stopped)
133 return;
134
135 trc->fileno = (u16) fileno;
136 trc->line = (u16) line;
137 trc->data.u64 = data;
138 trc->timestamp = BFA_TRC_TS(trcm);
139 dc_flush(trc);
140
141 trcm->tail = (trcm->tail + 1) & (BFA_TRC_MAX - 1);
142 if (trcm->tail == trcm->head)
143 trcm->head = (trcm->head + 1) & (BFA_TRC_MAX - 1);
144 dc_flush(trcm);
145}
146
147
148static inline void
149__bfa_trc32(struct bfa_trc_mod_s *trcm, int fileno, int line, u32 data)
150{
151 int tail = trcm->tail;
152 struct bfa_trc_s *trc = &trcm->trc[tail];
153
154 if (trcm->stopped)
155 return;
156
157 trc->fileno = (u16) fileno;
158 trc->line = (u16) line;
159 trc->data.u32.u32 = data;
160 trc->timestamp = BFA_TRC_TS(trcm);
161 dc_flush(trc);
162
163 trcm->tail = (trcm->tail + 1) & (BFA_TRC_MAX - 1);
164 if (trcm->tail == trcm->head)
165 trcm->head = (trcm->head + 1) & (BFA_TRC_MAX - 1);
166 dc_flush(trcm);
167}
168
169#ifndef BFA_PERF_BUILD
170#define bfa_trc_fp(_trcp, _data) bfa_trc(_trcp, _data)
171#else
172#define bfa_trc_fp(_trcp, _data)
173#endif
174
175#endif /* __BFA_TRC_H__ */
176
diff --git a/drivers/scsi/bfa/include/cs/bfa_wc.h b/drivers/scsi/bfa/include/cs/bfa_wc.h
new file mode 100644
index 000000000000..0460bd4fc7c4
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_wc.h
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_wc.h Generic wait counter.
20 */
21
22#ifndef __BFA_WC_H__
23#define __BFA_WC_H__
24
25typedef void (*bfa_wc_resume_t) (void *cbarg);
26
27struct bfa_wc_s {
28 bfa_wc_resume_t wc_resume;
29 void *wc_cbarg;
30 int wc_count;
31};
32
33static inline void
34bfa_wc_up(struct bfa_wc_s *wc)
35{
36 wc->wc_count++;
37}
38
39static inline void
40bfa_wc_down(struct bfa_wc_s *wc)
41{
42 wc->wc_count--;
43 if (wc->wc_count == 0)
44 wc->wc_resume(wc->wc_cbarg);
45}
46
47/**
48 * Initialize a waiting counter.
49 */
50static inline void
51bfa_wc_init(struct bfa_wc_s *wc, bfa_wc_resume_t wc_resume, void *wc_cbarg)
52{
53 wc->wc_resume = wc_resume;
54 wc->wc_cbarg = wc_cbarg;
55 wc->wc_count = 0;
56 bfa_wc_up(wc);
57}
58
59/**
60 * Wait for counter to reach zero
61 */
62static inline void
63bfa_wc_wait(struct bfa_wc_s *wc)
64{
65 bfa_wc_down(wc);
66}
67
68#endif
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_adapter.h b/drivers/scsi/bfa/include/defs/bfa_defs_adapter.h
new file mode 100644
index 000000000000..8c208fc8e329
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_adapter.h
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_ADAPTER_H__
18#define __BFA_DEFS_ADAPTER_H__
19
20#include <protocol/types.h>
21#include <defs/bfa_defs_version.h>
22#include <defs/bfa_defs_mfg.h>
23
24/**
25 * BFA adapter level attributes.
26 */
27enum {
28 BFA_ADAPTER_SERIAL_NUM_LEN = STRSZ(BFA_MFG_SERIALNUM_SIZE),
29 /*
30 *!< adapter serial num length
31 */
32 BFA_ADAPTER_MODEL_NAME_LEN = 16, /* model name length */
33 BFA_ADAPTER_MODEL_DESCR_LEN = 128, /* model description length */
34 BFA_ADAPTER_MFG_NAME_LEN = 8, /* manufacturer name length */
35 BFA_ADAPTER_SYM_NAME_LEN = 64, /* adapter symbolic name length */
36 BFA_ADAPTER_OS_TYPE_LEN = 64, /* adapter os type length */
37};
38
39struct bfa_adapter_attr_s {
40 char manufacturer[BFA_ADAPTER_MFG_NAME_LEN];
41 char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
42 u32 rsvd1;
43 char model[BFA_ADAPTER_MODEL_NAME_LEN];
44 char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN];
45 wwn_t pwwn;
46 char node_symname[FC_SYMNAME_MAX];
47 char hw_ver[BFA_VERSION_LEN];
48 char fw_ver[BFA_VERSION_LEN];
49 char optrom_ver[BFA_VERSION_LEN];
50 char os_type[BFA_ADAPTER_OS_TYPE_LEN];
51 struct bfa_mfg_vpd_s vpd;
52 struct mac_s mac;
53
54 u8 nports;
55 u8 max_speed;
56 u8 prototype;
57 char asic_rev;
58
59 u8 pcie_gen;
60 u8 pcie_lanes_orig;
61 u8 pcie_lanes;
62 u8 cna_capable;
63};
64
65/**
66 * BFA adapter level events
67 * Arguments below are in BFAL context from Mgmt
68 * BFA_PORT_AEN_ADD: [in]: None [out]: serial_num, pwwn, nports
69 * BFA_PORT_AEN_REMOVE: [in]: pwwn [out]: serial_num, pwwn, nports
70 */
71enum bfa_adapter_aen_event {
72 BFA_ADAPTER_AEN_ADD = 1, /* New Adapter found event */
73 BFA_ADAPTER_AEN_REMOVE = 2, /* Adapter removed event */
74};
75
76struct bfa_adapter_aen_data_s {
77 char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
78 u32 nports; /* Number of NPorts */
79 wwn_t pwwn; /* WWN of one of its physical port */
80};
81
82#endif /* __BFA_DEFS_ADAPTER_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_aen.h b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h
new file mode 100644
index 000000000000..4c81a613db3d
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h
@@ -0,0 +1,73 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_AEN_H__
19#define __BFA_DEFS_AEN_H__
20
21#include <defs/bfa_defs_types.h>
22#include <defs/bfa_defs_ioc.h>
23#include <defs/bfa_defs_adapter.h>
24#include <defs/bfa_defs_port.h>
25#include <defs/bfa_defs_lport.h>
26#include <defs/bfa_defs_rport.h>
27#include <defs/bfa_defs_itnim.h>
28#include <defs/bfa_defs_tin.h>
29#include <defs/bfa_defs_ipfc.h>
30#include <defs/bfa_defs_audit.h>
31#include <defs/bfa_defs_ethport.h>
32
33enum bfa_aen_category {
34 BFA_AEN_CAT_ADAPTER = 1,
35 BFA_AEN_CAT_PORT = 2,
36 BFA_AEN_CAT_LPORT = 3,
37 BFA_AEN_CAT_RPORT = 4,
38 BFA_AEN_CAT_ITNIM = 5,
39 BFA_AEN_CAT_TIN = 6,
40 BFA_AEN_CAT_IPFC = 7,
41 BFA_AEN_CAT_AUDIT = 8,
42 BFA_AEN_CAT_IOC = 9,
43 BFA_AEN_CAT_ETHPORT = 10,
44 BFA_AEN_MAX_CAT = 10
45};
46
47#pragma pack(1)
48union bfa_aen_data_u {
49 struct bfa_adapter_aen_data_s adapter;
50 struct bfa_port_aen_data_s port;
51 struct bfa_lport_aen_data_s lport;
52 struct bfa_rport_aen_data_s rport;
53 struct bfa_itnim_aen_data_s itnim;
54 struct bfa_audit_aen_data_s audit;
55 struct bfa_ioc_aen_data_s ioc;
56 struct bfa_ethport_aen_data_s ethport;
57};
58
59struct bfa_aen_entry_s {
60 enum bfa_aen_category aen_category;
61 int aen_type;
62 union bfa_aen_data_u aen_data;
63 struct bfa_timeval_s aen_tv;
64 s32 seq_num;
65 s32 bfad_num;
66 s32 rsvd[1];
67};
68
69#pragma pack()
70
71#define bfa_aen_event_t int
72
73#endif /* __BFA_DEFS_AEN_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_audit.h b/drivers/scsi/bfa/include/defs/bfa_defs_audit.h
new file mode 100644
index 000000000000..8e3a962bf20c
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_audit.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_AUDIT_H__
19#define __BFA_DEFS_AUDIT_H__
20
21#include <bfa_os_inc.h>
22
23/**
24 * BFA audit events
25 */
26enum bfa_audit_aen_event {
27 BFA_AUDIT_AEN_AUTH_ENABLE = 1,
28 BFA_AUDIT_AEN_AUTH_DISABLE = 2,
29};
30
31/**
32 * audit event data
33 */
34struct bfa_audit_aen_data_s {
35 wwn_t pwwn;
36};
37
38#endif /* __BFA_DEFS_AUDIT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_auth.h b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
new file mode 100644
index 000000000000..dd19c83aba58
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_AUTH_H__
18#define __BFA_DEFS_AUTH_H__
19
20#include <defs/bfa_defs_types.h>
21
22#define PUBLIC_KEY 15409
23#define PRIVATE_KEY 19009
24#define KEY_LEN 32399
25#define BFA_AUTH_SECRET_STRING_LEN 256
26#define BFA_AUTH_FAIL_TIMEOUT 0xFF
27
28/**
29 * Authentication status
30 */
31enum bfa_auth_status {
32 BFA_AUTH_STATUS_NONE = 0, /* no authentication */
33 BFA_AUTH_UNINIT = 1, /* state - uninit */
34 BFA_AUTH_NEG_SEND = 2, /* state - negotiate send */
35 BFA_AUTH_CHAL_WAIT = 3, /* state - challenge wait */
36 BFA_AUTH_NEG_RETRY = 4, /* state - negotiate retry */
37 BFA_AUTH_REPLY_SEND = 5, /* state - reply send */
38 BFA_AUTH_STATUS_WAIT = 6, /* state - status wait */
39 BFA_AUTH_SUCCESS = 7, /* state - success */
40 BFA_AUTH_FAILED = 8, /* state - failed */
41 BFA_AUTH_STATUS_UNKNOWN = 9, /* authentication status unknown */
42};
43
44struct auth_proto_stats_s {
45 u32 auth_rjts;
46 u32 auth_negs;
47 u32 auth_dones;
48
49 u32 dhchap_challenges;
50 u32 dhchap_replies;
51 u32 dhchap_successes;
52};
53
54/**
55 * Authentication related statistics
56 */
57struct bfa_auth_stats_s {
58 u32 auth_failures; /* authentication failures */
59 u32 auth_successes; /* authentication successes*/
60 struct auth_proto_stats_s auth_rx_stats; /* Rx protocol stats */
61 struct auth_proto_stats_s auth_tx_stats; /* Tx protocol stats */
62};
63
64/**
65 * Authentication hash function algorithms
66 */
67enum bfa_auth_algo {
68 BFA_AUTH_ALGO_MD5 = 1, /* Message-Digest algorithm 5 */
69 BFA_AUTH_ALGO_SHA1 = 2, /* Secure Hash Algorithm 1 */
70 BFA_AUTH_ALGO_MS = 3, /* MD5, then SHA-1 */
71 BFA_AUTH_ALGO_SM = 4, /* SHA-1, then MD5 */
72};
73
74/**
75 * DH Groups
76 *
77 * Current value could be combination of one or more of the following values
78 */
79enum bfa_auth_group {
80 BFA_AUTH_GROUP_DHNULL = 0, /* DH NULL (value == 0) */
81 BFA_AUTH_GROUP_DH768 = 1, /* DH group 768 (value == 1) */
82 BFA_AUTH_GROUP_DH1024 = 2, /* DH group 1024 (value == 2) */
83 BFA_AUTH_GROUP_DH1280 = 4, /* DH group 1280 (value == 3) */
84 BFA_AUTH_GROUP_DH1536 = 8, /* DH group 1536 (value == 4) */
85
86 BFA_AUTH_GROUP_ALL = 256 /* Use default DH group order
87 * 0, 1, 2, 3, 4 */
88};
89
90/**
91 * Authentication secret sources
92 */
93enum bfa_auth_secretsource {
94 BFA_AUTH_SECSRC_LOCAL = 1, /* locally configured */
95 BFA_AUTH_SECSRC_RADIUS = 2, /* use radius server */
96 BFA_AUTH_SECSRC_TACACS = 3, /* TACACS server */
97};
98
99/**
100 * Authentication attributes
101 */
102struct bfa_auth_attr_s {
103 enum bfa_auth_status status;
104 enum bfa_auth_algo algo;
105 enum bfa_auth_group dh_grp;
106 u16 rjt_code;
107 u16 rjt_code_exp;
108 u8 secret_set;
109 u8 resv[7];
110};
111
112#endif /* __BFA_DEFS_AUTH_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_boot.h b/drivers/scsi/bfa/include/defs/bfa_defs_boot.h
new file mode 100644
index 000000000000..6f4aa5283545
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_boot.h
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_BOOT_H__
19#define __BFA_DEFS_BOOT_H__
20
21#include <protocol/types.h>
22#include <defs/bfa_defs_types.h>
23#include <defs/bfa_defs_pport.h>
24
25enum {
26 BFA_BOOT_BOOTLUN_MAX = 4, /* maximum boot lun per IOC */
27};
28
29#define BOOT_CFG_REV1 1
30
31/**
32 * Boot options setting. Boot options setting determines from where
33 * to get the boot lun information
34 */
35enum bfa_boot_bootopt {
36 BFA_BOOT_AUTO_DISCOVER = 0, /* Boot from blun provided by fabric */
37 BFA_BOOT_STORED_BLUN = 1, /* Boot from bluns stored in flash */
38 BFA_BOOT_FIRST_LUN = 2, /* Boot from first discovered blun */
39};
40
41/**
42 * Boot lun information.
43 */
44struct bfa_boot_bootlun_s {
45 wwn_t pwwn; /* port wwn of target */
46 lun_t lun; /* 64-bit lun */
47};
48
49/**
50 * BOOT boot configuraton
51 */
52struct bfa_boot_cfg_s {
53 u8 version;
54 u8 rsvd1;
55 u16 chksum;
56
57 u8 enable; /* enable/disable SAN boot */
58 u8 speed; /* boot speed settings */
59 u8 topology; /* boot topology setting */
60 u8 bootopt; /* bfa_boot_bootopt_t */
61
62 u32 nbluns; /* number of boot luns */
63
64 u32 rsvd2;
65
66 struct bfa_boot_bootlun_s blun[BFA_BOOT_BOOTLUN_MAX];
67 struct bfa_boot_bootlun_s blun_disc[BFA_BOOT_BOOTLUN_MAX];
68};
69
70
71#endif /* __BFA_DEFS_BOOT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_cee.h b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h
new file mode 100644
index 000000000000..520a22f52dd1
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h
@@ -0,0 +1,159 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * bfa_defs_cee.h Interface declarations between host based
7 * BFAL and DCBX/LLDP module in Firmware
8 *
9 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License (GPL) Version 2 as
13 * published by the Free Software Foundation
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 */
20#ifndef __BFA_DEFS_CEE_H__
21#define __BFA_DEFS_CEE_H__
22
23#include <defs/bfa_defs_types.h>
24#include <defs/bfa_defs_pport.h>
25#include <protocol/types.h>
26
27#pragma pack(1)
28
29#define BFA_CEE_LLDP_MAX_STRING_LEN (128)
30
31
32/* FIXME: this is coming from the protocol spec. Can the host & apps share the
33 protocol .h files ?
34 */
35#define BFA_CEE_LLDP_SYS_CAP_OTHER 0x0001
36#define BFA_CEE_LLDP_SYS_CAP_REPEATER 0x0002
37#define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE 0x0004
38#define BFA_CEE_LLDP_SYS_CAP_WLAN_AP 0x0008
39#define BFA_CEE_LLDP_SYS_CAP_ROUTER 0x0010
40#define BFA_CEE_LLDP_SYS_CAP_TELEPHONE 0x0020
41#define BFA_CEE_LLDP_SYS_CAP_DOCSIS_CD 0x0040
42#define BFA_CEE_LLDP_SYS_CAP_STATION 0x0080
43#define BFA_CEE_LLDP_SYS_CAP_CVLAN 0x0100
44#define BFA_CEE_LLDP_SYS_CAP_SVLAN 0x0200
45#define BFA_CEE_LLDP_SYS_CAP_TPMR 0x0400
46
47
48/* LLDP string type */
49struct bfa_cee_lldp_str_s {
50 u8 sub_type;
51 u8 len;
52 u8 rsvd[2];
53 u8 value[BFA_CEE_LLDP_MAX_STRING_LEN];
54};
55
56
57/* LLDP paramters */
58struct bfa_cee_lldp_cfg_s {
59 struct bfa_cee_lldp_str_s chassis_id;
60 struct bfa_cee_lldp_str_s port_id;
61 struct bfa_cee_lldp_str_s port_desc;
62 struct bfa_cee_lldp_str_s sys_name;
63 struct bfa_cee_lldp_str_s sys_desc;
64 struct bfa_cee_lldp_str_s mgmt_addr;
65 u16 time_to_interval;
66 u16 enabled_system_cap;
67};
68
69enum bfa_cee_dcbx_version_e {
70 DCBX_PROTOCOL_PRECEE = 1,
71 DCBX_PROTOCOL_CEE = 2,
72};
73
74enum bfa_cee_lls_e {
75 CEE_LLS_DOWN_NO_TLV = 0, /* LLS is down because the TLV not sent by
76 * the peer */
77 CEE_LLS_DOWN = 1, /* LLS is down as advertised by the peer */
78 CEE_LLS_UP = 2,
79};
80
81/* CEE/DCBX parameters */
82struct bfa_cee_dcbx_cfg_s {
83 u8 pgid[8];
84 u8 pg_percentage[8];
85 u8 pfc_enabled; /* bitmap of priorties with PFC enabled */
86 u8 fcoe_user_priority; /* bitmap of priorities used for FcoE
87 * traffic */
88 u8 dcbx_version; /* operating version:CEE or preCEE */
89 u8 lls_fcoe; /* FCoE Logical Link Status */
90 u8 lls_lan; /* LAN Logical Link Status */
91 u8 rsvd[3];
92};
93
94/* CEE status */
95/* Making this to tri-state for the benefit of port list command */
96enum bfa_cee_status_e {
97 CEE_PHY_DOWN = 0,
98 CEE_PHY_UP = 1,
99 CEE_UP = 2,
100};
101
102/* CEE Query */
103struct bfa_cee_attr_s {
104 u8 cee_status;
105 u8 error_reason;
106 struct bfa_cee_lldp_cfg_s lldp_remote;
107 struct bfa_cee_dcbx_cfg_s dcbx_remote;
108 mac_t src_mac;
109 u8 link_speed;
110 u8 filler[3];
111};
112
113
114
115
116/* LLDP/DCBX/CEE Statistics */
117
118struct bfa_cee_lldp_stats_s {
119 u32 frames_transmitted;
120 u32 frames_aged_out;
121 u32 frames_discarded;
122 u32 frames_in_error;
123 u32 frames_rcvd;
124 u32 tlvs_discarded;
125 u32 tlvs_unrecognized;
126};
127
128struct bfa_cee_dcbx_stats_s {
129 u32 subtlvs_unrecognized;
130 u32 negotiation_failed;
131 u32 remote_cfg_changed;
132 u32 tlvs_received;
133 u32 tlvs_invalid;
134 u32 seqno;
135 u32 ackno;
136 u32 recvd_seqno;
137 u32 recvd_ackno;
138};
139
140struct bfa_cee_cfg_stats_s {
141 u32 cee_status_down;
142 u32 cee_status_up;
143 u32 cee_hw_cfg_changed;
144 u32 recvd_invalid_cfg;
145};
146
147
148struct bfa_cee_stats_s {
149 struct bfa_cee_lldp_stats_s lldp_stats;
150 struct bfa_cee_dcbx_stats_s dcbx_stats;
151 struct bfa_cee_cfg_stats_s cfg_stats;
152};
153
154#pragma pack()
155
156
157#endif /* __BFA_DEFS_CEE_H__ */
158
159
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_driver.h b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
new file mode 100644
index 000000000000..57049805762b
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_DRIVER_H__
19#define __BFA_DEFS_DRIVER_H__
20
21/**
22 * Driver statistics
23 */
24 u16 tm_io_abort;
25 u16 tm_io_abort_comp;
26 u16 tm_lun_reset;
27 u16 tm_lun_reset_comp;
28 u16 tm_target_reset;
29 u16 tm_bus_reset;
30 u16 ioc_restart; /* IOC restart count */
31 u16 io_pending; /* outstanding io count per-IOC */
32 u64 control_req;
33 u64 input_req;
34 u64 output_req;
35 u64 input_words;
36 u64 output_words;
37} bfa_driver_stats_t;
38
39
40#endif /* __BFA_DEFS_DRIVER_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h
new file mode 100644
index 000000000000..79f9b3e146f7
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h
@@ -0,0 +1,98 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_ETHPORT_H__
19#define __BFA_DEFS_ETHPORT_H__
20
21#include <defs/bfa_defs_status.h>
22#include <protocol/types.h>
23#include <cna/pstats/phyport_defs.h>
24#include <cna/pstats/ethport_defs.h>
25
26struct bna_tx_info_s {
27 u32 miniport_state;
28 u32 adapter_state;
29 u64 tx_count;
30 u64 tx_wi;
31 u64 tx_sg;
32 u64 tx_tcp_chksum;
33 u64 tx_udp_chksum;
34 u64 tx_ip_chksum;
35 u64 tx_lsov1;
36 u64 tx_lsov2;
37 u64 tx_max_sg_len ;
38};
39
40struct bna_rx_queue_info_s {
41 u16 q_id ;
42 u16 buf_size ;
43 u16 buf_count ;
44 u16 rsvd ;
45 u64 rx_count ;
46 u64 rx_dropped ;
47 u64 rx_unsupported ;
48 u64 rx_internal_err ;
49 u64 rss_count ;
50 u64 vlan_count ;
51 u64 rx_tcp_chksum ;
52 u64 rx_udp_chksum ;
53 u64 rx_ip_chksum ;
54 u64 rx_hds ;
55};
56
57struct bna_rx_q_set_s {
58 u16 q_set_type;
59 u32 miniport_state;
60 u32 adapter_state;
61 struct bna_rx_queue_info_s rx_queue[2];
62};
63
64struct bna_port_stats_s {
65 struct bna_tx_info_s tx_stats;
66 u16 qset_count ;
67 struct bna_rx_q_set_s rx_qset[8];
68};
69
70struct bfa_ethport_stats_s {
71 struct bna_stats_txf txf_stats[1];
72 struct bna_stats_rxf rxf_stats[1];
73 struct bnad_drv_stats drv_stats;
74};
75
76/**
77 * Ethernet port events
78 * Arguments below are in BFAL context from Mgmt
79 * BFA_PORT_AEN_ETH_LINKUP: [in]: mac [out]: mac
80 * BFA_PORT_AEN_ETH_LINKDOWN: [in]: mac [out]: mac
81 * BFA_PORT_AEN_ETH_ENABLE: [in]: mac [out]: mac
82 * BFA_PORT_AEN_ETH_DISABLE: [in]: mac [out]: mac
83 *
84 */
85enum bfa_ethport_aen_event {
86 BFA_ETHPORT_AEN_LINKUP = 1, /* Base Port Ethernet link up event */
87 BFA_ETHPORT_AEN_LINKDOWN = 2, /* Base Port Ethernet link down event */
88 BFA_ETHPORT_AEN_ENABLE = 3, /* Base Port Ethernet link enable event */
89 BFA_ETHPORT_AEN_DISABLE = 4, /* Base Port Ethernet link disable
90 * event */
91};
92
93struct bfa_ethport_aen_data_s {
94 mac_t mac; /* MAC address of the physical port */
95};
96
97
98#endif /* __BFA_DEFS_ETHPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_fcpim.h b/drivers/scsi/bfa/include/defs/bfa_defs_fcpim.h
new file mode 100644
index 000000000000..c08f4f5026ac
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_fcpim.h
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_FCPIM_H__
18#define __BFA_DEFS_FCPIM_H__
19
20struct bfa_fcpim_stats_s {
21 u32 total_ios; /* Total IO count */
22 u32 qresumes; /* IO waiting for CQ space */
23 u32 no_iotags; /* NO IO contexts */
24 u32 io_aborts; /* IO abort requests */
25 u32 no_tskims; /* NO task management contexts */
26 u32 iocomp_ok; /* IO completions with OK status */
27 u32 iocomp_underrun; /* IO underrun (good) */
28 u32 iocomp_overrun; /* IO overrun (good) */
29 u32 iocomp_aborted; /* Aborted IO requests */
30 u32 iocomp_timedout; /* IO timeouts */
31 u32 iocom_nexus_abort; /* IO selection timeouts */
32 u32 iocom_proto_err; /* IO protocol errors */
33 u32 iocom_dif_err; /* IO SBC-3 protection errors */
34 u32 iocom_tm_abort; /* IO aborted by TM requests */
35 u32 iocom_sqer_needed; /* IO retry for SQ error
36 *recovery */
37 u32 iocom_res_free; /* Delayed freeing of IO resources */
38 u32 iocomp_scsierr; /* IO with non-good SCSI status */
39 u32 iocom_hostabrts; /* Host IO abort requests */
40 u32 iocom_utags; /* IO comp with unknown tags */
41 u32 io_cleanups; /* IO implicitly aborted */
42 u32 io_tmaborts; /* IO aborted due to TM commands */
43 u32 rsvd;
44};
45#endif /*__BFA_DEFS_FCPIM_H__*/
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h
new file mode 100644
index 000000000000..9ccf53bef65a
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_IM_COMMON_H__
19#define __BFA_DEFS_IM_COMMON_H__
20
21#define BFA_ADAPTER_NAME_LEN 256
22#define BFA_ADAPTER_GUID_LEN 256
23#define RESERVED_VLAN_NAME L"PORT VLAN"
24#define PASSTHRU_VLAN_NAME L"PASSTHRU VLAN"
25
26 u64 tx_pkt_cnt;
27 u64 rx_pkt_cnt;
28 u32 duration;
29 u8 status;
30} bfa_im_stats_t, *pbfa_im_stats_t;
31
32#endif /* __BFA_DEFS_IM_COMMON_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h
new file mode 100644
index 000000000000..a486a7eb81d6
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_IM_TEAM_H__
19#define __BFA_DEFS_IM_TEAM_H__
20
21#include <protocol/types.h>
22
23#define BFA_TEAM_MAX_PORTS 8
24#define BFA_TEAM_NAME_LEN 256
25#define BFA_MAX_NUM_TEAMS 16
26#define BFA_TEAM_INVALID_DELAY -1
27
28 BFA_LACP_RATE_SLOW = 1,
29 BFA_LACP_RATE_FAST
30} bfa_im_lacp_rate_t;
31
32 BFA_TEAM_MODE_FAIL_OVER = 1,
33 BFA_TEAM_MODE_FAIL_BACK,
34 BFA_TEAM_MODE_LACP,
35 BFA_TEAM_MODE_NONE
36} bfa_im_team_mode_t;
37
38 BFA_XMIT_POLICY_L2 = 1,
39 BFA_XMIT_POLICY_L3_L4
40} bfa_im_xmit_policy_t;
41
42 bfa_im_team_mode_t team_mode;
43 bfa_im_lacp_rate_t lacp_rate;
44 bfa_im_xmit_policy_t xmit_policy;
45 int delay;
46 wchar_t primary[BFA_ADAPTER_NAME_LEN];
47 wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN];
48 mac_t mac;
49 u16 num_ports;
50 u16 num_vlans;
51 u16 vlan_list[BFA_MAX_VLANS_PER_PORT];
52 wchar_t team_guid_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_GUID_LEN];
53 wchar_t ioc_name_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_NAME_LEN];
54} bfa_im_team_attr_t;
55
56 wchar_t team_name[BFA_TEAM_NAME_LEN];
57 bfa_im_xmit_policy_t xmit_policy;
58 int delay;
59 wchar_t primary[BFA_ADAPTER_NAME_LEN];
60 wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN];
61} bfa_im_team_edit_t, *pbfa_im_team_edit_t;
62
63 wchar_t team_name[BFA_TEAM_NAME_LEN];
64 bfa_im_team_mode_t team_mode;
65 mac_t mac;
66} bfa_im_team_info_t;
67
68 bfa_im_team_info_t team_info[BFA_MAX_NUM_TEAMS];
69 u16 num_teams;
70} bfa_im_team_list_t, *pbfa_im_team_list_t;
71
72#endif /* __BFA_DEFS_IM_TEAM_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
new file mode 100644
index 000000000000..b1d532da3a9d
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
@@ -0,0 +1,152 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_IOC_H__
19#define __BFA_DEFS_IOC_H__
20
21#include <protocol/types.h>
22#include <defs/bfa_defs_types.h>
23#include <defs/bfa_defs_version.h>
24#include <defs/bfa_defs_adapter.h>
25#include <defs/bfa_defs_pm.h>
26
27enum {
28 BFA_IOC_DRIVER_LEN = 16,
29 BFA_IOC_CHIP_REV_LEN = 8,
30};
31
32/**
33 * Driver and firmware versions.
34 */
35struct bfa_ioc_driver_attr_s {
36 char driver[BFA_IOC_DRIVER_LEN]; /* driver name */
37 char driver_ver[BFA_VERSION_LEN]; /* driver version */
38 char fw_ver[BFA_VERSION_LEN]; /* firmware version*/
39 char bios_ver[BFA_VERSION_LEN]; /* bios version */
40 char efi_ver[BFA_VERSION_LEN]; /* EFI version */
41 char ob_ver[BFA_VERSION_LEN]; /* openboot version*/
42};
43
44/**
45 * IOC PCI device attributes
46 */
47struct bfa_ioc_pci_attr_s {
48 u16 vendor_id; /* PCI vendor ID */
49 u16 device_id; /* PCI device ID */
50 u16 ssid; /* subsystem ID */
51 u16 ssvid; /* subsystem vendor ID */
52 u32 pcifn; /* PCI device function */
53 u32 rsvd; /* padding */
54 u8 chip_rev[BFA_IOC_CHIP_REV_LEN]; /* chip revision */
55};
56
57/**
58 * IOC states
59 */
60enum bfa_ioc_state {
61 BFA_IOC_RESET = 1, /* IOC is in reset state */
62 BFA_IOC_SEMWAIT = 2, /* Waiting for IOC hardware semaphore */
63 BFA_IOC_HWINIT = 3, /* IOC hardware is being initialized */
64 BFA_IOC_GETATTR = 4, /* IOC is being configured */
65 BFA_IOC_OPERATIONAL = 5, /* IOC is operational */
66 BFA_IOC_INITFAIL = 6, /* IOC hardware failure */
67 BFA_IOC_HBFAIL = 7, /* IOC heart-beat failure */
68 BFA_IOC_DISABLING = 8, /* IOC is being disabled */
69 BFA_IOC_DISABLED = 9, /* IOC is disabled */
70 BFA_IOC_FWMISMATCH = 10, /* IOC firmware different from drivers */
71};
72
73/**
74 * IOC firmware stats
75 */
76struct bfa_fw_ioc_stats_s {
77 u32 hb_count;
78 u32 cfg_reqs;
79 u32 enable_reqs;
80 u32 disable_reqs;
81 u32 stats_reqs;
82 u32 clrstats_reqs;
83 u32 unknown_reqs;
84 u32 ic_reqs; /* interrupt coalesce reqs */
85};
86
87/**
88 * IOC driver stats
89 */
90struct bfa_ioc_drv_stats_s {
91 u32 ioc_isrs;
92 u32 ioc_enables;
93 u32 ioc_disables;
94 u32 ioc_hbfails;
95 u32 ioc_boots;
96 u32 stats_tmos;
97 u32 hb_count;
98 u32 disable_reqs;
99 u32 enable_reqs;
100 u32 disable_replies;
101 u32 enable_replies;
102};
103
104/**
105 * IOC statistics
106 */
107struct bfa_ioc_stats_s {
108 struct bfa_ioc_drv_stats_s drv_stats; /* driver IOC stats */
109 struct bfa_fw_ioc_stats_s fw_stats; /* firmware IOC stats */
110};
111
112
113enum bfa_ioc_type_e {
114 BFA_IOC_TYPE_FC = 1,
115 BFA_IOC_TYPE_FCoE = 2,
116 BFA_IOC_TYPE_LL = 3,
117};
118
119/**
120 * IOC attributes returned in queries
121 */
122struct bfa_ioc_attr_s {
123 enum bfa_ioc_type_e ioc_type;
124 enum bfa_ioc_state state; /* IOC state */
125 struct bfa_adapter_attr_s adapter_attr; /* HBA attributes */
126 struct bfa_ioc_driver_attr_s driver_attr; /* driver attr */
127 struct bfa_ioc_pci_attr_s pci_attr;
128 u8 port_id; /* port number */
129};
130
131/**
132 * BFA IOC level events
133 */
134enum bfa_ioc_aen_event {
135 BFA_IOC_AEN_HBGOOD = 1, /* Heart Beat restore event */
136 BFA_IOC_AEN_HBFAIL = 2, /* Heart Beat failure event */
137 BFA_IOC_AEN_ENABLE = 3, /* IOC enabled event */
138 BFA_IOC_AEN_DISABLE = 4, /* IOC disabled event */
139 BFA_IOC_AEN_FWMISMATCH = 5, /* IOC firmware mismatch */
140};
141
142/**
143 * BFA IOC level event data, now just a place holder
144 */
145struct bfa_ioc_aen_data_s {
146 enum bfa_ioc_type_e ioc_type;
147 wwn_t pwwn;
148 mac_t mac;
149};
150
151#endif /* __BFA_DEFS_IOC_H__ */
152
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
new file mode 100644
index 000000000000..d76bcbd9820f
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
@@ -0,0 +1,310 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_IOCFC_H__
19#define __BFA_DEFS_IOCFC_H__
20
21#include <protocol/types.h>
22#include <defs/bfa_defs_types.h>
23#include <defs/bfa_defs_version.h>
24#include <defs/bfa_defs_adapter.h>
25#include <defs/bfa_defs_pm.h>
26
27#define BFA_IOCFC_INTR_DELAY 1125
28#define BFA_IOCFC_INTR_LATENCY 225
29
30/**
31 * Interrupt coalescing configuration.
32 */
33struct bfa_iocfc_intr_attr_s {
34 bfa_boolean_t coalesce; /* enable/disable coalescing */
35 u16 latency; /* latency in microseconds */
36 u16 delay; /* delay in microseconds */
37};
38
39/**
40 * IOC firmware configuraton
41 */
42struct bfa_iocfc_fwcfg_s {
43 u16 num_fabrics; /* number of fabrics */
44 u16 num_lports; /* number of local lports */
45 u16 num_rports; /* number of remote ports */
46 u16 num_ioim_reqs; /* number of IO reqs */
47 u16 num_tskim_reqs; /* task management requests */
48 u16 num_iotm_reqs; /* number of TM IO reqs */
49 u16 num_tsktm_reqs; /* TM task management requests*/
50 u16 num_fcxp_reqs; /* unassisted FC exchanges */
51 u16 num_uf_bufs; /* unsolicited recv buffers */
52 u8 num_cqs;
53 u8 rsvd;
54};
55
56struct bfa_iocfc_drvcfg_s {
57 u16 num_reqq_elems; /* number of req queue elements */
58 u16 num_rspq_elems; /* number of rsp queue elements */
59 u16 num_sgpgs; /* number of total SG pages */
60 u16 num_sboot_tgts; /* number of SAN boot targets */
61 u16 num_sboot_luns; /* number of SAN boot luns */
62 u16 ioc_recover; /* IOC recovery mode */
63 u16 min_cfg; /* minimum configuration */
64 u16 path_tov; /* device path timeout */
65 bfa_boolean_t delay_comp; /* delay completion of
66 failed inflight IOs */
67 u32 rsvd;
68};
69/**
70 * IOC configuration
71 */
72struct bfa_iocfc_cfg_s {
73 struct bfa_iocfc_fwcfg_s fwcfg; /* firmware side config */
74 struct bfa_iocfc_drvcfg_s drvcfg; /* driver side config */
75};
76
77/**
78 * IOC firmware IO stats
79 */
80struct bfa_fw_io_stats_s {
81 u32 host_abort; /* IO aborted by host driver*/
82 u32 host_cleanup; /* IO clean up by host driver */
83
84 u32 fw_io_timeout; /* IOs timedout */
85 u32 fw_frm_parse; /* frame parsed by f/w */
86 u32 fw_frm_data; /* fcp_data frame parsed by f/w */
87 u32 fw_frm_rsp; /* fcp_rsp frame parsed by f/w */
88 u32 fw_frm_xfer_rdy; /* xfer_rdy frame parsed by f/w */
89 u32 fw_frm_bls_acc; /* BLS ACC frame parsed by f/w */
90 u32 fw_frm_tgt_abort; /* target ABTS parsed by f/w */
91 u32 fw_frm_unknown; /* unknown parsed by f/w */
92 u32 fw_data_dma; /* f/w DMA'ed the data frame */
93 u32 fw_frm_drop; /* f/w drop the frame */
94
95 u32 rec_timeout; /* FW rec timed out */
96 u32 error_rec; /* FW sending rec on
97 * an error condition*/
98 u32 wait_for_si; /* FW wait for SI */
99 u32 rec_rsp_inval; /* REC rsp invalid */
100 u32 seqr_io_abort; /* target does not know cmd so abort */
101 u32 seqr_io_retry; /* SEQR failed so retry IO */
102
103 u32 itn_cisc_upd_rsp; /* ITN cisc updated on fcp_rsp */
104 u32 itn_cisc_upd_data; /* ITN cisc updated on fcp_data */
105 u32 itn_cisc_upd_xfer_rdy; /* ITN cisc updated on fcp_data */
106
107 u32 fcp_data_lost; /* fcp data lost */
108
109 u32 ro_set_in_xfer_rdy; /* Target set RO in Xfer_rdy frame */
110 u32 xfer_rdy_ooo_err; /* Out of order Xfer_rdy received */
111 u32 xfer_rdy_unknown_err; /* unknown error in xfer_rdy frame */
112
113 u32 io_abort_timeout; /* ABTS timedout */
114 u32 sler_initiated; /* SLER initiated */
115
116 u32 unexp_fcp_rsp; /* fcp response in wrong state */
117
118 u32 fcp_rsp_under_run; /* fcp rsp IO underrun */
119 u32 fcp_rsp_under_run_wr; /* fcp rsp IO underrun for write */
120 u32 fcp_rsp_under_run_err; /* fcp rsp IO underrun error */
121 u32 fcp_rsp_resid_inval; /* invalid residue */
122 u32 fcp_rsp_over_run; /* fcp rsp IO overrun */
123 u32 fcp_rsp_over_run_err; /* fcp rsp IO overrun error */
124 u32 fcp_rsp_proto_err; /* protocol error in fcp rsp */
125 u32 fcp_rsp_sense_err; /* error in sense info in fcp rsp */
126 u32 fcp_conf_req; /* FCP conf requested */
127
128 u32 tgt_aborted_io; /* target initiated abort */
129
130 u32 ioh_edtov_timeout_event;/* IOH edtov timer popped */
131 u32 ioh_fcp_rsp_excp_event; /* IOH FCP_RSP exception */
132 u32 ioh_fcp_conf_event; /* IOH FCP_CONF */
133 u32 ioh_mult_frm_rsp_event; /* IOH multi_frame FCP_RSP */
134 u32 ioh_hit_class2_event; /* IOH hit class2 */
135 u32 ioh_miss_other_event; /* IOH miss other */
136 u32 ioh_seq_cnt_err_event; /* IOH seq cnt error */
137 u32 ioh_len_err_event; /* IOH len error - fcp_dl !=
138 * bytes xfered */
139 u32 ioh_seq_len_err_event; /* IOH seq len error */
140 u32 ioh_data_oor_event; /* Data out of range */
141 u32 ioh_ro_ooo_event; /* Relative offset out of range */
142 u32 ioh_cpu_owned_event; /* IOH hit -iost owned by f/w */
143 u32 ioh_unexp_frame_event; /* unexpected frame recieved
144 * count */
145 u32 ioh_err_int; /* IOH error int during data-phase
146 * for scsi write
147 */
148};
149
150/**
151 * IOC port firmware stats
152 */
153
154struct bfa_fw_port_fpg_stats_s {
155 u32 intr_evt;
156 u32 intr;
157 u32 intr_excess;
158 u32 intr_cause0;
159 u32 intr_other;
160 u32 intr_other_ign;
161 u32 sig_lost;
162 u32 sig_regained;
163 u32 sync_lost;
164 u32 sync_to;
165 u32 sync_regained;
166 u32 div2_overflow;
167 u32 div2_underflow;
168 u32 efifo_overflow;
169 u32 efifo_underflow;
170 u32 idle_rx;
171 u32 lrr_rx;
172 u32 lr_rx;
173 u32 ols_rx;
174 u32 nos_rx;
175 u32 lip_rx;
176 u32 arbf0_rx;
177 u32 mrk_rx;
178 u32 const_mrk_rx;
179 u32 prim_unknown;
180 u32 rsvd;
181};
182
183
184struct bfa_fw_port_lksm_stats_s {
185 u32 hwsm_success; /* hwsm state machine success */
186 u32 hwsm_fails; /* hwsm fails */
187 u32 hwsm_wdtov; /* hwsm timed out */
188 u32 swsm_success; /* swsm success */
189 u32 swsm_fails; /* swsm fails */
190 u32 swsm_wdtov; /* swsm timed out */
191 u32 busybufs; /* link init failed due to busybuf */
192 u32 buf_waits; /* bufwait state entries */
193 u32 link_fails; /* link failures */
194 u32 psp_errors; /* primitive sequence protocol errors */
195 u32 lr_unexp; /* No. of times LR rx-ed unexpectedly */
196 u32 lrr_unexp; /* No. of times LRR rx-ed unexpectedly */
197 u32 lr_tx; /* No. of times LR tx started */
198 u32 lrr_tx; /* No. of times LRR tx started */
199 u32 ols_tx; /* No. of times OLS tx started */
200 u32 nos_tx; /* No. of times NOS tx started */
201};
202
203
204struct bfa_fw_port_snsm_stats_s {
205 u32 hwsm_success; /* Successful hwsm terminations */
206 u32 hwsm_fails; /* hwsm fail count */
207 u32 hwsm_wdtov; /* hwsm timed out */
208 u32 swsm_success; /* swsm success */
209 u32 swsm_wdtov; /* swsm timed out */
210 u32 error_resets; /* error resets initiated by upsm */
211 u32 sync_lost; /* Sync loss count */
212 u32 sig_lost; /* Signal loss count */
213};
214
215
216struct bfa_fw_port_physm_stats_s {
217 u32 module_inserts; /* Module insert count */
218 u32 module_xtracts; /* Module extracts count */
219 u32 module_invalids; /* Invalid module inserted count */
220 u32 module_read_ign; /* Module validation status ignored */
221 u32 laser_faults; /* Laser fault count */
222 u32 rsvd;
223};
224
225
226struct bfa_fw_fip_stats_s {
227 u32 disc_req; /* Discovery solicit requests */
228 u32 disc_rsp; /* Discovery solicit response */
229 u32 disc_err; /* Discovery advt. parse errors */
230 u32 disc_unsol; /* Discovery unsolicited */
231 u32 disc_timeouts; /* Discovery timeouts */
232 u32 linksvc_unsupp; /* Unsupported link service req */
233 u32 linksvc_err; /* Parse error in link service req */
234 u32 logo_req; /* Number of FIP logos received */
235 u32 clrvlink_req; /* Clear virtual link req */
236 u32 op_unsupp; /* Unsupported FIP operation */
237 u32 untagged; /* Untagged frames (ignored) */
238 u32 rsvd;
239};
240
241
242struct bfa_fw_lps_stats_s {
243 u32 mac_invalids; /* Invalid mac assigned */
244 u32 rsvd;
245};
246
247
248struct bfa_fw_fcoe_stats_s {
249 u32 cee_linkups; /* CEE link up count */
250 u32 cee_linkdns; /* CEE link down count */
251 u32 fip_linkups; /* FIP link up count */
252 u32 fip_linkdns; /* FIP link up count */
253 u32 fip_fails; /* FIP fail count */
254 u32 mac_invalids; /* Invalid mac assigned */
255};
256
257/**
258 * IOC firmware FCoE port stats
259 */
260struct bfa_fw_fcoe_port_stats_s {
261 struct bfa_fw_fcoe_stats_s fcoe_stats;
262 struct bfa_fw_fip_stats_s fip_stats;
263};
264
265/**
266 * IOC firmware FC port stats
267 */
268struct bfa_fw_fc_port_stats_s {
269 struct bfa_fw_port_fpg_stats_s fpg_stats;
270 struct bfa_fw_port_physm_stats_s physm_stats;
271 struct bfa_fw_port_snsm_stats_s snsm_stats;
272 struct bfa_fw_port_lksm_stats_s lksm_stats;
273};
274
275/**
276 * IOC firmware FC port stats
277 */
278union bfa_fw_port_stats_s {
279 struct bfa_fw_fc_port_stats_s fc_stats;
280 struct bfa_fw_fcoe_port_stats_s fcoe_stats;
281};
282
283/**
284 * IOC firmware stats
285 */
286struct bfa_fw_stats_s {
287 struct bfa_fw_ioc_stats_s ioc_stats;
288 struct bfa_fw_io_stats_s io_stats;
289 union bfa_fw_port_stats_s port_stats;
290};
291
292/**
293 * IOC statistics
294 */
295struct bfa_iocfc_stats_s {
296 struct bfa_fw_stats_s fw_stats; /* firmware IOC stats */
297};
298
299/**
300 * IOC attributes returned in queries
301 */
302struct bfa_iocfc_attr_s {
303 struct bfa_iocfc_cfg_s config; /* IOCFC config */
304 struct bfa_iocfc_intr_attr_s intr_attr; /* interrupt attr */
305};
306
307#define BFA_IOCFC_PATHTOV_MAX 60
308#define BFA_IOCFC_QDEPTH_MAX 2000
309
310#endif /* __BFA_DEFS_IOC_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ipfc.h b/drivers/scsi/bfa/include/defs/bfa_defs_ipfc.h
new file mode 100644
index 000000000000..7cb63ea98f38
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_ipfc.h
@@ -0,0 +1,70 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_IPFC_H__
18#define __BFA_DEFS_IPFC_H__
19
20#include <bfa_os_inc.h>
21#include <protocol/types.h>
22#include <defs/bfa_defs_types.h>
23
24/**
25 * FCS ip remote port states
26 */
27enum bfa_iprp_state {
28 BFA_IPRP_UNINIT = 0, /* PORT is not yet initialized */
29 BFA_IPRP_ONLINE = 1, /* process login is complete */
30 BFA_IPRP_OFFLINE = 2, /* iprp is offline */
31};
32
33/**
34 * FCS remote port statistics
35 */
36struct bfa_iprp_stats_s {
37 u32 offlines;
38 u32 onlines;
39 u32 rscns;
40 u32 plogis;
41 u32 logos;
42 u32 plogi_timeouts;
43 u32 plogi_rejects;
44};
45
46/**
47 * FCS iprp attribute returned in queries
48 */
49struct bfa_iprp_attr_s {
50 enum bfa_iprp_state state;
51};
52
53struct bfa_ipfc_stats_s {
54 u32 arp_sent;
55 u32 arp_recv;
56 u32 arp_reply_sent;
57 u32 arp_reply_recv;
58 u32 farp_sent;
59 u32 farp_recv;
60 u32 farp_reply_sent;
61 u32 farp_reply_recv;
62 u32 farp_reject_sent;
63 u32 farp_reject_recv;
64};
65
66struct bfa_ipfc_attr_s {
67 bfa_boolean_t enabled;
68};
69
70#endif /* __BFA_DEFS_IPFC_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_itnim.h b/drivers/scsi/bfa/include/defs/bfa_defs_itnim.h
new file mode 100644
index 000000000000..2ec769903d24
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_itnim.h
@@ -0,0 +1,126 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_ITNIM_H__
18#define __BFA_DEFS_ITNIM_H__
19
20#include <bfa_os_inc.h>
21#include <protocol/types.h>
22
23/**
24 * FCS itnim states
25 */
26enum bfa_itnim_state {
27 BFA_ITNIM_OFFLINE = 0, /* offline */
28 BFA_ITNIM_PRLI_SEND = 1, /* prli send */
29 BFA_ITNIM_PRLI_SENT = 2, /* prli sent */
30 BFA_ITNIM_PRLI_RETRY = 3, /* prli retry */
31 BFA_ITNIM_HCB_ONLINE = 4, /* online callback */
32 BFA_ITNIM_ONLINE = 5, /* online */
33 BFA_ITNIM_HCB_OFFLINE = 6, /* offline callback */
34 BFA_ITNIM_INITIATIOR = 7, /* initiator */
35};
36
37struct bfa_itnim_hal_stats_s {
38 u32 onlines; /* ITN nexus onlines (PRLI done) */
39 u32 offlines; /* ITN Nexus offlines */
40 u32 creates; /* ITN create requests */
41 u32 deletes; /* ITN delete requests */
42 u32 create_comps; /* ITN create completions */
43 u32 delete_comps; /* ITN delete completions */
44 u32 sler_events; /* SLER (sequence level error
45 * recovery) events */
46 u32 ioc_disabled; /* Num IOC disables */
47 u32 cleanup_comps; /* ITN cleanup completions */
48 u32 tm_cmnds; /* task management(TM) cmnds sent */
49 u32 tm_fw_rsps; /* TM cmds firmware responses */
50 u32 tm_success; /* TM successes */
51 u32 tm_failures; /* TM failures */
52 u32 tm_io_comps; /* TM IO completions */
53 u32 tm_qresumes; /* TM queue resumes (after waiting
54 * for resources)
55 */
56 u32 tm_iocdowns; /* TM cmnds affected by IOC down */
57 u32 tm_cleanups; /* TM cleanups */
58 u32 tm_cleanup_comps;
59 /* TM cleanup completions */
60 u32 ios; /* IO requests */
61 u32 io_comps; /* IO completions */
62 u64 input_reqs; /* INPUT requests */
63 u64 output_reqs; /* OUTPUT requests */
64};
65
66/**
67 * FCS remote port statistics
68 */
69struct bfa_itnim_stats_s {
70 u32 onlines; /* num rport online */
71 u32 offlines; /* num rport offline */
72 u32 prli_sent; /* num prli sent out */
73 u32 fcxp_alloc_wait;/* num fcxp alloc waits */
74 u32 prli_rsp_err; /* num prli rsp errors */
75 u32 prli_rsp_acc; /* num prli rsp accepts */
76 u32 initiator; /* rport is an initiator */
77 u32 prli_rsp_parse_err; /* prli rsp parsing errors */
78 u32 prli_rsp_rjt; /* num prli rsp rejects */
79 u32 timeout; /* num timeouts detected */
80 u32 sler; /* num sler notification from BFA */
81 u32 rsvd;
82 struct bfa_itnim_hal_stats_s hal_stats;
83};
84
85/**
86 * FCS itnim attributes returned in queries
87 */
88struct bfa_itnim_attr_s {
89 enum bfa_itnim_state state; /* FCS itnim state */
90 u8 retry; /* data retransmision support */
91 u8 task_retry_id; /* task retry ident support */
92 u8 rec_support; /* REC supported */
93 u8 conf_comp; /* confirmed completion supp */
94};
95
96/**
97 * BFA ITNIM events.
98 * Arguments below are in BFAL context from Mgmt
99 * BFA_ITNIM_AEN_NEW: [in]: None [out]: vf_id, lpwwn
100 * BFA_ITNIM_AEN_DELETE: [in]: vf_id, lpwwn, rpwwn (0 = all fcp4 targets),
101 * [out]: vf_id, ppwwn, lpwwn, rpwwn
102 * BFA_ITNIM_AEN_ONLINE: [in]: vf_id, lpwwn, rpwwn (0 = all fcp4 targets),
103 * [out]: vf_id, ppwwn, lpwwn, rpwwn
104 * BFA_ITNIM_AEN_OFFLINE: [in]: vf_id, lpwwn, rpwwn (0 = all fcp4 targets),
105 * [out]: vf_id, ppwwn, lpwwn, rpwwn
106 * BFA_ITNIM_AEN_DISCONNECT:[in]: vf_id, lpwwn, rpwwn (0 = all fcp4 targets),
107 * [out]: vf_id, ppwwn, lpwwn, rpwwn
108 */
109enum bfa_itnim_aen_event {
110 BFA_ITNIM_AEN_ONLINE = 1, /* Target online */
111 BFA_ITNIM_AEN_OFFLINE = 2, /* Target offline */
112 BFA_ITNIM_AEN_DISCONNECT = 3, /* Target disconnected */
113};
114
115/**
116 * BFA ITNIM event data structure.
117 */
118struct bfa_itnim_aen_data_s {
119 u16 vf_id; /* vf_id of the IT nexus */
120 u16 rsvd[3];
121 wwn_t ppwwn; /* WWN of its physical port */
122 wwn_t lpwwn; /* WWN of logical port */
123 wwn_t rpwwn; /* WWN of remote(target) port */
124};
125
126#endif /* __BFA_DEFS_ITNIM_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_led.h b/drivers/scsi/bfa/include/defs/bfa_defs_led.h
new file mode 100644
index 000000000000..62039273264e
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_led.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_LED_H__
19#define __BFA_DEFS_LED_H__
20
21#define BFA_LED_MAX_NUM 3
22
23enum bfa_led_op {
24 BFA_LED_OFF = 0,
25 BFA_LED_ON = 1,
26 BFA_LED_FLICK = 2,
27 BFA_LED_BLINK = 3,
28};
29
30enum bfa_led_color {
31 BFA_LED_GREEN = 0,
32 BFA_LED_AMBER = 1,
33};
34
35#endif /* __BFA_DEFS_LED_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_lport.h b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h
new file mode 100644
index 000000000000..7359f82aacfc
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_LPORT_H__
19#define __BFA_DEFS_LPORT_H__
20
21#include <defs/bfa_defs_types.h>
22#include <defs/bfa_defs_port.h>
23
24/**
25 * BFA AEN logical port events.
26 * Arguments below are in BFAL context from Mgmt
27 * BFA_LPORT_AEN_NEW: [in]: None [out]: vf_id, ppwwn, lpwwn, roles
28 * BFA_LPORT_AEN_DELETE: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
29 * BFA_LPORT_AEN_ONLINE: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
30 * BFA_LPORT_AEN_OFFLINE: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
31 * BFA_LPORT_AEN_DISCONNECT:[in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
32 * BFA_LPORT_AEN_NEW_PROP: [in]: None [out]: vf_id, ppwwn. lpwwn, roles
33 * BFA_LPORT_AEN_DELETE_PROP: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
34 * BFA_LPORT_AEN_NEW_STANDARD: [in]: None [out]: vf_id, ppwwn. lpwwn, roles
35 * BFA_LPORT_AEN_DELETE_STANDARD: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
36 * BFA_LPORT_AEN_NPIV_DUP_WWN: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
37 * BFA_LPORT_AEN_NPIV_FABRIC_MAX: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
38 * BFA_LPORT_AEN_NPIV_UNKNOWN: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
39 */
40enum bfa_lport_aen_event {
41 BFA_LPORT_AEN_NEW = 1, /* LPort created event */
42 BFA_LPORT_AEN_DELETE = 2, /* LPort deleted event */
43 BFA_LPORT_AEN_ONLINE = 3, /* LPort online event */
44 BFA_LPORT_AEN_OFFLINE = 4, /* LPort offline event */
45 BFA_LPORT_AEN_DISCONNECT = 5, /* LPort disconnect event */
46 BFA_LPORT_AEN_NEW_PROP = 6, /* VPort created event */
47 BFA_LPORT_AEN_DELETE_PROP = 7, /* VPort deleted event */
48 BFA_LPORT_AEN_NEW_STANDARD = 8, /* VPort created event */
49 BFA_LPORT_AEN_DELETE_STANDARD = 9, /* VPort deleted event */
50 BFA_LPORT_AEN_NPIV_DUP_WWN = 10, /* VPort configured with
51 * duplicate WWN event
52 */
53 BFA_LPORT_AEN_NPIV_FABRIC_MAX = 11, /* Max NPIV in fabric/fport */
54 BFA_LPORT_AEN_NPIV_UNKNOWN = 12, /* Unknown NPIV Error code event */
55};
56
57/**
58 * BFA AEN event data structure
59 */
60struct bfa_lport_aen_data_s {
61 u16 vf_id; /* vf_id of this logical port */
62 u16 rsvd;
63 enum bfa_port_role roles; /* Logical port mode,IM/TM/IP etc */
64 wwn_t ppwwn; /* WWN of its physical port */
65 wwn_t lpwwn; /* WWN of this logical port */
66};
67
68#endif /* __BFA_DEFS_LPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
new file mode 100644
index 000000000000..13fd4ab6aae2
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_MFG_H__
18#define __BFA_DEFS_MFG_H__
19
20#include <bfa_os_inc.h>
21
22/**
23 * Manufacturing block version
24 */
25#define BFA_MFG_VERSION 1
26
27/**
28 * Manufacturing block format
29 */
30#define BFA_MFG_SERIALNUM_SIZE 11
31#define BFA_MFG_PARTNUM_SIZE 14
32#define BFA_MFG_SUPPLIER_ID_SIZE 10
33#define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20
34#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20
35#define BFA_MFG_SUPPLIER_REVISION_SIZE 4
36#define STRSZ(_n) (((_n) + 4) & ~3)
37
38/**
39 * VPD data length
40 */
41#define BFA_MFG_VPD_LEN 256
42
43/**
44 * All numerical fields are in big-endian format.
45 */
46struct bfa_mfg_vpd_s {
47 u8 version; /* vpd data version */
48 u8 vpd_sig[3]; /* characters 'V', 'P', 'D' */
49 u8 chksum; /* u8 checksum */
50 u8 vendor; /* vendor */
51 u8 len; /* vpd data length excluding header */
52 u8 rsv;
53 u8 data[BFA_MFG_VPD_LEN]; /* vpd data */
54};
55
56#pragma pack(1)
57
58#endif /* __BFA_DEFS_MFG_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pci.h b/drivers/scsi/bfa/include/defs/bfa_defs_pci.h
new file mode 100644
index 000000000000..c9b83321694b
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_pci.h
@@ -0,0 +1,41 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_PCI_H__
19#define __BFA_DEFS_PCI_H__
20
21/**
22 * PCI device and vendor ID information
23 */
24enum {
25 BFA_PCI_VENDOR_ID_BROCADE = 0x1657,
26 BFA_PCI_DEVICE_ID_FC_8G2P = 0x13,
27 BFA_PCI_DEVICE_ID_FC_8G1P = 0x17,
28 BFA_PCI_DEVICE_ID_CT = 0x14,
29};
30
31/**
32 * PCI sub-system device and vendor ID information
33 */
34enum {
35 BFA_PCI_FCOE_SSDEVICE_ID = 0x14,
36};
37
38#define BFA_PCI_ACCESS_RANGES 1 /* Maximum number of device address ranges
39 * mapped through different BAR(s). */
40
41#endif /* __BFA_DEFS_PCI_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pm.h b/drivers/scsi/bfa/include/defs/bfa_defs_pm.h
new file mode 100644
index 000000000000..e8d6d959006e
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_pm.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_PM_H__
19#define __BFA_DEFS_PM_H__
20
21#include <bfa_os_inc.h>
22
23/**
24 * BFA power management device states
25 */
26enum bfa_pm_ds {
27 BFA_PM_DS_D0 = 0, /* full power mode */
28 BFA_PM_DS_D1 = 1, /* power save state 1 */
29 BFA_PM_DS_D2 = 2, /* power save state 2 */
30 BFA_PM_DS_D3 = 3, /* power off state */
31};
32
33#endif /* __BFA_DEFS_PM_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pom.h b/drivers/scsi/bfa/include/defs/bfa_defs_pom.h
new file mode 100644
index 000000000000..d9fa278472b7
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_pom.h
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_POM_H__
18#define __BFA_DEFS_POM_H__
19
20#include <bfa_os_inc.h>
21#include <defs/bfa_defs_types.h>
22
23/**
24 * POM health status levels for each attributes.
25 */
26enum bfa_pom_entry_health {
27 BFA_POM_HEALTH_NOINFO = 1, /* no information */
28 BFA_POM_HEALTH_NORMAL = 2, /* health is normal */
29 BFA_POM_HEALTH_WARNING = 3, /* warning level */
30 BFA_POM_HEALTH_ALARM = 4, /* alarming level */
31};
32
33/**
34 * Reading of temperature/voltage/current/power
35 */
36struct bfa_pom_entry_s {
37 enum bfa_pom_entry_health health; /* POM entry health */
38 u32 curr_value; /* current value */
39 u32 thr_warn_high; /* threshold warning high */
40 u32 thr_warn_low; /* threshold warning low */
41 u32 thr_alarm_low; /* threshold alaram low */
42 u32 thr_alarm_high; /* threshold alarm high */
43};
44
45/**
46 * POM attributes
47 */
48struct bfa_pom_attr_s {
49 struct bfa_pom_entry_s temperature; /* centigrade */
50 struct bfa_pom_entry_s voltage; /* volts */
51 struct bfa_pom_entry_s curr; /* milli amps */
52 struct bfa_pom_entry_s txpower; /* micro watts */
53 struct bfa_pom_entry_s rxpower; /* micro watts */
54};
55
56#endif /* __BFA_DEFS_POM_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_port.h b/drivers/scsi/bfa/include/defs/bfa_defs_port.h
new file mode 100644
index 000000000000..de0696c81bc4
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_port.h
@@ -0,0 +1,245 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_PORT_H__
19#define __BFA_DEFS_PORT_H__
20
21#include <bfa_os_inc.h>
22#include <protocol/types.h>
23#include <defs/bfa_defs_pport.h>
24#include <defs/bfa_defs_ioc.h>
25
26#define BFA_FCS_FABRIC_IPADDR_SZ 16
27
28/**
29 * symbolic names for base port/virtual port
30 */
31#define BFA_SYMNAME_MAXLEN 128 /* vmware/windows uses 128 bytes */
32struct bfa_port_symname_s {
33 char symname[BFA_SYMNAME_MAXLEN];
34};
35
36/**
37* Roles of FCS port:
38 * - FCP IM and FCP TM roles cannot be enabled together for a FCS port
39 * - Create multiple ports if both IM and TM functions required.
40 * - Atleast one role must be specified.
41 */
42enum bfa_port_role {
43 BFA_PORT_ROLE_FCP_IM = 0x01, /* FCP initiator role */
44 BFA_PORT_ROLE_FCP_TM = 0x02, /* FCP target role */
45 BFA_PORT_ROLE_FCP_IPFC = 0x04, /* IP over FC role */
46 BFA_PORT_ROLE_FCP_MAX = BFA_PORT_ROLE_FCP_IPFC | BFA_PORT_ROLE_FCP_IM
47};
48
49/**
50 * FCS port configuration.
51 */
52struct bfa_port_cfg_s {
53 wwn_t pwwn; /* port wwn */
54 wwn_t nwwn; /* node wwn */
55 struct bfa_port_symname_s sym_name; /* vm port symbolic name */
56 enum bfa_port_role roles; /* FCS port roles */
57 u32 rsvd;
58 u8 tag[16]; /* opaque tag from application */
59};
60
61/**
62 * FCS port states
63 */
64enum bfa_port_state {
65 BFA_PORT_UNINIT = 0, /* PORT is not yet initialized */
66 BFA_PORT_FDISC = 1, /* FDISC is in progress */
67 BFA_PORT_ONLINE = 2, /* login to fabric is complete */
68 BFA_PORT_OFFLINE = 3, /* No login to fabric */
69};
70
71/**
72 * FCS port type. Required for VmWare.
73 */
74enum bfa_port_type {
75 BFA_PORT_TYPE_PHYSICAL = 0,
76 BFA_PORT_TYPE_VIRTUAL,
77};
78
79/**
80 * FCS port offline reason. Required for VmWare.
81 */
82enum bfa_port_offline_reason {
83 BFA_PORT_OFFLINE_UNKNOWN = 0,
84 BFA_PORT_OFFLINE_LINKDOWN,
85 BFA_PORT_OFFLINE_FAB_UNSUPPORTED, /* NPIV not supported by the
86 * fabric */
87 BFA_PORT_OFFLINE_FAB_NORESOURCES,
88 BFA_PORT_OFFLINE_FAB_LOGOUT,
89};
90
91/**
92 * FCS lport info. Required for VmWare.
93 */
94struct bfa_port_info_s {
95 u8 port_type; /* bfa_port_type_t : physical or
96 * virtual */
97 u8 port_state; /* one of bfa_port_state values */
98 u8 offline_reason; /* one of bfa_port_offline_reason_t
99 * values */
100 wwn_t port_wwn;
101 wwn_t node_wwn;
102
103 /*
104 * following 4 feilds are valid for Physical Ports only
105 */
106 u32 max_vports_supp; /* Max supported vports */
107 u32 num_vports_inuse; /* Num of in use vports */
108 u32 max_rports_supp; /* Max supported rports */
109 u32 num_rports_inuse; /* Num of doscovered rports */
110
111};
112
113/**
114 * FCS port statistics
115 */
116struct bfa_port_stats_s {
117 u32 ns_plogi_sent;
118 u32 ns_plogi_rsp_err;
119 u32 ns_plogi_acc_err;
120 u32 ns_plogi_accepts;
121 u32 ns_rejects; /* NS command rejects */
122 u32 ns_plogi_unknown_rsp;
123 u32 ns_plogi_alloc_wait;
124
125 u32 ns_retries; /* NS command retries */
126 u32 ns_timeouts; /* NS command timeouts */
127
128 u32 ns_rspnid_sent;
129 u32 ns_rspnid_accepts;
130 u32 ns_rspnid_rsp_err;
131 u32 ns_rspnid_rejects;
132 u32 ns_rspnid_alloc_wait;
133
134 u32 ns_rftid_sent;
135 u32 ns_rftid_accepts;
136 u32 ns_rftid_rsp_err;
137 u32 ns_rftid_rejects;
138 u32 ns_rftid_alloc_wait;
139
140 u32 ns_rffid_sent;
141 u32 ns_rffid_accepts;
142 u32 ns_rffid_rsp_err;
143 u32 ns_rffid_rejects;
144 u32 ns_rffid_alloc_wait;
145
146 u32 ns_gidft_sent;
147 u32 ns_gidft_accepts;
148 u32 ns_gidft_rsp_err;
149 u32 ns_gidft_rejects;
150 u32 ns_gidft_unknown_rsp;
151 u32 ns_gidft_alloc_wait;
152
153 /*
154 * Mgmt Server stats
155 */
156 u32 ms_retries; /* MS command retries */
157 u32 ms_timeouts; /* MS command timeouts */
158 u32 ms_plogi_sent;
159 u32 ms_plogi_rsp_err;
160 u32 ms_plogi_acc_err;
161 u32 ms_plogi_accepts;
162 u32 ms_rejects; /* NS command rejects */
163 u32 ms_plogi_unknown_rsp;
164 u32 ms_plogi_alloc_wait;
165
166 u32 num_rscn; /* Num of RSCN received */
167 u32 num_portid_rscn;/* Num portid format RSCN
168 * received */
169
170 u32 uf_recvs; /* unsolicited recv frames */
171 u32 uf_recv_drops; /* dropped received frames */
172
173 u32 rsvd; /* padding for 64 bit alignment */
174};
175
176/**
177 * BFA port attribute returned in queries
178 */
179struct bfa_port_attr_s {
180 enum bfa_port_state state; /* port state */
181 u32 pid; /* port ID */
182 struct bfa_port_cfg_s port_cfg; /* port configuration */
183 enum bfa_pport_type port_type; /* current topology */
184 u32 loopback; /* cable is externally looped back */
185 wwn_t fabric_name; /* attached switch's nwwn */
186 u8 fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /* attached
187 * fabric's ip addr */
188};
189
190/**
191 * BFA physical port Level events
192 * Arguments below are in BFAL context from Mgmt
193 * BFA_PORT_AEN_ONLINE: [in]: pwwn [out]: pwwn
194 * BFA_PORT_AEN_OFFLINE: [in]: pwwn [out]: pwwn
195 * BFA_PORT_AEN_RLIR: [in]: None [out]: pwwn, rlir_data, rlir_len
196 * BFA_PORT_AEN_SFP_INSERT: [in]: pwwn [out]: port_id, pwwn
197 * BFA_PORT_AEN_SFP_REMOVE: [in]: pwwn [out]: port_id, pwwn
198 * BFA_PORT_AEN_SFP_POM: [in]: pwwn [out]: level, port_id, pwwn
199 * BFA_PORT_AEN_ENABLE: [in]: pwwn [out]: pwwn
200 * BFA_PORT_AEN_DISABLE: [in]: pwwn [out]: pwwn
201 * BFA_PORT_AEN_AUTH_ON: [in]: pwwn [out]: pwwn
202 * BFA_PORT_AEN_AUTH_OFF: [in]: pwwn [out]: pwwn
203 * BFA_PORT_AEN_DISCONNECT: [in]: pwwn [out]: pwwn
204 * BFA_PORT_AEN_QOS_NEG: [in]: pwwn [out]: pwwn
205 * BFA_PORT_AEN_FABRIC_NAME_CHANGE: [in]: pwwn, [out]: pwwn, fwwn
206 *
207 */
208enum bfa_port_aen_event {
209 BFA_PORT_AEN_ONLINE = 1, /* Physical Port online event */
210 BFA_PORT_AEN_OFFLINE = 2, /* Physical Port offline event */
211 BFA_PORT_AEN_RLIR = 3, /* RLIR event, not supported */
212 BFA_PORT_AEN_SFP_INSERT = 4, /* SFP inserted event */
213 BFA_PORT_AEN_SFP_REMOVE = 5, /* SFP removed event */
214 BFA_PORT_AEN_SFP_POM = 6, /* SFP POM event */
215 BFA_PORT_AEN_ENABLE = 7, /* Physical Port enable event */
216 BFA_PORT_AEN_DISABLE = 8, /* Physical Port disable event */
217 BFA_PORT_AEN_AUTH_ON = 9, /* Physical Port auth success event */
218 BFA_PORT_AEN_AUTH_OFF = 10, /* Physical Port auth fail event */
219 BFA_PORT_AEN_DISCONNECT = 11, /* Physical Port disconnect event */
220 BFA_PORT_AEN_QOS_NEG = 12, /* Base Port QOS negotiation event */
221 BFA_PORT_AEN_FABRIC_NAME_CHANGE = 13, /* Fabric Name/WWN change
222 * event */
223 BFA_PORT_AEN_SFP_ACCESS_ERROR = 14, /* SFP read error event */
224 BFA_PORT_AEN_SFP_UNSUPPORT = 15, /* Unsupported SFP event */
225};
226
227enum bfa_port_aen_sfp_pom {
228 BFA_PORT_AEN_SFP_POM_GREEN = 1, /* Normal */
229 BFA_PORT_AEN_SFP_POM_AMBER = 2, /* Warning */
230 BFA_PORT_AEN_SFP_POM_RED = 3, /* Critical */
231 BFA_PORT_AEN_SFP_POM_MAX = BFA_PORT_AEN_SFP_POM_RED
232};
233
234struct bfa_port_aen_data_s {
235 enum bfa_ioc_type_e ioc_type;
236 wwn_t pwwn; /* WWN of the physical port */
237 wwn_t fwwn; /* WWN of the fabric port */
238 mac_t mac; /* MAC addres of the ethernet port,
239 * applicable to CNA port only */
240 int phy_port_num; /*! For SFP related events */
241 enum bfa_port_aen_sfp_pom level; /* Only transitions will
242 * be informed */
243};
244
245#endif /* __BFA_DEFS_PORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
new file mode 100644
index 000000000000..a000bc4e2d4a
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
@@ -0,0 +1,383 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_PPORT_H__
19#define __BFA_DEFS_PPORT_H__
20
21#include <bfa_os_inc.h>
22#include <protocol/fc.h>
23#include <defs/bfa_defs_types.h>
24#include <defs/bfa_defs_qos.h>
25#include <cna/pstats/phyport_defs.h>
26
27/* Modify char* port_stt[] in bfal_port.c if a new state was added */
28enum bfa_pport_states {
29 BFA_PPORT_ST_UNINIT = 1,
30 BFA_PPORT_ST_ENABLING_QWAIT = 2,
31 BFA_PPORT_ST_ENABLING = 3,
32 BFA_PPORT_ST_LINKDOWN = 4,
33 BFA_PPORT_ST_LINKUP = 5,
34 BFA_PPORT_ST_DISABLING_QWAIT = 6,
35 BFA_PPORT_ST_DISABLING = 7,
36 BFA_PPORT_ST_DISABLED = 8,
37 BFA_PPORT_ST_STOPPED = 9,
38 BFA_PPORT_ST_IOCDOWN = 10,
39 BFA_PPORT_ST_IOCDIS = 11,
40 BFA_PPORT_ST_FWMISMATCH = 12,
41 BFA_PPORT_ST_MAX_STATE,
42};
43
44/**
45 * Port speed settings. Each specific speed is a bit field. Use multiple
46 * bits to specify speeds to be selected for auto-negotiation.
47 */
48enum bfa_pport_speed {
49 BFA_PPORT_SPEED_UNKNOWN = 0,
50 BFA_PPORT_SPEED_1GBPS = 1,
51 BFA_PPORT_SPEED_2GBPS = 2,
52 BFA_PPORT_SPEED_4GBPS = 4,
53 BFA_PPORT_SPEED_8GBPS = 8,
54 BFA_PPORT_SPEED_10GBPS = 10,
55 BFA_PPORT_SPEED_AUTO =
56 (BFA_PPORT_SPEED_1GBPS | BFA_PPORT_SPEED_2GBPS |
57 BFA_PPORT_SPEED_4GBPS | BFA_PPORT_SPEED_8GBPS),
58};
59
60/**
61 * Port operational type (in sync with SNIA port type).
62 */
63enum bfa_pport_type {
64 BFA_PPORT_TYPE_UNKNOWN = 1, /* port type is unkown */
65 BFA_PPORT_TYPE_TRUNKED = 2, /* Trunked mode */
66 BFA_PPORT_TYPE_NPORT = 5, /* P2P with switched fabric */
67 BFA_PPORT_TYPE_NLPORT = 6, /* public loop */
68 BFA_PPORT_TYPE_LPORT = 20, /* private loop */
69 BFA_PPORT_TYPE_P2P = 21, /* P2P with no switched fabric */
70 BFA_PPORT_TYPE_VPORT = 22, /* NPIV - virtual port */
71};
72
73/**
74 * Port topology setting. A port's topology and fabric login status
75 * determine its operational type.
76 */
77enum bfa_pport_topology {
78 BFA_PPORT_TOPOLOGY_NONE = 0, /* No valid topology */
79 BFA_PPORT_TOPOLOGY_P2P = 1, /* P2P only */
80 BFA_PPORT_TOPOLOGY_LOOP = 2, /* LOOP topology */
81 BFA_PPORT_TOPOLOGY_AUTO = 3, /* auto topology selection */
82};
83
84/**
85 * Physical port loopback types.
86 */
87enum bfa_pport_opmode {
88 BFA_PPORT_OPMODE_NORMAL = 0x00, /* normal non-loopback mode */
89 BFA_PPORT_OPMODE_LB_INT = 0x01, /* internal loop back */
90 BFA_PPORT_OPMODE_LB_SLW = 0x02, /* serial link wrapback (serdes) */
91 BFA_PPORT_OPMODE_LB_EXT = 0x04, /* external loop back (serdes) */
92 BFA_PPORT_OPMODE_LB_CBL = 0x08, /* cabled loop back */
93 BFA_PPORT_OPMODE_LB_NLINT = 0x20, /* NL_Port internal loopback */
94};
95
96#define BFA_PPORT_OPMODE_LB_HARD(_mode) \
97 ((_mode == BFA_PPORT_OPMODE_LB_INT) || \
98 (_mode == BFA_PPORT_OPMODE_LB_SLW) || \
99 (_mode == BFA_PPORT_OPMODE_LB_EXT))
100
101/**
102 Port State (in sync with SNIA port state).
103 */
104enum bfa_pport_snia_state {
105 BFA_PPORT_STATE_UNKNOWN = 1, /* port is not initialized */
106 BFA_PPORT_STATE_ONLINE = 2, /* port is ONLINE */
107 BFA_PPORT_STATE_DISABLED = 3, /* port is disabled by user */
108 BFA_PPORT_STATE_BYPASSED = 4, /* port is bypassed (in LOOP) */
109 BFA_PPORT_STATE_DIAG = 5, /* port diagnostics is active */
110 BFA_PPORT_STATE_LINKDOWN = 6, /* link is down */
111 BFA_PPORT_STATE_LOOPBACK = 8, /* port is looped back */
112};
113
114/**
115 * Port link state
116 */
117enum bfa_pport_linkstate {
118 BFA_PPORT_LINKUP = 1, /* Physical port/Trunk link up */
119 BFA_PPORT_LINKDOWN = 2, /* Physical port/Trunk link down */
120 BFA_PPORT_TRUNK_LINKDOWN = 3, /* Trunk link down (new tmaster) */
121};
122
123/**
124 * Port link state event
125 */
126#define bfa_pport_event_t enum bfa_pport_linkstate
127
128/**
129 * Port link state reason code
130 */
131enum bfa_pport_linkstate_rsn {
132 BFA_PPORT_LINKSTATE_RSN_NONE = 0,
133 BFA_PPORT_LINKSTATE_RSN_DISABLED = 1,
134 BFA_PPORT_LINKSTATE_RSN_RX_NOS = 2,
135 BFA_PPORT_LINKSTATE_RSN_RX_OLS = 3,
136 BFA_PPORT_LINKSTATE_RSN_RX_LIP = 4,
137 BFA_PPORT_LINKSTATE_RSN_RX_LIPF7 = 5,
138 BFA_PPORT_LINKSTATE_RSN_SFP_REMOVED = 6,
139 BFA_PPORT_LINKSTATE_RSN_PORT_FAULT = 7,
140 BFA_PPORT_LINKSTATE_RSN_RX_LOS = 8,
141 BFA_PPORT_LINKSTATE_RSN_LOCAL_FAULT = 9,
142 BFA_PPORT_LINKSTATE_RSN_REMOTE_FAULT = 10,
143 BFA_PPORT_LINKSTATE_RSN_TIMEOUT = 11,
144
145
146
147 /* CEE related reason codes/errors */
148 CEE_LLDP_INFO_AGED_OUT = 20,
149 CEE_LLDP_SHUTDOWN_TLV_RCVD = 21,
150 CEE_PEER_NOT_ADVERTISE_DCBX = 22,
151 CEE_PEER_NOT_ADVERTISE_PG = 23,
152 CEE_PEER_NOT_ADVERTISE_PFC = 24,
153 CEE_PEER_NOT_ADVERTISE_FCOE = 25,
154 CEE_PG_NOT_COMPATIBLE = 26,
155 CEE_PFC_NOT_COMPATIBLE = 27,
156 CEE_FCOE_NOT_COMPATIBLE = 28,
157 CEE_BAD_PG_RCVD = 29,
158 CEE_BAD_BW_RCVD = 30,
159 CEE_BAD_PFC_RCVD = 31,
160 CEE_BAD_FCOE_PRI_RCVD = 32,
161 CEE_FCOE_PRI_PFC_OFF = 33,
162 CEE_DUP_CONTROL_TLV_RCVD = 34,
163 CEE_DUP_FEAT_TLV_RCVD = 35,
164 CEE_APPLY_NEW_CFG = 36, /* reason, not an error */
165 CEE_PROTOCOL_INIT = 37, /* reason, not an error */
166 CEE_PHY_LINK_DOWN = 38,
167 CEE_LLS_FCOE_ABSENT = 39,
168 CEE_LLS_FCOE_DOWN = 40
169};
170
171/**
172 * Default Target Rate Limiting Speed.
173 */
174#define BFA_PPORT_DEF_TRL_SPEED BFA_PPORT_SPEED_1GBPS
175
176/**
177 * Physical port configuration
178 */
179struct bfa_pport_cfg_s {
180 u8 topology; /* bfa_pport_topology */
181 u8 speed; /* enum bfa_pport_speed */
182 u8 trunked; /* trunked or not */
183 u8 qos_enabled; /* qos enabled or not */
184 u8 trunk_ports; /* bitmap of trunked ports */
185 u8 cfg_hardalpa; /* is hard alpa configured */
186 u16 maxfrsize; /* maximum frame size */
187 u8 hardalpa; /* configured hard alpa */
188 u8 rx_bbcredit; /* receive buffer credits */
189 u8 tx_bbcredit; /* transmit buffer credits */
190 u8 ratelimit; /* ratelimit enabled or not */
191 u8 trl_def_speed; /* ratelimit default speed */
192 u8 rsvd[3];
193 u16 path_tov; /* device path timeout */
194 u16 q_depth; /* SCSI Queue depth */
195};
196
197/**
198 * Port attribute values.
199 */
200struct bfa_pport_attr_s {
201 /*
202 * Static fields
203 */
204 wwn_t nwwn; /* node wwn */
205 wwn_t pwwn; /* port wwn */
206 enum fc_cos cos_supported; /* supported class of services */
207 u32 rsvd;
208 struct fc_symname_s port_symname; /* port symbolic name */
209 enum bfa_pport_speed speed_supported; /* supported speeds */
210 bfa_boolean_t pbind_enabled; /* Will be set if Persistent binding
211 * enabled. Relevant only in Windows
212 */
213
214 /*
215 * Configured values
216 */
217 struct bfa_pport_cfg_s pport_cfg; /* pport cfg */
218
219 /*
220 * Dynamic field - info from BFA
221 */
222 enum bfa_pport_states port_state; /* current port state */
223 enum bfa_pport_speed speed; /* current speed */
224 enum bfa_pport_topology topology; /* current topology */
225 bfa_boolean_t beacon; /* current beacon status */
226 bfa_boolean_t link_e2e_beacon;/* set if link beacon on */
227 bfa_boolean_t plog_enabled; /* set if portlog is enabled*/
228
229 /*
230 * Dynamic field - info from FCS
231 */
232 u32 pid; /* port ID */
233 enum bfa_pport_type port_type; /* current topology */
234 u32 loopback; /* external loopback */
235 u32 rsvd1;
236 u32 rsvd2; /* padding for 64 bit */
237};
238
239/**
240 * FC Port statistics.
241 */
242struct bfa_pport_fc_stats_s {
243 u64 secs_reset; /* seconds since stats is reset */
244 u64 tx_frames; /* transmitted frames */
245 u64 tx_words; /* transmitted words */
246 u64 rx_frames; /* received frames */
247 u64 rx_words; /* received words */
248 u64 lip_count; /* LIPs seen */
249 u64 nos_count; /* NOS count */
250 u64 error_frames; /* errored frames (sent?) */
251 u64 dropped_frames; /* dropped frames */
252 u64 link_failures; /* link failure count */
253 u64 loss_of_syncs; /* loss of sync count */
254 u64 loss_of_signals;/* loss of signal count */
255 u64 primseq_errs; /* primitive sequence protocol */
256 u64 bad_os_count; /* invalid ordered set */
257 u64 err_enc_out; /* Encoding error outside frame */
258 u64 invalid_crcs; /* frames received with invalid CRC*/
259 u64 undersized_frm; /* undersized frames */
260 u64 oversized_frm; /* oversized frames */
261 u64 bad_eof_frm; /* frames with bad EOF */
262 struct bfa_qos_stats_s qos_stats; /* QoS statistics */
263};
264
265/**
266 * Eth Port statistics.
267 */
268struct bfa_pport_eth_stats_s {
269 u64 secs_reset; /* seconds since stats is reset */
270 u64 frame_64; /* both rx and tx counter */
271 u64 frame_65_127; /* both rx and tx counter */
272 u64 frame_128_255; /* both rx and tx counter */
273 u64 frame_256_511; /* both rx and tx counter */
274 u64 frame_512_1023; /* both rx and tx counter */
275 u64 frame_1024_1518; /* both rx and tx counter */
276 u64 frame_1519_1522; /* both rx and tx counter */
277
278 u64 tx_bytes;
279 u64 tx_packets;
280 u64 tx_mcast_packets;
281 u64 tx_bcast_packets;
282 u64 tx_control_frame;
283 u64 tx_drop;
284 u64 tx_jabber;
285 u64 tx_fcs_error;
286 u64 tx_fragments;
287
288 u64 rx_bytes;
289 u64 rx_packets;
290 u64 rx_mcast_packets;
291 u64 rx_bcast_packets;
292 u64 rx_control_frames;
293 u64 rx_unknown_opcode;
294 u64 rx_drop;
295 u64 rx_jabber;
296 u64 rx_fcs_error;
297 u64 rx_alignment_error;
298 u64 rx_frame_length_error;
299 u64 rx_code_error;
300 u64 rx_fragments;
301
302 u64 rx_pause; /* BPC */
303 u64 rx_zero_pause; /* BPC Pause cancellation */
304 u64 tx_pause; /* BPC */
305 u64 tx_zero_pause; /* BPC Pause cancellation */
306 u64 rx_fcoe_pause; /* BPC */
307 u64 rx_fcoe_zero_pause; /* BPC Pause cancellation */
308 u64 tx_fcoe_pause; /* BPC */
309 u64 tx_fcoe_zero_pause; /* BPC Pause cancellation */
310};
311
312/**
313 * Port statistics.
314 */
315union bfa_pport_stats_u {
316 struct bfa_pport_fc_stats_s fc;
317 struct bfa_pport_eth_stats_s eth;
318};
319
320/**
321 * Port FCP mappings.
322 */
323struct bfa_pport_fcpmap_s {
324 char osdevname[256];
325 u32 bus;
326 u32 target;
327 u32 oslun;
328 u32 fcid;
329 wwn_t nwwn;
330 wwn_t pwwn;
331 u64 fcplun;
332 char luid[256];
333};
334
335/**
336 * Port RNID info.
337 */
338struct bfa_pport_rnid_s {
339 wwn_t wwn;
340 u32 unittype;
341 u32 portid;
342 u32 attached_nodes_num;
343 u16 ip_version;
344 u16 udp_port;
345 u8 ipaddr[16];
346 u16 rsvd;
347 u16 topologydiscoveryflags;
348};
349
350/**
351 * Link state information
352 */
353struct bfa_pport_link_s {
354 u8 linkstate; /* Link state bfa_pport_linkstate */
355 u8 linkstate_rsn; /* bfa_pport_linkstate_rsn_t */
356 u8 topology; /* P2P/LOOP bfa_pport_topology */
357 u8 speed; /* Link speed (1/2/4/8 G) */
358 u32 linkstate_opt; /* Linkstate optional data (debug) */
359 u8 trunked; /* Trunked or not (1 or 0) */
360 u8 resvd[3];
361 struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
362 struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */
363 union {
364 struct {
365 u8 tmaster;/* Trunk Master or
366 * not (1 or 0) */
367 u8 tlinks; /* Trunk links bitmap
368 * (linkup) */
369 u8 resv1; /* Reserved */
370 } trunk_info;
371
372 struct {
373 u8 myalpa; /* alpa claimed */
374 u8 login_req; /* Login required or
375 * not (1 or 0) */
376 u8 alpabm_val;/* alpa bitmap valid
377 * or not (1 or 0) */
378 struct fc_alpabm_s alpabm; /* alpa bitmap */
379 } loop_info;
380 } tl;
381};
382
383#endif /* __BFA_DEFS_PPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_qos.h b/drivers/scsi/bfa/include/defs/bfa_defs_qos.h
new file mode 100644
index 000000000000..aadbacd1d2d7
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_qos.h
@@ -0,0 +1,99 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_QOS_H__
19#define __BFA_DEFS_QOS_H__
20
21/**
22 * QoS states
23 */
24enum bfa_qos_state {
25 BFA_QOS_ONLINE = 1, /* QoS is online */
26 BFA_QOS_OFFLINE = 2, /* QoS is offline */
27};
28
29
30/**
31 * QoS Priority levels.
32 */
33enum bfa_qos_priority {
34 BFA_QOS_UNKNOWN = 0,
35 BFA_QOS_HIGH = 1, /* QoS Priority Level High */
36 BFA_QOS_MED = 2, /* QoS Priority Level Medium */
37 BFA_QOS_LOW = 3, /* QoS Priority Level Low */
38};
39
40
41/**
42 * QoS bandwidth allocation for each priority level
43 */
44enum bfa_qos_bw_alloc {
45 BFA_QOS_BW_HIGH = 60, /* bandwidth allocation for High */
46 BFA_QOS_BW_MED = 30, /* bandwidth allocation for Medium */
47 BFA_QOS_BW_LOW = 10, /* bandwidth allocation for Low */
48};
49
50/**
51 * QoS attribute returned in QoS Query
52 */
53struct bfa_qos_attr_s {
54 enum bfa_qos_state state; /* QoS current state */
55 u32 total_bb_cr; /* Total BB Credits */
56};
57
58/**
59 * These fields should be displayed only from the CLI.
60 * There will be a separate BFAL API (get_qos_vc_attr ?)
61 * to retrieve this.
62 *
63 */
64#define BFA_QOS_MAX_VC 16
65
66struct bfa_qos_vc_info_s {
67 u8 vc_credit;
68 u8 borrow_credit;
69 u8 priority;
70 u8 resvd;
71};
72
73struct bfa_qos_vc_attr_s {
74 u16 total_vc_count; /* Total VC Count */
75 u16 shared_credit;
76 u32 elp_opmode_flags;
77 struct bfa_qos_vc_info_s vc_info[BFA_QOS_MAX_VC]; /* as many as
78 * total_vc_count */
79};
80
81/**
82 * QoS statistics
83 */
84struct bfa_qos_stats_s {
85 u32 flogi_sent; /* QoS Flogi sent */
86 u32 flogi_acc_recvd; /* QoS Flogi Acc received */
87 u32 flogi_rjt_recvd; /* QoS Flogi rejects received */
88 u32 flogi_retries; /* QoS Flogi retries */
89
90 u32 elp_recvd; /* QoS ELP received */
91 u32 elp_accepted; /* QoS ELP Accepted */
92 u32 elp_rejected; /* QoS ELP rejected */
93 u32 elp_dropped; /* QoS ELP dropped */
94
95 u32 qos_rscn_recvd; /* QoS RSCN received */
96 u32 rsvd; /* padding for 64 bit alignment */
97};
98
99#endif /* __BFA_DEFS_QOS_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_rport.h b/drivers/scsi/bfa/include/defs/bfa_defs_rport.h
new file mode 100644
index 000000000000..e0af59d6d2f6
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_rport.h
@@ -0,0 +1,199 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_RPORT_H__
19#define __BFA_DEFS_RPORT_H__
20
21#include <bfa_os_inc.h>
22#include <protocol/types.h>
23#include <defs/bfa_defs_pport.h>
24#include <defs/bfa_defs_port.h>
25#include <defs/bfa_defs_qos.h>
26
27/**
28 * FCS remote port states
29 */
30enum bfa_rport_state {
31 BFA_RPORT_UNINIT = 0, /* PORT is not yet initialized */
32 BFA_RPORT_OFFLINE = 1, /* rport is offline */
33 BFA_RPORT_PLOGI = 2, /* PLOGI to rport is in progress */
34 BFA_RPORT_ONLINE = 3, /* login to rport is complete */
35 BFA_RPORT_PLOGI_RETRY = 4, /* retrying login to rport */
36 BFA_RPORT_NSQUERY = 5, /* nameserver query */
37 BFA_RPORT_ADISC = 6, /* ADISC authentication */
38 BFA_RPORT_LOGO = 7, /* logging out with rport */
39 BFA_RPORT_LOGORCV = 8, /* handling LOGO from rport */
40 BFA_RPORT_NSDISC = 9, /* re-discover rport */
41};
42
43/**
44 * Rport Scsi Function : Initiator/Target.
45 */
46enum bfa_rport_function {
47 BFA_RPORT_INITIATOR = 0x01, /* SCSI Initiator */
48 BFA_RPORT_TARGET = 0x02, /* SCSI Target */
49};
50
51/**
52 * port/node symbolic names for rport
53 */
54#define BFA_RPORT_SYMNAME_MAXLEN 255
55struct bfa_rport_symname_s {
56 char symname[BFA_RPORT_SYMNAME_MAXLEN];
57};
58
59struct bfa_rport_hal_stats_s {
60 u32 sm_un_cr; /* uninit: create events */
61 u32 sm_un_unexp; /* uninit: exception events */
62 u32 sm_cr_on; /* created: online events */
63 u32 sm_cr_del; /* created: delete events */
64 u32 sm_cr_hwf; /* created: IOC down */
65 u32 sm_cr_unexp; /* created: exception events */
66 u32 sm_fwc_rsp; /* fw create: f/w responses */
67 u32 sm_fwc_del; /* fw create: delete events */
68 u32 sm_fwc_off; /* fw create: offline events */
69 u32 sm_fwc_hwf; /* fw create: IOC down */
70 u32 sm_fwc_unexp; /* fw create: exception events*/
71 u32 sm_on_off; /* online: offline events */
72 u32 sm_on_del; /* online: delete events */
73 u32 sm_on_hwf; /* online: IOC down events */
74 u32 sm_on_unexp; /* online: exception events */
75 u32 sm_fwd_rsp; /* fw delete: fw responses */
76 u32 sm_fwd_del; /* fw delete: delete events */
77 u32 sm_fwd_hwf; /* fw delete: IOC down events */
78 u32 sm_fwd_unexp; /* fw delete: exception events*/
79 u32 sm_off_del; /* offline: delete events */
80 u32 sm_off_on; /* offline: online events */
81 u32 sm_off_hwf; /* offline: IOC down events */
82 u32 sm_off_unexp; /* offline: exception events */
83 u32 sm_del_fwrsp; /* delete: fw responses */
84 u32 sm_del_hwf; /* delete: IOC down events */
85 u32 sm_del_unexp; /* delete: exception events */
86 u32 sm_delp_fwrsp; /* delete pend: fw responses */
87 u32 sm_delp_hwf; /* delete pend: IOC downs */
88 u32 sm_delp_unexp; /* delete pend: exceptions */
89 u32 sm_offp_fwrsp; /* off-pending: fw responses */
90 u32 sm_offp_del; /* off-pending: deletes */
91 u32 sm_offp_hwf; /* off-pending: IOC downs */
92 u32 sm_offp_unexp; /* off-pending: exceptions */
93 u32 sm_iocd_off; /* IOC down: offline events */
94 u32 sm_iocd_del; /* IOC down: delete events */
95 u32 sm_iocd_on; /* IOC down: online events */
96 u32 sm_iocd_unexp; /* IOC down: exceptions */
97 u32 rsvd;
98};
99
100/**
101 * FCS remote port statistics
102 */
103struct bfa_rport_stats_s {
104 u32 offlines; /* remote port offline count */
105 u32 onlines; /* remote port online count */
106 u32 rscns; /* RSCN affecting rport */
107 u32 plogis; /* plogis sent */
108 u32 plogi_accs; /* plogi accepts */
109 u32 plogi_timeouts; /* plogi timeouts */
110 u32 plogi_rejects; /* rcvd plogi rejects */
111 u32 plogi_failed; /* local failure */
112 u32 plogi_rcvd; /* plogis rcvd */
113 u32 prli_rcvd; /* inbound PRLIs */
114 u32 adisc_rcvd; /* ADISCs received */
115 u32 adisc_rejects; /* recvd ADISC rejects */
116 u32 adisc_sent; /* ADISC requests sent */
117 u32 adisc_accs; /* ADISC accepted by rport */
118 u32 adisc_failed; /* ADISC failed (no response) */
119 u32 adisc_rejected; /* ADISC rejected by us */
120 u32 logos; /* logos sent */
121 u32 logo_accs; /* LOGO accepts from rport */
122 u32 logo_failed; /* LOGO failures */
123 u32 logo_rejected; /* LOGO rejects from rport */
124 u32 logo_rcvd; /* LOGO from remote port */
125
126 u32 rpsc_rcvd; /* RPSC received */
127 u32 rpsc_rejects; /* recvd RPSC rejects */
128 u32 rpsc_sent; /* RPSC requests sent */
129 u32 rpsc_accs; /* RPSC accepted by rport */
130 u32 rpsc_failed; /* RPSC failed (no response) */
131 u32 rpsc_rejected; /* RPSC rejected by us */
132
133 u32 rsvd;
134 struct bfa_rport_hal_stats_s hal_stats; /* BFA rport stats */
135};
136
137/**
138 * Rport's QoS attributes
139 */
140struct bfa_rport_qos_attr_s {
141 enum bfa_qos_priority qos_priority; /* rport's QoS priority */
142 u32 qos_flow_id; /* QoS flow Id */
143};
144
145/**
146 * FCS remote port attributes returned in queries
147 */
148struct bfa_rport_attr_s {
149 wwn_t nwwn; /* node wwn */
150 wwn_t pwwn; /* port wwn */
151 enum fc_cos cos_supported; /* supported class of services */
152 u32 pid; /* port ID */
153 u32 df_sz; /* Max payload size */
154 enum bfa_rport_state state; /* Rport State machine state */
155 enum fc_cos fc_cos; /* FC classes of services */
156 bfa_boolean_t cisc; /* CISC capable device */
157 struct bfa_rport_symname_s symname; /* Symbolic Name */
158 enum bfa_rport_function scsi_function; /* Initiator/Target */
159 struct bfa_rport_qos_attr_s qos_attr; /* qos attributes */
160 enum bfa_pport_speed curr_speed; /* operating speed got from
161 * RPSC ELS. UNKNOWN, if RPSC
162 * is not supported */
163 bfa_boolean_t trl_enforced; /* TRL enforced ? TRUE/FALSE */
164 enum bfa_pport_speed assigned_speed; /* Speed assigned by the user.
165 * will be used if RPSC is not
166 * supported by the rport */
167};
168
169#define bfa_rport_aen_qos_data_t struct bfa_rport_qos_attr_s
170
171/**
172 * BFA remote port events
173 * Arguments below are in BFAL context from Mgmt
174 * BFA_RPORT_AEN_ONLINE: [in]: lpwwn [out]: vf_id, lpwwn, rpwwn
175 * BFA_RPORT_AEN_OFFLINE: [in]: lpwwn [out]: vf_id, lpwwn, rpwwn
176 * BFA_RPORT_AEN_DISCONNECT:[in]: lpwwn [out]: vf_id, lpwwn, rpwwn
177 * BFA_RPORT_AEN_QOS_PRIO: [in]: lpwwn [out]: vf_id, lpwwn, rpwwn, prio
178 * BFA_RPORT_AEN_QOS_FLOWID:[in]: lpwwn [out]: vf_id, lpwwn, rpwwn, flow_id
179 */
180enum bfa_rport_aen_event {
181 BFA_RPORT_AEN_ONLINE = 1, /* RPort online event */
182 BFA_RPORT_AEN_OFFLINE = 2, /* RPort offline event */
183 BFA_RPORT_AEN_DISCONNECT = 3, /* RPort disconnect event */
184 BFA_RPORT_AEN_QOS_PRIO = 4, /* QOS priority change event */
185 BFA_RPORT_AEN_QOS_FLOWID = 5, /* QOS flow Id change event */
186};
187
188struct bfa_rport_aen_data_s {
189 u16 vf_id; /* vf_id of this logical port */
190 u16 rsvd[3];
191 wwn_t ppwwn; /* WWN of its physical port */
192 wwn_t lpwwn; /* WWN of this logical port */
193 wwn_t rpwwn; /* WWN of this remote port */
194 union {
195 bfa_rport_aen_qos_data_t qos;
196 } priv;
197};
198
199#endif /* __BFA_DEFS_RPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_status.h b/drivers/scsi/bfa/include/defs/bfa_defs_status.h
new file mode 100644
index 000000000000..cdceaeb9f4b8
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_status.h
@@ -0,0 +1,255 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_STATUS_H__
18#define __BFA_DEFS_STATUS_H__
19
20/**
21 * API status return values
22 *
23 * NOTE: The error msgs are auto generated from the comments. Only singe line
24 * comments are supported
25 */
26enum bfa_status {
27 BFA_STATUS_OK = 0, /* Success */
28 BFA_STATUS_FAILED = 1, /* Operation failed */
29 BFA_STATUS_EINVAL = 2, /* Invalid params Check input
30 * parameters */
31 BFA_STATUS_ENOMEM = 3, /* Out of resources */
32 BFA_STATUS_ENOSYS = 4, /* Function not implemented */
33 BFA_STATUS_ETIMER = 5, /* Timer expired - Retry, if
34 * persists, contact support */
35 BFA_STATUS_EPROTOCOL = 6, /* Protocol error */
36 BFA_STATUS_ENOFCPORTS = 7, /* No FC ports resources */
37 BFA_STATUS_NOFLASH = 8, /* Flash not present */
38 BFA_STATUS_BADFLASH = 9, /* Flash is corrupted or bad */
39 BFA_STATUS_SFP_UNSUPP = 10, /* Unsupported SFP - Replace SFP */
40 BFA_STATUS_UNKNOWN_VFID = 11, /* VF_ID not found */
41 BFA_STATUS_DATACORRUPTED = 12, /* Diag returned data corrupted
42 * contact support */
43 BFA_STATUS_DEVBUSY = 13, /* Device busy - Retry operation */
44 BFA_STATUS_ABORTED = 14, /* Operation aborted */
45 BFA_STATUS_NODEV = 15, /* Dev is not present */
46 BFA_STATUS_HDMA_FAILED = 16, /* Host dma failed contact support */
47 BFA_STATUS_FLASH_BAD_LEN = 17, /* Flash bad length */
48 BFA_STATUS_UNKNOWN_LWWN = 18, /* LPORT PWWN not found */
49 BFA_STATUS_UNKNOWN_RWWN = 19, /* RPORT PWWN not found */
50 BFA_STATUS_FCPT_LS_RJT = 20, /* Got LS_RJT for FC Pass
51 * through Req */
52 BFA_STATUS_VPORT_EXISTS = 21, /* VPORT already exists */
53 BFA_STATUS_VPORT_MAX = 22, /* Reached max VPORT supported
54 * limit */
55 BFA_STATUS_UNSUPP_SPEED = 23, /* Invalid Speed Check speed
56 * setting */
57 BFA_STATUS_INVLD_DFSZ = 24, /* Invalid Max data field size */
58 BFA_STATUS_CNFG_FAILED = 25, /* Setting can not be persisted */
59 BFA_STATUS_CMD_NOTSUPP = 26, /* Command/API not supported */
60 BFA_STATUS_NO_ADAPTER = 27, /* No Brocade Adapter Found */
61 BFA_STATUS_LINKDOWN = 28, /* Link is down - Check or replace
62 * SFP/cable */
63 BFA_STATUS_FABRIC_RJT = 29, /* Reject from attached fabric */
64 BFA_STATUS_UNKNOWN_VWWN = 30, /* VPORT PWWN not found */
65 BFA_STATUS_NSLOGIN_FAILED = 31, /* Nameserver login failed */
66 BFA_STATUS_NO_RPORTS = 32, /* No remote ports found */
67 BFA_STATUS_NSQUERY_FAILED = 33, /* Nameserver query failed */
68 BFA_STATUS_PORT_OFFLINE = 34, /* Port is not online */
69 BFA_STATUS_RPORT_OFFLINE = 35, /* RPORT is not online */
70 BFA_STATUS_TGTOPEN_FAILED = 36, /* Remote SCSI target open failed */
71 BFA_STATUS_BAD_LUNS = 37, /* No valid LUNs found */
72 BFA_STATUS_IO_FAILURE = 38, /* SCSI target IO failure */
73 BFA_STATUS_NO_FABRIC = 39, /* No switched fabric present */
74 BFA_STATUS_EBADF = 40, /* Bad file descriptor */
75 BFA_STATUS_EINTR = 41, /* A signal was caught during ioctl */
76 BFA_STATUS_EIO = 42, /* I/O error */
77 BFA_STATUS_ENOTTY = 43, /* Inappropriate I/O control
78 * operation */
79 BFA_STATUS_ENXIO = 44, /* No such device or address */
80 BFA_STATUS_EFOPEN = 45, /* Failed to open file */
81 BFA_STATUS_VPORT_WWN_BP = 46, /* WWN is same as base port's WWN */
82 BFA_STATUS_PORT_NOT_DISABLED = 47, /* Port not disabled disable port
83 * first */
84 BFA_STATUS_BADFRMHDR = 48, /* Bad frame header */
85 BFA_STATUS_BADFRMSZ = 49, /* Bad frame size check and replace
86 * SFP/cable */
87 BFA_STATUS_MISSINGFRM = 50, /* Missing frame check and replace
88 * SFP/cable */
89 BFA_STATUS_LINKTIMEOUT = 51, /* Link timeout check and replace
90 * SFP/cable */
91 BFA_STATUS_NO_FCPIM_NEXUS = 52, /* No FCP Nexus exists with the
92 * rport */
93 BFA_STATUS_CHECKSUM_FAIL = 53, /* checksum failure */
94 BFA_STATUS_GZME_FAILED = 54, /* Get zone member query failed */
95 BFA_STATUS_SCSISTART_REQD = 55, /* SCSI disk require START command */
96 BFA_STATUS_IOC_FAILURE = 56, /* IOC failure - Retry, if persists
97 * contact support */
98 BFA_STATUS_INVALID_WWN = 57, /* Invalid WWN */
99 BFA_STATUS_MISMATCH = 58, /* Version mismatch */
100 BFA_STATUS_IOC_ENABLED = 59, /* IOC is already enabled */
101 BFA_STATUS_ADAPTER_ENABLED = 60, /* Adapter is not disabled disable
102 * adapter first */
103 BFA_STATUS_IOC_NON_OP = 61, /* IOC is not operational. Enable IOC
104 * and if it still fails,
105 * contact support */
106 BFA_STATUS_ADDR_MAP_FAILURE = 62, /* PCI base address not mapped
107 * in OS */
108 BFA_STATUS_SAME_NAME = 63, /* Name exists! use a different
109 * name */
110 BFA_STATUS_PENDING = 64, /* API completes asynchronously */
111 BFA_STATUS_8G_SPD = 65, /* Speed setting not valid for
112 * 8G HBA */
113 BFA_STATUS_4G_SPD = 66, /* Speed setting not valid for
114 * 4G HBA */
115 BFA_STATUS_AD_IS_ENABLE = 67, /* Adapter is already enabled */
116 BFA_STATUS_EINVAL_TOV = 68, /* Invalid path failover TOV */
117 BFA_STATUS_EINVAL_QDEPTH = 69, /* Invalid queue depth value */
118 BFA_STATUS_VERSION_FAIL = 70, /* Application/Driver version
119 * mismatch */
120 BFA_STATUS_DIAG_BUSY = 71, /* diag busy */
121 BFA_STATUS_BEACON_ON = 72, /* Port Beacon already on */
122 BFA_STATUS_BEACON_OFF = 73, /* Port Beacon already off */
123 BFA_STATUS_LBEACON_ON = 74, /* Link End-to-End Beacon already
124 * on */
125 BFA_STATUS_LBEACON_OFF = 75, /* Link End-to-End Beacon already
126 * off */
127 BFA_STATUS_PORT_NOT_INITED = 76, /* Port not initialized */
128 BFA_STATUS_RPSC_ENABLED = 77, /* Target has a valid speed */
129 BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */
130 BFA_STATUS_BAD_FILE = 79, /* Not a valid Brocade Boot Code
131 * file */
132 BFA_STATUS_RLIM_EN = 80, /* Target rate limiting is already
133 * enabled */
134 BFA_STATUS_RLIM_DIS = 81, /* Target rate limiting is already
135 * disabled */
136 BFA_STATUS_IOC_DISABLED = 82, /* IOC is already disabled */
137 BFA_STATUS_ADAPTER_DISABLED = 83, /* Adapter is already disabled */
138 BFA_STATUS_BIOS_DISABLED = 84, /* Bios is already disabled */
139 BFA_STATUS_AUTH_ENABLED = 85, /* Authentication is already
140 * enabled */
141 BFA_STATUS_AUTH_DISABLED = 86, /* Authentication is already
142 * disabled */
143 BFA_STATUS_ERROR_TRL_ENABLED = 87, /* Target rate limiting is
144 * enabled */
145 BFA_STATUS_ERROR_QOS_ENABLED = 88, /* QoS is enabled */
146 BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */
147 BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact
148 * support */
149 BFA_STATUS_INVALID_DEVID = 91, /* Invalid device id provided */
150 BFA_STATUS_QOS_ENABLED = 92, /* QOS is already enabled */
151 BFA_STATUS_QOS_DISABLED = 93, /* QOS is already disabled */
152 BFA_STATUS_INCORRECT_DRV_CONFIG = 94, /* Check configuration
153 * key/value pair */
154 BFA_STATUS_REG_FAIL = 95, /* Can't read windows registry */
155 BFA_STATUS_IM_INV_CODE = 96, /* Invalid IOCTL code */
156 BFA_STATUS_IM_INV_VLAN = 97, /* Invalid VLAN ID */
157 BFA_STATUS_IM_INV_ADAPT_NAME = 98, /* Invalid adapter name */
158 BFA_STATUS_IM_LOW_RESOURCES = 99, /* Memory allocation failure in
159 * driver */
160 BFA_STATUS_IM_VLANID_IS_PVID = 100, /* Given VLAN id same as PVID */
161 BFA_STATUS_IM_VLANID_EXISTS = 101, /* Given VLAN id already exists */
162 BFA_STATUS_IM_FW_UPDATE_FAIL = 102, /* Updating firmware with new
163 * VLAN ID failed */
164 BFA_STATUS_PORTLOG_ENABLED = 103, /* Port Log is already enabled */
165 BFA_STATUS_PORTLOG_DISABLED = 104, /* Port Log is already disabled */
166 BFA_STATUS_FILE_NOT_FOUND = 105, /* Specified file could not be
167 * found */
168 BFA_STATUS_QOS_FC_ONLY = 106, /* QOS can be enabled for FC mode
169 * only */
170 BFA_STATUS_RLIM_FC_ONLY = 107, /* RATELIM can be enabled for FC mode
171 * only */
172 BFA_STATUS_CT_SPD = 108, /* Invalid speed selection for Catapult. */
173 BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */
174 BFA_STATUS_CEE_NOT_DN = 110, /* eth port is not at down state, please
175 * bring down first */
176 BFA_STATUS_10G_SPD = 111, /* Speed setting not valid for 10G HBA */
177 BFA_STATUS_IM_INV_TEAM_NAME = 112, /* Invalid team name */
178 BFA_STATUS_IM_DUP_TEAM_NAME = 113, /* Given team name already
179 * exists */
180 BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114, /* Given adapter is part
181 * of another team */
182 BFA_STATUS_IM_ADAPT_HAS_VLANS = 115, /* Adapter has VLANs configured.
183 * Delete all VLANs before
184 * creating team */
185 BFA_STATUS_IM_PVID_MISMATCH = 116, /* Mismatching PVIDs configured
186 * for adapters */
187 BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117, /* Mismatching link speeds
188 * configured for adapters */
189 BFA_STATUS_IM_MTU_MISMATCH = 118, /* Mismatching MTUs configured for
190 * adapters */
191 BFA_STATUS_IM_RSS_MISMATCH = 119, /* Mismatching RSS parameters
192 * configured for adapters */
193 BFA_STATUS_IM_HDS_MISMATCH = 120, /* Mismatching HDS parameters
194 * configured for adapters */
195 BFA_STATUS_IM_OFFLOAD_MISMATCH = 121, /* Mismatching offload
196 * parameters configured for
197 * adapters */
198 BFA_STATUS_IM_PORT_PARAMS = 122, /* Error setting port parameters */
199 BFA_STATUS_IM_PORT_NOT_IN_TEAM = 123, /* Port is not part of team */
200 BFA_STATUS_IM_CANNOT_REM_PRI = 124, /* Primary adapter cannot be
201 * removed. Change primary before
202 * removing */
203 BFA_STATUS_IM_MAX_PORTS_REACHED = 125, /* Exceeding maximum ports
204 * per team */
205 BFA_STATUS_IM_LAST_PORT_DELETE = 126, /* Last port in team being
206 * deleted */
207 BFA_STATUS_IM_NO_DRIVER = 127, /* IM driver is not installed */
208 BFA_STATUS_IM_MAX_VLANS_REACHED = 128, /* Exceeding maximum VLANs
209 * per port */
210 BFA_STATUS_TOMCAT_SPD_NOT_ALLOWED = 129, /* Bios speed config not
211 * allowed for CNA */
212 BFA_STATUS_NO_MINPORT_DRIVER = 130, /* Miniport driver is not
213 * loaded */
214 BFA_STATUS_CARD_TYPE_MISMATCH = 131, /* Card type mismatch */
215 BFA_STATUS_BAD_ASICBLK = 132, /* Bad ASIC block */
216 BFA_STATUS_NO_DRIVER = 133, /* Storage/Ethernet driver not loaded */
217 BFA_STATUS_INVALID_MAC = 134, /* Invalid mac address */
218 BFA_STATUS_IM_NO_VLAN = 135, /* No VLANs configured on the adapter */
219 BFA_STATUS_IM_ETH_LB_FAILED = 136, /* Ethernet loopback test failed */
220 BFA_STATUS_IM_PVID_REMOVE = 137, /* Cannot remove port vlan (PVID) */
221 BFA_STATUS_IM_PVID_EDIT = 138, /* Cannot edit port vlan (PVID) */
222 BFA_STATUS_CNA_NO_BOOT = 139, /* Boot upload not allowed for CNA */
223 BFA_STATUS_IM_PVID_NON_ZERO = 140, /* Port VLAN ID (PVID) is Set to
224 * Non-Zero Value */
225 BFA_STATUS_IM_INETCFG_LOCK_FAILED = 141, /* Acquiring Network
226 * Subsytem Lock Failed.Please
227 * try after some time */
228 BFA_STATUS_IM_GET_INETCFG_FAILED = 142, /* Acquiring Network Subsytem
229 * handle Failed. Please try
230 * after some time */
231 BFA_STATUS_IM_NOT_BOUND = 143, /* Brocade 10G Ethernet Service is not
232 * Enabled on this port */
233 BFA_STATUS_INSUFFICIENT_PERMS = 144, /* User doesn't have sufficient
234 * permissions to execute the BCU
235 * application */
236 BFA_STATUS_IM_INV_VLAN_NAME = 145, /* Invalid/Reserved Vlan name
237 * string. The name is not allowed
238 * for the normal Vlans */
239 BFA_STATUS_CMD_NOTSUPP_CNA = 146, /* Command not supported for CNA */
240 BFA_STATUS_IM_PASSTHRU_EDIT = 147, /* Can not edit passthru vlan id */
241 BFA_STATUS_IM_BIND_FAILED = 148, /*! < IM Driver bind operation
242 * failed */
243 BFA_STATUS_IM_UNBIND_FAILED = 149, /* ! < IM Driver unbind operation
244 * failed */
245 BFA_STATUS_MAX_VAL /* Unknown error code */
246};
247#define bfa_status_t enum bfa_status
248
249enum bfa_eproto_status {
250 BFA_EPROTO_BAD_ACCEPT = 0,
251 BFA_EPROTO_UNKNOWN_RSP = 1
252};
253#define bfa_eproto_status_t enum bfa_eproto_status
254
255#endif /* __BFA_DEFS_STATUS_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_tin.h b/drivers/scsi/bfa/include/defs/bfa_defs_tin.h
new file mode 100644
index 000000000000..e05a2db7abed
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_tin.h
@@ -0,0 +1,118 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_TIN_H__
19#define __BFA_DEFS_TIN_H__
20
21#include <protocol/types.h>
22#include <protocol/fc.h>
23
24/**
25 * FCS tin states
26 */
27enum bfa_tin_state_e {
28 BFA_TIN_SM_OFFLINE = 0, /* tin is offline */
29 BFA_TIN_SM_WOS_LOGIN = 1, /* Waiting PRLI ACC/RJT from ULP */
30 BFA_TIN_SM_WFW_ONLINE = 2, /* Waiting ACK to PRLI ACC from FW */
31 BFA_TIN_SM_ONLINE = 3, /* tin login is complete */
32 BFA_TIN_SM_WIO_RELOGIN = 4, /* tin relogin is in progress */
33 BFA_TIN_SM_WIO_LOGOUT = 5, /* Processing of PRLO req from
34 * Initiator is in progress
35 */
36 BFA_TIN_SM_WOS_LOGOUT = 6, /* Processing of PRLO req from
37 * Initiator is in progress
38 */
39 BFA_TIN_SM_WIO_CLEAN = 7, /* Waiting for IO cleanup before tin
40 * is offline. This can be triggered
41 * by RPORT LOGO (rcvd/sent) or by
42 * PRLO (rcvd/sent)
43 */
44};
45
46struct bfa_prli_req_s {
47 struct fchs_s fchs;
48 struct fc_prli_s prli_payload;
49};
50
51struct bfa_prlo_req_s {
52 struct fchs_s fchs;
53 struct fc_prlo_s prlo_payload;
54};
55
56void bfa_tin_send_login_rsp(void *bfa_tin, u32 login_rsp,
57 struct fc_ls_rjt_s rjt_payload);
58void bfa_tin_send_logout_rsp(void *bfa_tin, u32 logout_rsp,
59 struct fc_ls_rjt_s rjt_payload);
60/**
61 * FCS target port statistics
62 */
63struct bfa_tin_stats_s {
64 u32 onlines; /* ITN nexus onlines (PRLI done) */
65 u32 offlines; /* ITN Nexus offlines */
66 u32 prli_req_parse_err; /* prli req parsing errors */
67 u32 prli_rsp_rjt; /* num prli rsp rejects sent */
68 u32 prli_rsp_acc; /* num prli rsp accepts sent */
69 u32 cleanup_comps; /* ITN cleanup completions */
70};
71
72/**
73 * FCS tin attributes returned in queries
74 */
75struct bfa_tin_attr_s {
76 enum bfa_tin_state_e state;
77 u8 seq_retry; /* Sequence retry supported */
78 u8 rsvd[3];
79};
80
81/**
82 * BFA TIN async event data structure for BFAL
83 */
84enum bfa_tin_aen_event {
85 BFA_TIN_AEN_ONLINE = 1, /* Target online */
86 BFA_TIN_AEN_OFFLINE = 2, /* Target offline */
87 BFA_TIN_AEN_DISCONNECT = 3, /* Target disconnected */
88};
89
90/**
91 * BFA TIN event data structure.
92 */
93struct bfa_tin_aen_data_s {
94 u16 vf_id; /* vf_id of the IT nexus */
95 u16 rsvd[3];
96 wwn_t lpwwn; /* WWN of logical port */
97 wwn_t rpwwn; /* WWN of remote(target) port */
98};
99
100/**
101 * Below APIs are needed from BFA driver
102 * Move these to BFA driver public header file?
103 */
104/* TIN rcvd new PRLI & gets bfad_tin_t ptr from driver this callback */
105void *bfad_tin_rcvd_login_req(void *bfad_tm_port, void *bfa_tin,
106 wwn_t rp_wwn, u32 rp_fcid,
107 struct bfa_prli_req_s prli_req);
108/* TIN rcvd new PRLO */
109void bfad_tin_rcvd_logout_req(void *bfad_tin, wwn_t rp_wwn, u32 rp_fcid,
110 struct bfa_prlo_req_s prlo_req);
111/* TIN is online and ready for IO */
112void bfad_tin_online(void *bfad_tin);
113/* TIN is offline and BFA driver can shutdown its upper stack */
114void bfad_tin_offline(void *bfad_tin);
115/* TIN does not need this BFA driver tin tag anymore, so can be freed */
116void bfad_tin_res_free(void *bfad_tin);
117
118#endif /* __BFA_DEFS_TIN_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h b/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h
new file mode 100644
index 000000000000..31881d218515
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_TSENSOR_H__
19#define __BFA_DEFS_TSENSOR_H__
20
21#include <bfa_os_inc.h>
22#include <defs/bfa_defs_types.h>
23
24/**
25 * Temperature sensor status values
26 */
27enum bfa_tsensor_status {
28 BFA_TSENSOR_STATUS_UNKNOWN = 1, /* unkown status */
29 BFA_TSENSOR_STATUS_FAULTY = 2, /* sensor is faulty */
30 BFA_TSENSOR_STATUS_BELOW_MIN = 3, /* temperature below mininum */
31 BFA_TSENSOR_STATUS_NOMINAL = 4, /* normal temperature */
32 BFA_TSENSOR_STATUS_ABOVE_MAX = 5, /* temperature above maximum */
33};
34
35/**
36 * Temperature sensor attribute
37 */
38struct bfa_tsensor_attr_s {
39 enum bfa_tsensor_status status; /* temperature sensor status */
40 u32 value; /* current temperature in celsius */
41};
42
43#endif /* __BFA_DEFS_TSENSOR_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_types.h b/drivers/scsi/bfa/include/defs/bfa_defs_types.h
new file mode 100644
index 000000000000..4348332b107a
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_types.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_TYPES_H__
18#define __BFA_DEFS_TYPES_H__
19
20#include <bfa_os_inc.h>
21
22enum bfa_boolean {
23 BFA_FALSE = 0,
24 BFA_TRUE = 1
25};
26#define bfa_boolean_t enum bfa_boolean
27
28#define BFA_STRING_32 32
29
30#endif /* __BFA_DEFS_TYPES_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_version.h b/drivers/scsi/bfa/include/defs/bfa_defs_version.h
new file mode 100644
index 000000000000..f8902a2c9aad
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_version.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_VERSION_H__
18#define __BFA_DEFS_VERSION_H__
19
20#define BFA_VERSION_LEN 64
21
22#endif
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_vf.h b/drivers/scsi/bfa/include/defs/bfa_defs_vf.h
new file mode 100644
index 000000000000..3235be5e9423
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_vf.h
@@ -0,0 +1,74 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_VF_H__
19#define __BFA_DEFS_VF_H__
20
21#include <bfa_os_inc.h>
22#include <defs/bfa_defs_port.h>
23#include <protocol/types.h>
24
25/**
26 * VF states
27 */
28enum bfa_vf_state {
29 BFA_VF_UNINIT = 0, /* fabric is not yet initialized */
30 BFA_VF_LINK_DOWN = 1, /* link is down */
31 BFA_VF_FLOGI = 2, /* flogi is in progress */
32 BFA_VF_AUTH = 3, /* authentication in progress */
33 BFA_VF_NOFABRIC = 4, /* fabric is not present */
34 BFA_VF_ONLINE = 5, /* login to fabric is complete */
35 BFA_VF_EVFP = 6, /* EVFP is in progress */
36 BFA_VF_ISOLATED = 7, /* port isolated due to vf_id mismatch */
37};
38
39/**
40 * VF statistics
41 */
42struct bfa_vf_stats_s {
43 u32 flogi_sent; /* Num FLOGIs sent */
44 u32 flogi_rsp_err; /* FLOGI response errors */
45 u32 flogi_acc_err; /* FLOGI accept errors */
46 u32 flogi_accepts; /* FLOGI accepts received */
47 u32 flogi_rejects; /* FLOGI rejects received */
48 u32 flogi_unknown_rsp; /* Unknown responses for FLOGI */
49 u32 flogi_alloc_wait; /* Allocation waits prior to
50 * sending FLOGI
51 */
52 u32 flogi_rcvd; /* FLOGIs received */
53 u32 flogi_rejected; /* Incoming FLOGIs rejected */
54 u32 fabric_onlines; /* Internal fabric online
55 * notification sent to other
56 * modules
57 */
58 u32 fabric_offlines; /* Internal fabric offline
59 * notification sent to other
60 * modules
61 */
62 u32 resvd;
63};
64
65/**
66 * VF attributes returned in queries
67 */
68struct bfa_vf_attr_s {
69 enum bfa_vf_state state; /* VF state */
70 u32 rsvd;
71 wwn_t fabric_name; /* fabric name */
72};
73
74#endif /* __BFA_DEFS_VF_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_vport.h b/drivers/scsi/bfa/include/defs/bfa_defs_vport.h
new file mode 100644
index 000000000000..9f021f43b3b4
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_vport.h
@@ -0,0 +1,91 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_DEFS_VPORT_H__
19#define __BFA_DEFS_VPORT_H__
20
21#include <bfa_os_inc.h>
22#include <defs/bfa_defs_port.h>
23#include <protocol/types.h>
24
25/**
26 * VPORT states
27 */
28enum bfa_vport_state {
29 BFA_FCS_VPORT_UNINIT = 0,
30 BFA_FCS_VPORT_CREATED = 1,
31 BFA_FCS_VPORT_OFFLINE = 1,
32 BFA_FCS_VPORT_FDISC_SEND = 2,
33 BFA_FCS_VPORT_FDISC = 3,
34 BFA_FCS_VPORT_FDISC_RETRY = 4,
35 BFA_FCS_VPORT_ONLINE = 5,
36 BFA_FCS_VPORT_DELETING = 6,
37 BFA_FCS_VPORT_CLEANUP = 6,
38 BFA_FCS_VPORT_LOGO_SEND = 7,
39 BFA_FCS_VPORT_LOGO = 8,
40 BFA_FCS_VPORT_ERROR = 9,
41 BFA_FCS_VPORT_MAX_STATE,
42};
43
44/**
45 * vport statistics
46 */
47struct bfa_vport_stats_s {
48 struct bfa_port_stats_s port_stats; /* base class (port) stats */
49 /*
50 * TODO - remove
51 */
52
53 u32 fdisc_sent; /* num fdisc sent */
54 u32 fdisc_accepts; /* fdisc accepts */
55 u32 fdisc_retries; /* fdisc retries */
56 u32 fdisc_timeouts; /* fdisc timeouts */
57 u32 fdisc_rsp_err; /* fdisc response error */
58 u32 fdisc_acc_bad; /* bad fdisc accepts */
59 u32 fdisc_rejects; /* fdisc rejects */
60 u32 fdisc_unknown_rsp;
61 /*
62 *!< fdisc rsp unknown error
63 */
64 u32 fdisc_alloc_wait;/* fdisc req (fcxp)alloc wait */
65
66 u32 logo_alloc_wait;/* logo req (fcxp) alloc wait */
67 u32 logo_sent; /* logo sent */
68 u32 logo_accepts; /* logo accepts */
69 u32 logo_rejects; /* logo rejects */
70 u32 logo_rsp_err; /* logo rsp errors */
71 u32 logo_unknown_rsp;
72 /* logo rsp unknown errors */
73
74 u32 fab_no_npiv; /* fabric does not support npiv */
75
76 u32 fab_offline; /* offline events from fab SM */
77 u32 fab_online; /* online events from fab SM */
78 u32 fab_cleanup; /* cleanup request from fab SM */
79 u32 rsvd;
80};
81
82/**
83 * BFA vport attribute returned in queries
84 */
85struct bfa_vport_attr_s {
86 struct bfa_port_attr_s port_attr; /* base class (port) attributes */
87 enum bfa_vport_state vport_state; /* vport state */
88 u32 rsvd;
89};
90
91#endif /* __BFA_DEFS_VPORT_H__ */
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb.h b/drivers/scsi/bfa/include/fcb/bfa_fcb.h
new file mode 100644
index 000000000000..2963b0bc30e7
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcb.h BFA FCS callback interfaces
20 */
21
22#ifndef __BFA_FCB_H__
23#define __BFA_FCB_H__
24
25/**
26 * fcb Main fcs callbacks
27 */
28
29void bfa_fcb_exit(struct bfad_s *bfad);
30
31
32
33#endif /* __BFA_FCB_H__ */
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h
new file mode 100644
index 000000000000..a6c70aee0aa3
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h
@@ -0,0 +1,76 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19* : bfad_fcpim.h - BFA FCS initiator mode remote port callbacks
20 */
21
22#ifndef __BFAD_FCB_FCPIM_H__
23#define __BFAD_FCB_FCPIM_H__
24
25struct bfad_itnim_s;
26
27/*
28 * RPIM callbacks
29 */
30
31/**
32 * Memory allocation for remote port instance. Called before PRLI is
33 * initiated to the remote target port.
34 *
35 * @param[in] bfad - driver instance
36 * @param[out] itnim - FCS remote port (IM) instance
37 * @param[out] itnim_drv - driver remote port (IM) instance
38 *
39 * @return None
40 */
41void bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim,
42 struct bfad_itnim_s **itnim_drv);
43
44/**
45 * Free remote port (IM) instance.
46 *
47 * @param[in] bfad - driver instance
48 * @param[in] itnim_drv - driver remote port instance
49 *
50 * @return None
51 */
52void bfa_fcb_itnim_free(struct bfad_s *bfad,
53 struct bfad_itnim_s *itnim_drv);
54
55/**
56 * Notification of when login with a remote target device is complete.
57 *
58 * @param[in] itnim_drv - driver remote port instance
59 *
60 * @return None
61 */
62void bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv);
63
64/**
65 * Notification when login with the remote device is severed.
66 *
67 * @param[in] itnim_drv - driver remote port instance
68 *
69 * @return None
70 */
71void bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv);
72
73void bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim_drv);
74void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim_drv);
75
76#endif /* __BFAD_FCB_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_port.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_port.h
new file mode 100644
index 000000000000..5fd7f986fa32
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_port.h
@@ -0,0 +1,113 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcb_port.h BFA FCS virtual port driver interfaces
20 */
21
22#ifndef __BFA_FCB_PORT_H__
23#define __BFA_FCB_PORT_H__
24
25#include <fcb/bfa_fcb_vport.h>
26/**
27 * fcs_port_fcb FCS port driver interfaces
28 */
29
30/*
31 * Forward declarations
32 */
33struct bfad_port_s;
34
35/*
36 * Callback functions from BFA FCS to driver
37 */
38
39/**
40 * Call from FCS to driver module when a port is instantiated. The port
41 * can be a base port or a virtual port with in the base fabric or
42 * a virtual fabric.
43 *
44 * On this callback, driver is supposed to create scsi_host, scsi_tgt or
45 * network interfaces bases on ports personality/roles.
46 *
47 * base port of base fabric: vf_drv == NULL && vp_drv == NULL
48 * vport of base fabric: vf_drv == NULL && vp_drv != NULL
49 * base port of VF: vf_drv != NULL && vp_drv == NULL
50 * vport of VF: vf_drv != NULL && vp_drv != NULL
51 *
52 * @param[in] bfad - driver instance
53 * @param[in] port - FCS port instance
54 * @param[in] roles - port roles: IM, TM, IP
55 * @param[in] vf_drv - VF driver instance, NULL if base fabric (no VF)
56 * @param[in] vp_drv - vport driver instance, NULL if base port
57 *
58 * @return None
59 */
60struct bfad_port_s *bfa_fcb_port_new(struct bfad_s *bfad,
61 struct bfa_fcs_port_s *port,
62 enum bfa_port_role roles, struct bfad_vf_s *vf_drv,
63 struct bfad_vport_s *vp_drv);
64
65/**
66 * Call from FCS to driver module when a port is deleted. The port
67 * can be a base port or a virtual port with in the base fabric or
68 * a virtual fabric.
69 *
70 * @param[in] bfad - driver instance
71 * @param[in] roles - port roles: IM, TM, IP
72 * @param[in] vf_drv - VF driver instance, NULL if base fabric (no VF)
73 * @param[in] vp_drv - vport driver instance, NULL if base port
74 *
75 * @return None
76 */
77void bfa_fcb_port_delete(struct bfad_s *bfad, enum bfa_port_role roles,
78 struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv);
79
80/**
81 * Notification when port transitions to ONLINE state.
82 *
83 * Online notification is a logical link up for the local port. This
84 * notification is sent after a successfull FLOGI, or a successful
85 * link initialization in proviate-loop or N2N topologies.
86 *
87 * @param[in] bfad - driver instance
88 * @param[in] roles - port roles: IM, TM, IP
89 * @param[in] vf_drv - VF driver instance, NULL if base fabric (no VF)
90 * @param[in] vp_drv - vport driver instance, NULL if base port
91 *
92 * @return None
93 */
94void bfa_fcb_port_online(struct bfad_s *bfad, enum bfa_port_role roles,
95 struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv);
96
97/**
98 * Notification when port transitions to OFFLINE state.
99 *
100 * Offline notification is a logical link down for the local port.
101 *
102 * @param[in] bfad - driver instance
103 * @param[in] roles - port roles: IM, TM, IP
104 * @param[in] vf_drv - VF driver instance, NULL if base fabric (no VF)
105 * @param[in] vp_drv - vport driver instance, NULL if base port
106 *
107 * @return None
108 */
109void bfa_fcb_port_offline(struct bfad_s *bfad, enum bfa_port_role roles,
110 struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv);
111
112
113#endif /* __BFA_FCB_PORT_H__ */
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_rport.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_rport.h
new file mode 100644
index 000000000000..e0261bb6d1c1
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_rport.h
@@ -0,0 +1,80 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcb_rport.h BFA FCS rport driver interfaces
20 */
21
22#ifndef __BFA_FCB_RPORT_H__
23#define __BFA_FCB_RPORT_H__
24
25/**
26 * fcs_rport_fcb Remote port driver interfaces
27 */
28
29
30struct bfad_rport_s;
31
32/*
33 * Callback functions from BFA FCS to driver
34 */
35
36/**
37 * Completion callback for bfa_fcs_rport_add().
38 *
39 * @param[in] rport_drv - driver instance of rport
40 *
41 * @return None
42 */
43void bfa_fcb_rport_add(struct bfad_rport_s *rport_drv);
44
45/**
46 * Completion callback for bfa_fcs_rport_remove().
47 *
48 * @param[in] rport_drv - driver instance of rport
49 *
50 * @return None
51 */
52void bfa_fcb_rport_remove(struct bfad_rport_s *rport_drv);
53
54/**
55 * Call to allocate a rport instance.
56 *
57 * @param[in] bfad - driver instance
58 * @param[out] rport - BFA FCS instance of rport
59 * @param[out] rport_drv - driver instance of rport
60 *
61 * @retval BFA_STATUS_OK - successfully allocated
62 * @retval BFA_STATUS_ENOMEM - cannot allocate
63 */
64bfa_status_t bfa_fcb_rport_alloc(struct bfad_s *bfad,
65 struct bfa_fcs_rport_s **rport,
66 struct bfad_rport_s **rport_drv);
67
68/**
69 * Call to free rport memory resources.
70 *
71 * @param[in] bfad - driver instance
72 * @param[in] rport_drv - driver instance of rport
73 *
74 * @return None
75 */
76void bfa_fcb_rport_free(struct bfad_s *bfad, struct bfad_rport_s **rport_drv);
77
78
79
80#endif /* __BFA_FCB_RPORT_H__ */
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_vf.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_vf.h
new file mode 100644
index 000000000000..cfd3fac0a4e2
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_vf.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcb_vf.h BFA FCS virtual fabric driver interfaces
20 */
21
22#ifndef __BFA_FCB_VF_H__
23#define __BFA_FCB_VF_H__
24
25/**
26 * fcs_vf_fcb Virtual fabric driver intrefaces
27 */
28
29
30struct bfad_vf_s;
31
32/*
33 * Callback functions from BFA FCS to driver
34 */
35
36/**
37 * Completion callback for bfa_fcs_vf_stop().
38 *
39 * @param[in] vf_drv - driver instance of vf
40 *
41 * @return None
42 */
43void bfa_fcb_vf_stop(struct bfad_vf_s *vf_drv);
44
45
46
47#endif /* __BFA_FCB_VF_H__ */
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h
new file mode 100644
index 000000000000..a39f474c2fcf
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcb_vport.h BFA FCS virtual port driver interfaces
20 */
21
22#ifndef __BFA_FCB_VPORT_H__
23#define __BFA_FCB_VPORT_H__
24
25/**
26 * fcs_vport_fcb Virtual port driver interfaces
27 */
28
29
30struct bfad_vport_s;
31
32/*
33 * Callback functions from BFA FCS to driver
34 */
35
36/**
37 * Completion callback for bfa_fcs_vport_delete().
38 *
39 * @param[in] vport_drv - driver instance of vport
40 *
41 * @return None
42 */
43void bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv);
44
45
46
47#endif /* __BFA_FCB_VPORT_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs.h b/drivers/scsi/bfa/include/fcs/bfa_fcs.h
new file mode 100644
index 000000000000..627669c65546
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs.h
@@ -0,0 +1,73 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_FCS_H__
19#define __BFA_FCS_H__
20
21#include <cs/bfa_debug.h>
22#include <defs/bfa_defs_status.h>
23#include <defs/bfa_defs_version.h>
24#include <bfa.h>
25#include <fcs/bfa_fcs_fabric.h>
26
27#define BFA_FCS_OS_STR_LEN 64
28
29struct bfa_fcs_stats_s {
30 struct {
31 u32 untagged; /* untagged receive frames */
32 u32 tagged; /* tagged receive frames */
33 u32 vfid_unknown; /* VF id is unknown */
34 } uf;
35};
36
37struct bfa_fcs_driver_info_s {
38 u8 version[BFA_VERSION_LEN]; /* Driver Version */
39 u8 host_machine_name[BFA_FCS_OS_STR_LEN];
40 u8 host_os_name[BFA_FCS_OS_STR_LEN]; /* OS name and version */
41 u8 host_os_patch[BFA_FCS_OS_STR_LEN];/* patch or service pack */
42 u8 os_device_name[BFA_FCS_OS_STR_LEN]; /* Driver Device Name */
43};
44
45struct bfa_fcs_s {
46 struct bfa_s *bfa; /* corresponding BFA bfa instance */
47 struct bfad_s *bfad; /* corresponding BDA driver instance */
48 struct bfa_log_mod_s *logm; /* driver logging module instance */
49 struct bfa_trc_mod_s *trcmod; /* tracing module */
50 struct bfa_aen_s *aen; /* aen component */
51 bfa_boolean_t vf_enabled; /* VF mode is enabled */
52 bfa_boolean_t min_cfg; /* min cfg enabled/disabled */
53 u16 port_vfid; /* port default VF ID */
54 struct bfa_fcs_driver_info_s driver_info;
55 struct bfa_fcs_fabric_s fabric; /* base fabric state machine */
56 struct bfa_fcs_stats_s stats; /* FCS statistics */
57 struct bfa_wc_s wc; /* waiting counter */
58};
59
60/*
61 * bfa fcs API functions
62 */
63void bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
64 bfa_boolean_t min_cfg);
65void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
66 struct bfa_fcs_driver_info_s *driver_info);
67void bfa_fcs_exit(struct bfa_fcs_s *fcs);
68void bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod);
69void bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod);
70void bfa_fcs_aen_init(struct bfa_fcs_s *fcs, struct bfa_aen_s *aen);
71void bfa_fcs_start(struct bfa_fcs_s *fcs);
72
73#endif /* __BFA_FCS_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_auth.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_auth.h
new file mode 100644
index 000000000000..28c4c9ff08b3
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_auth.h
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_FCS_AUTH_H__
19#define __BFA_FCS_AUTH_H__
20
21struct bfa_fcs_s;
22
23#include <defs/bfa_defs_status.h>
24#include <defs/bfa_defs_auth.h>
25#include <defs/bfa_defs_vf.h>
26#include <cs/bfa_q.h>
27#include <cs/bfa_sm.h>
28#include <defs/bfa_defs_pport.h>
29#include <fcs/bfa_fcs_lport.h>
30#include <protocol/fc_sp.h>
31
32struct bfa_fcs_fabric_s;
33
34
35
36struct bfa_fcs_auth_s {
37 bfa_sm_t sm; /* state machine */
38 bfa_boolean_t policy; /* authentication enabled/disabled */
39 enum bfa_auth_status status; /* authentication status */
40 enum auth_rjt_codes rjt_code; /* auth reject status */
41 enum auth_rjt_code_exps rjt_code_exp; /* auth reject reason */
42 enum bfa_auth_algo algo; /* Authentication algorithm */
43 struct bfa_auth_stats_s stats; /* Statistics */
44 enum auth_dh_gid group; /* DH(diffie-hellman) Group */
45 enum bfa_auth_secretsource source; /* Secret source */
46 char secret[BFA_AUTH_SECRET_STRING_LEN];
47 /* secret string */
48 u8 secret_len;
49 /* secret string length */
50 u8 nretries;
51 /* number of retries */
52 struct bfa_fcs_fabric_s *fabric;/* pointer to fabric */
53 u8 sentcode; /* pointer to response data */
54 u8 *response; /* pointer to response data */
55 struct bfa_timer_s delay_timer; /* delay timer */
56 struct bfa_fcxp_s *fcxp; /* pointer to fcxp */
57 struct bfa_fcxp_wqe_s fcxp_wqe;
58};
59
60/**
61 * bfa fcs authentication public functions
62 */
63bfa_status_t bfa_fcs_auth_get_attr(struct bfa_fcs_s *port,
64 struct bfa_auth_attr_s *attr);
65bfa_status_t bfa_fcs_auth_set_policy(struct bfa_fcs_s *port,
66 bfa_boolean_t policy);
67enum bfa_auth_status bfa_fcs_auth_get_status(struct bfa_fcs_s *port);
68bfa_status_t bfa_fcs_auth_set_algo(struct bfa_fcs_s *port,
69 enum bfa_auth_algo algo);
70bfa_status_t bfa_fcs_auth_get_stats(struct bfa_fcs_s *port,
71 struct bfa_auth_stats_s *stats);
72bfa_status_t bfa_fcs_auth_set_dh_group(struct bfa_fcs_s *port, int group);
73bfa_status_t bfa_fcs_auth_set_secretstring(struct bfa_fcs_s *port,
74 char *secret);
75bfa_status_t bfa_fcs_auth_set_secretstring_encrypt(struct bfa_fcs_s *port,
76 u32 secret[], u32 len);
77bfa_status_t bfa_fcs_auth_set_secretsource(struct bfa_fcs_s *port,
78 enum bfa_auth_secretsource src);
79bfa_status_t bfa_fcs_auth_reset_stats(struct bfa_fcs_s *port);
80bfa_status_t bfa_fcs_auth_reinit(struct bfa_fcs_s *port);
81
82#endif /* __BFA_FCS_AUTH_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h
new file mode 100644
index 000000000000..4ffd2242d3de
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_FCS_FABRIC_H__
19#define __BFA_FCS_FABRIC_H__
20
21struct bfa_fcs_s;
22
23#include <defs/bfa_defs_status.h>
24#include <defs/bfa_defs_vf.h>
25#include <cs/bfa_q.h>
26#include <cs/bfa_sm.h>
27#include <defs/bfa_defs_pport.h>
28#include <fcs/bfa_fcs_lport.h>
29#include <protocol/fc_sp.h>
30#include <fcs/bfa_fcs_auth.h>
31
32/*
33 * forward declaration
34 */
35struct bfad_vf_s;
36
37enum bfa_fcs_fabric_type {
38 BFA_FCS_FABRIC_UNKNOWN = 0,
39 BFA_FCS_FABRIC_SWITCHED = 1,
40 BFA_FCS_FABRIC_PLOOP = 2,
41 BFA_FCS_FABRIC_N2N = 3,
42};
43
44
45struct bfa_fcs_fabric_s {
46 struct list_head qe; /* queue element */
47 bfa_sm_t sm; /* state machine */
48 struct bfa_fcs_s *fcs; /* FCS instance */
49 struct bfa_fcs_port_s bport; /* base logical port */
50 enum bfa_fcs_fabric_type fab_type; /* fabric type */
51 enum bfa_pport_type oper_type; /* current link topology */
52 u8 is_vf; /* is virtual fabric? */
53 u8 is_npiv; /* is NPIV supported ? */
54 u8 is_auth; /* is Security/Auth supported ? */
55 u16 bb_credit; /* BB credit from fabric */
56 u16 vf_id; /* virtual fabric ID */
57 u16 num_vports; /* num vports */
58 u16 rsvd;
59 struct list_head vport_q; /* queue of virtual ports */
60 struct list_head vf_q; /* queue of virtual fabrics */
61 struct bfad_vf_s *vf_drv; /* driver vf structure */
62 struct bfa_timer_s link_timer; /* Link Failure timer. Vport */
63 wwn_t fabric_name; /* attached fabric name */
64 bfa_boolean_t auth_reqd; /* authentication required */
65 struct bfa_timer_s delay_timer; /* delay timer */
66 union {
67 u16 swp_vfid;/* switch port VF id */
68 } event_arg;
69 struct bfa_fcs_auth_s auth; /* authentication config */
70 struct bfa_wc_s wc; /* wait counter for delete */
71 struct bfa_vf_stats_s stats; /* fabric/vf stats */
72 struct bfa_lps_s *lps; /* lport login services */
73 u8 fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /* attached
74 * fabric's ip addr
75 */
76};
77
78#define bfa_fcs_fabric_npiv_capable(__f) (__f)->is_npiv
79#define bfa_fcs_fabric_is_switched(__f) \
80 ((__f)->fab_type == BFA_FCS_FABRIC_SWITCHED)
81
82/**
83 * The design calls for a single implementation of base fabric and vf.
84 */
85#define bfa_fcs_vf_t struct bfa_fcs_fabric_s
86
87struct bfa_vf_event_s {
88 u32 undefined;
89};
90
91/**
92 * bfa fcs vf public functions
93 */
94bfa_status_t bfa_fcs_vf_mode_enable(struct bfa_fcs_s *fcs, u16 vf_id);
95bfa_status_t bfa_fcs_vf_mode_disable(struct bfa_fcs_s *fcs);
96bfa_status_t bfa_fcs_vf_create(bfa_fcs_vf_t *vf, struct bfa_fcs_s *fcs,
97 u16 vf_id, struct bfa_port_cfg_s *port_cfg,
98 struct bfad_vf_s *vf_drv);
99bfa_status_t bfa_fcs_vf_delete(bfa_fcs_vf_t *vf);
100void bfa_fcs_vf_start(bfa_fcs_vf_t *vf);
101bfa_status_t bfa_fcs_vf_stop(bfa_fcs_vf_t *vf);
102void bfa_fcs_vf_list(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs);
103void bfa_fcs_vf_list_all(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs);
104void bfa_fcs_vf_get_attr(bfa_fcs_vf_t *vf, struct bfa_vf_attr_s *vf_attr);
105void bfa_fcs_vf_get_stats(bfa_fcs_vf_t *vf,
106 struct bfa_vf_stats_s *vf_stats);
107void bfa_fcs_vf_clear_stats(bfa_fcs_vf_t *vf);
108void bfa_fcs_vf_get_ports(bfa_fcs_vf_t *vf, wwn_t vpwwn[], int *nports);
109bfa_fcs_vf_t *bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id);
110struct bfad_vf_s *bfa_fcs_vf_get_drv_vf(bfa_fcs_vf_t *vf);
111
112#endif /* __BFA_FCS_FABRIC_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h
new file mode 100644
index 000000000000..e719f2c3eb35
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h
@@ -0,0 +1,131 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcs_fcpim.h BFA FCS FCP Initiator Mode interfaces/defines.
20 */
21
22#ifndef __BFA_FCS_FCPIM_H__
23#define __BFA_FCS_FCPIM_H__
24
25#include <defs/bfa_defs_status.h>
26#include <defs/bfa_defs_itnim.h>
27#include <fcs/bfa_fcs.h>
28#include <fcs/bfa_fcs_rport.h>
29#include <fcs/bfa_fcs_lport.h>
30#include <bfa_fcpim.h>
31
32/*
33 * forward declarations
34 */
35struct bfad_itnim_s;
36
37struct bfa_fcs_itnim_s {
38 bfa_sm_t sm; /* state machine */
39 struct bfa_fcs_rport_s *rport; /* parent remote rport */
40 struct bfad_itnim_s *itnim_drv; /* driver peer instance */
41 struct bfa_fcs_s *fcs; /* fcs instance */
42 struct bfa_timer_s timer; /* timer functions */
43 struct bfa_itnim_s *bfa_itnim; /* BFA itnim struct */
44 bfa_boolean_t seq_rec; /* seq recovery support */
45 bfa_boolean_t rec_support; /* REC supported */
46 bfa_boolean_t conf_comp; /* FCP_CONF support */
47 bfa_boolean_t task_retry_id; /* task retry id supp */
48 struct bfa_fcxp_wqe_s fcxp_wqe; /* wait qelem for fcxp */
49 struct bfa_fcxp_s *fcxp; /* FCXP in use */
50 struct bfa_itnim_stats_s stats; /* itn statistics */
51};
52
53
54static inline struct bfad_port_s *
55bfa_fcs_itnim_get_drvport(struct bfa_fcs_itnim_s *itnim)
56{
57 return itnim->rport->port->bfad_port;
58}
59
60
61static inline struct bfa_fcs_port_s *
62bfa_fcs_itnim_get_port(struct bfa_fcs_itnim_s *itnim)
63{
64 return itnim->rport->port;
65}
66
67
68static inline wwn_t
69bfa_fcs_itnim_get_nwwn(struct bfa_fcs_itnim_s *itnim)
70{
71 return itnim->rport->nwwn;
72}
73
74
75static inline wwn_t
76bfa_fcs_itnim_get_pwwn(struct bfa_fcs_itnim_s *itnim)
77{
78 return itnim->rport->pwwn;
79}
80
81
82static inline u32
83bfa_fcs_itnim_get_fcid(struct bfa_fcs_itnim_s *itnim)
84{
85 return itnim->rport->pid;
86}
87
88
89static inline u32
90bfa_fcs_itnim_get_maxfrsize(struct bfa_fcs_itnim_s *itnim)
91{
92 return itnim->rport->maxfrsize;
93}
94
95
96static inline enum fc_cos
97bfa_fcs_itnim_get_cos(struct bfa_fcs_itnim_s *itnim)
98{
99 return itnim->rport->fc_cos;
100}
101
102
103static inline struct bfad_itnim_s *
104bfa_fcs_itnim_get_drvitn(struct bfa_fcs_itnim_s *itnim)
105{
106 return itnim->itnim_drv;
107}
108
109
110static inline struct bfa_itnim_s *
111bfa_fcs_itnim_get_halitn(struct bfa_fcs_itnim_s *itnim)
112{
113 return itnim->bfa_itnim;
114}
115
116/**
117 * bfa fcs FCP Initiator mode API functions
118 */
119void bfa_fcs_itnim_get_attr(struct bfa_fcs_itnim_s *itnim,
120 struct bfa_itnim_attr_s *attr);
121void bfa_fcs_itnim_get_stats(struct bfa_fcs_itnim_s *itnim,
122 struct bfa_itnim_stats_s *stats);
123struct bfa_fcs_itnim_s *bfa_fcs_itnim_lookup(struct bfa_fcs_port_s *port,
124 wwn_t rpwwn);
125bfa_status_t bfa_fcs_itnim_attr_get(struct bfa_fcs_port_s *port, wwn_t rpwwn,
126 struct bfa_itnim_attr_s *attr);
127bfa_status_t bfa_fcs_itnim_stats_get(struct bfa_fcs_port_s *port, wwn_t rpwwn,
128 struct bfa_itnim_stats_s *stats);
129bfa_status_t bfa_fcs_itnim_stats_clear(struct bfa_fcs_port_s *port,
130 wwn_t rpwwn);
131#endif /* __BFA_FCS_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_fdmi.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_fdmi.h
new file mode 100644
index 000000000000..4441fffc9c82
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_fdmi.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcs_fdmi.h BFA fcs fdmi module public interface
20 */
21
22#ifndef __BFA_FCS_FDMI_H__
23#define __BFA_FCS_FDMI_H__
24#include <bfa_os_inc.h>
25#include <protocol/fdmi.h>
26
27#define BFA_FCS_FDMI_SUPORTED_SPEEDS (FDMI_TRANS_SPEED_1G | \
28 FDMI_TRANS_SPEED_2G | \
29 FDMI_TRANS_SPEED_4G | \
30 FDMI_TRANS_SPEED_8G)
31
32/*
33* HBA Attribute Block : BFA internal representation. Note : Some variable
34* sizes have been trimmed to suit BFA For Ex : Model will be "Brocade". Based
35 * on this the size has been reduced to 16 bytes from the standard's 64 bytes.
36 */
37struct bfa_fcs_fdmi_hba_attr_s {
38 wwn_t node_name;
39 u8 manufacturer[64];
40 u8 serial_num[64];
41 u8 model[16];
42 u8 model_desc[256];
43 u8 hw_version[8];
44 u8 driver_version[8];
45 u8 option_rom_ver[BFA_VERSION_LEN];
46 u8 fw_version[8];
47 u8 os_name[256];
48 u32 max_ct_pyld;
49};
50
51/*
52 * Port Attribute Block
53 */
54struct bfa_fcs_fdmi_port_attr_s {
55 u8 supp_fc4_types[32]; /* supported FC4 types */
56 u32 supp_speed; /* supported speed */
57 u32 curr_speed; /* current Speed */
58 u32 max_frm_size; /* max frame size */
59 u8 os_device_name[256]; /* OS device Name */
60 u8 host_name[256]; /* host name */
61};
62
63#endif /* __BFA_FCS_FDMI_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
new file mode 100644
index 000000000000..b85cba884b96
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
@@ -0,0 +1,226 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcs_port.h BFA fcs port module public interface
20 */
21
22#ifndef __BFA_FCS_PORT_H__
23#define __BFA_FCS_PORT_H__
24
25#include <defs/bfa_defs_status.h>
26#include <defs/bfa_defs_port.h>
27#include <defs/bfa_defs_pport.h>
28#include <defs/bfa_defs_rport.h>
29#include <cs/bfa_q.h>
30#include <bfa_svc.h>
31#include <cs/bfa_wc.h>
32
33struct bfa_fcs_s;
34struct bfa_fcs_fabric_s;
35
36/*
37* @todo : need to move to a global config file.
38 * Maximum Vports supported per physical port or vf.
39 */
40#define BFA_FCS_MAX_VPORTS_SUPP_CB 255
41#define BFA_FCS_MAX_VPORTS_SUPP_CT 191
42
43/*
44* @todo : need to move to a global config file.
45 * Maximum Rports supported per port (physical/logical).
46 */
47#define BFA_FCS_MAX_RPORTS_SUPP 256 /* @todo : tentative value */
48
49
50struct bfa_fcs_port_ns_s {
51 bfa_sm_t sm; /* state machine */
52 struct bfa_timer_s timer;
53 struct bfa_fcs_port_s *port; /* parent port */
54 struct bfa_fcxp_s *fcxp;
55 struct bfa_fcxp_wqe_s fcxp_wqe;
56};
57
58
59struct bfa_fcs_port_scn_s {
60 bfa_sm_t sm; /* state machine */
61 struct bfa_timer_s timer;
62 struct bfa_fcs_port_s *port; /* parent port */
63 struct bfa_fcxp_s *fcxp;
64 struct bfa_fcxp_wqe_s fcxp_wqe;
65};
66
67
68struct bfa_fcs_port_fdmi_s {
69 bfa_sm_t sm; /* state machine */
70 struct bfa_timer_s timer;
71 struct bfa_fcs_port_ms_s *ms; /* parent ms */
72 struct bfa_fcxp_s *fcxp;
73 struct bfa_fcxp_wqe_s fcxp_wqe;
74 u8 retry_cnt; /* retry count */
75 u8 rsvd[3];
76};
77
78
79struct bfa_fcs_port_ms_s {
80 bfa_sm_t sm; /* state machine */
81 struct bfa_timer_s timer;
82 struct bfa_fcs_port_s *port; /* parent port */
83 struct bfa_fcxp_s *fcxp;
84 struct bfa_fcxp_wqe_s fcxp_wqe;
85 struct bfa_fcs_port_fdmi_s fdmi; /* FDMI component of MS */
86 u8 retry_cnt; /* retry count */
87 u8 rsvd[3];
88};
89
90
91struct bfa_fcs_port_fab_s {
92 struct bfa_fcs_port_ns_s ns; /* NS component of port */
93 struct bfa_fcs_port_scn_s scn; /* scn component of port */
94 struct bfa_fcs_port_ms_s ms; /* MS component of port */
95};
96
97
98
99#define MAX_ALPA_COUNT 127
100
101struct bfa_fcs_port_loop_s {
102 u8 num_alpa; /* Num of ALPA entries in the map */
103 u8 alpa_pos_map[MAX_ALPA_COUNT]; /* ALPA Positional
104 *Map */
105 struct bfa_fcs_port_s *port; /* parent port */
106};
107
108
109
110struct bfa_fcs_port_n2n_s {
111 u32 rsvd;
112 u16 reply_oxid; /* ox_id from the req flogi to be
113 *used in flogi acc */
114 wwn_t rem_port_wwn; /* Attached port's wwn */
115};
116
117
118union bfa_fcs_port_topo_u {
119 struct bfa_fcs_port_fab_s pfab;
120 struct bfa_fcs_port_loop_s ploop;
121 struct bfa_fcs_port_n2n_s pn2n;
122};
123
124
125struct bfa_fcs_port_s {
126 struct list_head qe; /* used by port/vport */
127 bfa_sm_t sm; /* state machine */
128 struct bfa_fcs_fabric_s *fabric; /* parent fabric */
129 struct bfa_port_cfg_s port_cfg; /* port configuration */
130 struct bfa_timer_s link_timer; /* timer for link offline */
131 u32 pid : 24; /* FC address */
132 u8 lp_tag; /* lport tag */
133 u16 num_rports; /* Num of r-ports */
134 struct list_head rport_q; /* queue of discovered r-ports */
135 struct bfa_fcs_s *fcs; /* FCS instance */
136 union bfa_fcs_port_topo_u port_topo; /* fabric/loop/n2n details */
137 struct bfad_port_s *bfad_port; /* driver peer instance */
138 struct bfa_fcs_vport_s *vport; /* NULL for base ports */
139 struct bfa_fcxp_s *fcxp;
140 struct bfa_fcxp_wqe_s fcxp_wqe;
141 struct bfa_port_stats_s stats;
142 struct bfa_wc_s wc; /* waiting counter for events */
143};
144
145#define bfa_fcs_lport_t struct bfa_fcs_port_s
146
147/**
148 * Symbolic Name related defines
149 * Total bytes 255.
150 * Physical Port's symbolic name 128 bytes.
151 * For Vports, Vport's symbolic name is appended to the Physical port's
152 * Symbolic Name.
153 *
154 * Physical Port's symbolic name Format : (Total 128 bytes)
155 * Adapter Model number/name : 12 bytes
156 * Driver Version : 10 bytes
157 * Host Machine Name : 30 bytes
158 * Host OS Info : 48 bytes
159 * Host OS PATCH Info : 16 bytes
160 * ( remaining 12 bytes reserved to be used for separator)
161 */
162#define BFA_FCS_PORT_SYMBNAME_SEPARATOR " | "
163
164#define BFA_FCS_PORT_SYMBNAME_MODEL_SZ 12
165#define BFA_FCS_PORT_SYMBNAME_VERSION_SZ 10
166#define BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ 30
167#define BFA_FCS_PORT_SYMBNAME_OSINFO_SZ 48
168#define BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ 16
169
170/**
171 * Get FC port ID for a logical port.
172 */
173#define bfa_fcs_port_get_fcid(_lport) ((_lport)->pid)
174#define bfa_fcs_port_get_pwwn(_lport) ((_lport)->port_cfg.pwwn)
175#define bfa_fcs_port_get_nwwn(_lport) ((_lport)->port_cfg.nwwn)
176#define bfa_fcs_port_get_psym_name(_lport) ((_lport)->port_cfg.sym_name)
177#define bfa_fcs_port_is_initiator(_lport) \
178 ((_lport)->port_cfg.roles & BFA_PORT_ROLE_FCP_IM)
179#define bfa_fcs_port_is_target(_lport) \
180 ((_lport)->port_cfg.roles & BFA_PORT_ROLE_FCP_TM)
181#define bfa_fcs_port_get_nrports(_lport) \
182 ((_lport) ? (_lport)->num_rports : 0)
183
184static inline struct bfad_port_s *
185bfa_fcs_port_get_drvport(struct bfa_fcs_port_s *port)
186{
187 return port->bfad_port;
188}
189
190
191#define bfa_fcs_port_get_opertype(_lport) (_lport)->fabric->oper_type
192
193
194#define bfa_fcs_port_get_fabric_name(_lport) (_lport)->fabric->fabric_name
195
196
197#define bfa_fcs_port_get_fabric_ipaddr(_lport) (_lport)->fabric->fabric_ip_addr
198
199/**
200 * bfa fcs port public functions
201 */
202void bfa_fcs_cfg_base_port(struct bfa_fcs_s *fcs,
203 struct bfa_port_cfg_s *port_cfg);
204struct bfa_fcs_port_s *bfa_fcs_get_base_port(struct bfa_fcs_s *fcs);
205void bfa_fcs_port_get_rports(struct bfa_fcs_port_s *port,
206 wwn_t rport_wwns[], int *nrports);
207
208wwn_t bfa_fcs_port_get_rport(struct bfa_fcs_port_s *port, wwn_t wwn,
209 int index, int nrports, bfa_boolean_t bwwn);
210
211struct bfa_fcs_port_s *bfa_fcs_lookup_port(struct bfa_fcs_s *fcs,
212 u16 vf_id, wwn_t lpwwn);
213
214void bfa_fcs_port_get_info(struct bfa_fcs_port_s *port,
215 struct bfa_port_info_s *port_info);
216void bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port,
217 struct bfa_port_attr_s *port_attr);
218void bfa_fcs_port_get_stats(struct bfa_fcs_port_s *fcs_port,
219 struct bfa_port_stats_s *port_stats);
220void bfa_fcs_port_clear_stats(struct bfa_fcs_port_s *fcs_port);
221enum bfa_pport_speed bfa_fcs_port_get_rport_max_speed(
222 struct bfa_fcs_port_s *port);
223void bfa_fcs_port_enable_ipfc_roles(struct bfa_fcs_port_s *fcs_port);
224void bfa_fcs_port_disable_ipfc_roles(struct bfa_fcs_port_s *fcs_port);
225
226#endif /* __BFA_FCS_PORT_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h
new file mode 100644
index 000000000000..702b95b76c2d
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h
@@ -0,0 +1,104 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __BFA_FCS_RPORT_H__
19#define __BFA_FCS_RPORT_H__
20
21#include <defs/bfa_defs_status.h>
22#include <cs/bfa_q.h>
23#include <fcs/bfa_fcs.h>
24#include <defs/bfa_defs_rport.h>
25
26#define BFA_FCS_RPORT_DEF_DEL_TIMEOUT 90 /* in secs */
27/*
28 * forward declarations
29 */
30struct bfad_rport_s;
31
32struct bfa_fcs_itnim_s;
33struct bfa_fcs_tin_s;
34struct bfa_fcs_iprp_s;
35
36/* Rport Features (RPF) */
37struct bfa_fcs_rpf_s {
38 bfa_sm_t sm; /* state machine */
39 struct bfa_fcs_rport_s *rport; /* parent rport */
40 struct bfa_timer_s timer; /* general purpose timer */
41 struct bfa_fcxp_s *fcxp; /* FCXP needed for discarding */
42 struct bfa_fcxp_wqe_s fcxp_wqe; /* fcxp wait queue element */
43 int rpsc_retries; /* max RPSC retry attempts */
44 enum bfa_pport_speed rpsc_speed; /* Current Speed from RPSC.
45 * O if RPSC fails */
46 enum bfa_pport_speed assigned_speed; /* Speed assigned by the user.
47 * will be used if RPSC is not
48 * supported by the rport */
49};
50
51struct bfa_fcs_rport_s {
52 struct list_head qe; /* used by port/vport */
53 struct bfa_fcs_port_s *port; /* parent FCS port */
54 struct bfa_fcs_s *fcs; /* fcs instance */
55 struct bfad_rport_s *rp_drv; /* driver peer instance */
56 u32 pid; /* port ID of rport */
57 u16 maxfrsize; /* maximum frame size */
58 u16 reply_oxid; /* OX_ID of inbound requests */
59 enum fc_cos fc_cos; /* FC classes of service supp */
60 bfa_boolean_t cisc; /* CISC capable device */
61 wwn_t pwwn; /* port wwn of rport */
62 wwn_t nwwn; /* node wwn of rport */
63 struct bfa_rport_symname_s psym_name; /* port symbolic name */
64 bfa_sm_t sm; /* state machine */
65 struct bfa_timer_s timer; /* general purpose timer */
66 struct bfa_fcs_itnim_s *itnim; /* ITN initiator mode role */
67 struct bfa_fcs_tin_s *tin; /* ITN initiator mode role */
68 struct bfa_fcs_iprp_s *iprp; /* IP/FC role */
69 struct bfa_rport_s *bfa_rport; /* BFA Rport */
70 struct bfa_fcxp_s *fcxp; /* FCXP needed for discarding */
71 int plogi_retries; /* max plogi retry attempts */
72 int ns_retries; /* max NS query retry attempts */
73 struct bfa_fcxp_wqe_s fcxp_wqe; /* fcxp wait queue element */
74 struct bfa_rport_stats_s stats; /* rport stats */
75 enum bfa_rport_function scsi_function; /* Initiator/Target */
76 struct bfa_fcs_rpf_s rpf; /* Rport features module */
77};
78
79static inline struct bfa_rport_s *
80bfa_fcs_rport_get_halrport(struct bfa_fcs_rport_s *rport)
81{
82 return rport->bfa_rport;
83}
84
85/**
86 * bfa fcs rport API functions
87 */
88bfa_status_t bfa_fcs_rport_add(struct bfa_fcs_port_s *port, wwn_t *pwwn,
89 struct bfa_fcs_rport_s *rport,
90 struct bfad_rport_s *rport_drv);
91bfa_status_t bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport);
92void bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
93 struct bfa_rport_attr_s *attr);
94void bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport,
95 struct bfa_rport_stats_s *stats);
96void bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport);
97struct bfa_fcs_rport_s *bfa_fcs_rport_lookup(struct bfa_fcs_port_s *port,
98 wwn_t rpwwn);
99struct bfa_fcs_rport_s *bfa_fcs_rport_lookup_by_nwwn(
100 struct bfa_fcs_port_s *port, wwn_t rnwwn);
101void bfa_fcs_rport_set_del_timeout(u8 rport_tmo);
102void bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport,
103 enum bfa_pport_speed speed);
104#endif /* __BFA_FCS_RPORT_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h
new file mode 100644
index 000000000000..cd33f2cd5c34
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcs_vport.h BFA fcs vport module public interface
20 */
21
22#ifndef __BFA_FCS_VPORT_H__
23#define __BFA_FCS_VPORT_H__
24
25#include <defs/bfa_defs_status.h>
26#include <defs/bfa_defs_port.h>
27#include <defs/bfa_defs_vport.h>
28#include <fcs/bfa_fcs.h>
29#include <fcb/bfa_fcb_vport.h>
30
31struct bfa_fcs_vport_s {
32 struct list_head qe; /* queue elem */
33 bfa_sm_t sm; /* state machine */
34 bfa_fcs_lport_t lport; /* logical port */
35 struct bfa_timer_s timer; /* general purpose timer */
36 struct bfad_vport_s *vport_drv; /* Driver private */
37 struct bfa_vport_stats_s vport_stats; /* vport statistics */
38 struct bfa_lps_s *lps; /* Lport login service */
39 int fdisc_retries;
40};
41
42#define bfa_fcs_vport_get_port(vport) \
43 ((struct bfa_fcs_port_s *)(&vport->port))
44
45/**
46 * bfa fcs vport public functions
47 */
48bfa_status_t bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport,
49 struct bfa_fcs_s *fcs, u16 vf_id,
50 struct bfa_port_cfg_s *port_cfg,
51 struct bfad_vport_s *vport_drv);
52bfa_status_t bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport);
53bfa_status_t bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport);
54bfa_status_t bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport);
55void bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
56 struct bfa_vport_attr_s *vport_attr);
57void bfa_fcs_vport_get_stats(struct bfa_fcs_vport_s *vport,
58 struct bfa_vport_stats_s *vport_stats);
59void bfa_fcs_vport_clr_stats(struct bfa_fcs_vport_s *vport);
60struct bfa_fcs_vport_s *bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs,
61 u16 vf_id, wwn_t vpwwn);
62
63#endif /* __BFA_FCS_VPORT_H__ */
diff --git a/drivers/scsi/bfa/include/log/bfa_log_fcs.h b/drivers/scsi/bfa/include/log/bfa_log_fcs.h
new file mode 100644
index 000000000000..b6f5df8827f8
--- /dev/null
+++ b/drivers/scsi/bfa/include/log/bfa_log_fcs.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright (c) 2005-2009 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/*
19 * messages define for FCS Module
20 */
21#ifndef __BFA_LOG_FCS_H__
22#define __BFA_LOG_FCS_H__
23#include <cs/bfa_log.h>
24#define BFA_LOG_FCS_FABRIC_NOSWITCH \
25 (((u32) BFA_LOG_FCS_ID << BFA_LOG_MODID_OFFSET) | 1)
26#define BFA_LOG_FCS_FABRIC_ISOLATED \
27 (((u32) BFA_LOG_FCS_ID << BFA_LOG_MODID_OFFSET) | 2)
28#endif
diff --git a/drivers/scsi/bfa/include/log/bfa_log_hal.h b/drivers/scsi/bfa/include/log/bfa_log_hal.h
new file mode 100644
index 000000000000..0412aea2ec30
--- /dev/null
+++ b/drivers/scsi/bfa/include/log/bfa_log_hal.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (c) 2005-2009 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/* messages define for HAL Module */
19#ifndef __BFA_LOG_HAL_H__
20#define __BFA_LOG_HAL_H__
21#include <cs/bfa_log.h>
22#define BFA_LOG_HAL_ASSERT \
23 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 1)
24#define BFA_LOG_HAL_HEARTBEAT_FAILURE \
25 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 2)
26#define BFA_LOG_HAL_FCPIM_PARM_INVALID \
27 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 3)
28#define BFA_LOG_HAL_SM_ASSERT \
29 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 4)
30#endif
diff --git a/drivers/scsi/bfa/include/log/bfa_log_linux.h b/drivers/scsi/bfa/include/log/bfa_log_linux.h
new file mode 100644
index 000000000000..317c0547ee16
--- /dev/null
+++ b/drivers/scsi/bfa/include/log/bfa_log_linux.h
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 2005-2009 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/* messages define for LINUX Module */
19#ifndef __BFA_LOG_LINUX_H__
20#define __BFA_LOG_LINUX_H__
21#include <cs/bfa_log.h>
22#define BFA_LOG_LINUX_DEVICE_CLAIMED \
23 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 1)
24#define BFA_LOG_LINUX_HASH_INIT_FAILED \
25 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 2)
26#define BFA_LOG_LINUX_SYSFS_FAILED \
27 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 3)
28#define BFA_LOG_LINUX_MEM_ALLOC_FAILED \
29 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 4)
30#define BFA_LOG_LINUX_DRIVER_REGISTRATION_FAILED \
31 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 5)
32#define BFA_LOG_LINUX_ITNIM_FREE \
33 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 6)
34#define BFA_LOG_LINUX_ITNIM_ONLINE \
35 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 7)
36#define BFA_LOG_LINUX_ITNIM_OFFLINE \
37 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 8)
38#define BFA_LOG_LINUX_SCSI_HOST_FREE \
39 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 9)
40#define BFA_LOG_LINUX_SCSI_ABORT \
41 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 10)
42#define BFA_LOG_LINUX_SCSI_ABORT_COMP \
43 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 11)
44#endif
diff --git a/drivers/scsi/bfa/include/log/bfa_log_wdrv.h b/drivers/scsi/bfa/include/log/bfa_log_wdrv.h
new file mode 100644
index 000000000000..809a95f7afe2
--- /dev/null
+++ b/drivers/scsi/bfa/include/log/bfa_log_wdrv.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) 2005-2009 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/*
19 * messages define for WDRV Module
20 */
21#ifndef __BFA_LOG_WDRV_H__
22#define __BFA_LOG_WDRV_H__
23#include <cs/bfa_log.h>
24#define BFA_LOG_WDRV_IOC_INIT_ERROR \
25 (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 1)
26#define BFA_LOG_WDRV_IOC_INTERNAL_ERROR \
27 (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 2)
28#define BFA_LOG_WDRV_IOC_START_ERROR \
29 (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 3)
30#define BFA_LOG_WDRV_IOC_STOP_ERROR \
31 (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 4)
32#define BFA_LOG_WDRV_INSUFFICIENT_RESOURCES \
33 (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 5)
34#define BFA_LOG_WDRV_BASE_ADDRESS_MAP_ERROR \
35 (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 6)
36#endif
diff --git a/drivers/scsi/bfa/include/protocol/ct.h b/drivers/scsi/bfa/include/protocol/ct.h
new file mode 100644
index 000000000000..c59d6630b070
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/ct.h
@@ -0,0 +1,492 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __CT_H__
19#define __CT_H__
20
21#include <protocol/types.h>
22
23#pragma pack(1)
24
25struct ct_hdr_s{
26 u32 rev_id:8; /* Revision of the CT */
27 u32 in_id:24; /* Initiator Id */
28 u32 gs_type:8; /* Generic service Type */
29 u32 gs_sub_type:8; /* Generic service sub type */
30 u32 options:8; /* options */
31 u32 rsvrd:8; /* reserved */
32 u32 cmd_rsp_code:16;/* ct command/response code */
33 u32 max_res_size:16;/* maximum/residual size */
34 u32 frag_id:8; /* fragment ID */
35 u32 reason_code:8; /* reason code */
36 u32 exp_code:8; /* explanation code */
37 u32 vendor_unq:8; /* vendor unique */
38};
39
40/*
41 * defines for the Revision
42 */
43enum {
44 CT_GS3_REVISION = 0x01,
45};
46
47/*
48 * defines for gs_type
49 */
50enum {
51 CT_GSTYPE_KEYSERVICE = 0xF7,
52 CT_GSTYPE_ALIASSERVICE = 0xF8,
53 CT_GSTYPE_MGMTSERVICE = 0xFA,
54 CT_GSTYPE_TIMESERVICE = 0xFB,
55 CT_GSTYPE_DIRSERVICE = 0xFC,
56};
57
58/*
59 * defines for gs_sub_type for gs type directory service
60 */
61enum {
62 CT_GSSUBTYPE_NAMESERVER = 0x02,
63};
64
65/*
66 * defines for gs_sub_type for gs type management service
67 */
68enum {
69 CT_GSSUBTYPE_CFGSERVER = 0x01,
70 CT_GSSUBTYPE_UNZONED_NS = 0x02,
71 CT_GSSUBTYPE_ZONESERVER = 0x03,
72 CT_GSSUBTYPE_LOCKSERVER = 0x04,
73 CT_GSSUBTYPE_HBA_MGMTSERVER = 0x10, /* for FDMI */
74};
75
76/*
77 * defines for CT response code field
78 */
79enum {
80 CT_RSP_REJECT = 0x8001,
81 CT_RSP_ACCEPT = 0x8002,
82};
83
84/*
85 * defintions for CT reason code
86 */
87enum {
88 CT_RSN_INV_CMD = 0x01,
89 CT_RSN_INV_VER = 0x02,
90 CT_RSN_LOGIC_ERR = 0x03,
91 CT_RSN_INV_SIZE = 0x04,
92 CT_RSN_LOGICAL_BUSY = 0x05,
93 CT_RSN_PROTO_ERR = 0x07,
94 CT_RSN_UNABLE_TO_PERF = 0x09,
95 CT_RSN_NOT_SUPP = 0x0B,
96 CT_RSN_SERVER_NOT_AVBL = 0x0D,
97 CT_RSN_SESSION_COULD_NOT_BE_ESTBD = 0x0E,
98 CT_RSN_VENDOR_SPECIFIC = 0xFF,
99
100};
101
102/*
103 * definitions for explanations code for Name server
104 */
105enum {
106 CT_NS_EXP_NOADDITIONAL = 0x00,
107 CT_NS_EXP_ID_NOT_REG = 0x01,
108 CT_NS_EXP_PN_NOT_REG = 0x02,
109 CT_NS_EXP_NN_NOT_REG = 0x03,
110 CT_NS_EXP_CS_NOT_REG = 0x04,
111 CT_NS_EXP_IPN_NOT_REG = 0x05,
112 CT_NS_EXP_IPA_NOT_REG = 0x06,
113 CT_NS_EXP_FT_NOT_REG = 0x07,
114 CT_NS_EXP_SPN_NOT_REG = 0x08,
115 CT_NS_EXP_SNN_NOT_REG = 0x09,
116 CT_NS_EXP_PT_NOT_REG = 0x0A,
117 CT_NS_EXP_IPP_NOT_REG = 0x0B,
118 CT_NS_EXP_FPN_NOT_REG = 0x0C,
119 CT_NS_EXP_HA_NOT_REG = 0x0D,
120 CT_NS_EXP_FD_NOT_REG = 0x0E,
121 CT_NS_EXP_FF_NOT_REG = 0x0F,
122 CT_NS_EXP_ACCESSDENIED = 0x10,
123 CT_NS_EXP_UNACCEPTABLE_ID = 0x11,
124 CT_NS_EXP_DATABASEEMPTY = 0x12,
125 CT_NS_EXP_NOT_REG_IN_SCOPE = 0x13,
126 CT_NS_EXP_DOM_ID_NOT_PRESENT = 0x14,
127 CT_NS_EXP_PORT_NUM_NOT_PRESENT = 0x15,
128 CT_NS_EXP_NO_DEVICE_ATTACHED = 0x16
129};
130
131/*
132 * defintions for the explanation code for all servers
133 */
134enum {
135 CT_EXP_AUTH_EXCEPTION = 0xF1,
136 CT_EXP_DB_FULL = 0xF2,
137 CT_EXP_DB_EMPTY = 0xF3,
138 CT_EXP_PROCESSING_REQ = 0xF4,
139 CT_EXP_UNABLE_TO_VERIFY_CONN = 0xF5,
140 CT_EXP_DEVICES_NOT_IN_CMN_ZONE = 0xF6
141};
142
143/*
144 * Command codes for Name server
145 */
146enum {
147 GS_GID_PN = 0x0121, /* Get Id on port name */
148 GS_GPN_ID = 0x0112, /* Get port name on ID */
149 GS_GNN_ID = 0x0113, /* Get node name on ID */
150 GS_GID_FT = 0x0171, /* Get Id on FC4 type */
151 GS_GSPN_ID = 0x0118, /* Get symbolic PN on ID */
152 GS_RFT_ID = 0x0217, /* Register fc4type on ID */
153 GS_RSPN_ID = 0x0218, /* Register symbolic PN on ID */
154 GS_RPN_ID = 0x0212, /* Register port name */
155 GS_RNN_ID = 0x0213, /* Register node name */
156 GS_RCS_ID = 0x0214, /* Register class of service */
157 GS_RPT_ID = 0x021A, /* Register port type */
158 GS_GA_NXT = 0x0100, /* Get all next */
159 GS_RFF_ID = 0x021F, /* Register FC4 Feature */
160};
161
162struct fcgs_id_req_s{
163 u32 rsvd:8;
164 u32 dap:24; /* port identifier */
165};
166#define fcgs_gpnid_req_t struct fcgs_id_req_s
167#define fcgs_gnnid_req_t struct fcgs_id_req_s
168#define fcgs_gspnid_req_t struct fcgs_id_req_s
169
170struct fcgs_gidpn_req_s{
171 wwn_t port_name; /* port wwn */
172};
173
174struct fcgs_gidpn_resp_s{
175 u32 rsvd:8;
176 u32 dap:24; /* port identifier */
177};
178
179/**
180 * RFT_ID
181 */
182struct fcgs_rftid_req_s {
183 u32 rsvd:8;
184 u32 dap:24; /* port identifier */
185 u32 fc4_type[8]; /* fc4 types */
186};
187
188/**
189 * RFF_ID : Register FC4 features.
190 */
191
192#define FC_GS_FCP_FC4_FEATURE_INITIATOR 0x02
193#define FC_GS_FCP_FC4_FEATURE_TARGET 0x01
194
195struct fcgs_rffid_req_s{
196 u32 rsvd :8;
197 u32 dap :24; /* port identifier */
198 u32 rsvd1 :16;
199 u32 fc4ftr_bits :8; /* fc4 feature bits */
200 u32 fc4_type :8; /* corresponding FC4 Type */
201};
202
203/**
204 * GID_FT Request
205 */
206struct fcgs_gidft_req_s{
207 u8 reserved;
208 u8 domain_id; /* domain, 0 - all fabric */
209 u8 area_id; /* area, 0 - whole domain */
210 u8 fc4_type; /* FC_TYPE_FCP for SCSI devices */
211}; /* GID_FT Request */
212
213/**
214 * GID_FT Response
215 */
216struct fcgs_gidft_resp_s {
217 u8 last:1; /* last port identifier flag */
218 u8 reserved:7;
219 u32 pid:24; /* port identifier */
220}; /* GID_FT Response */
221
222/**
223 * RSPN_ID
224 */
225struct fcgs_rspnid_req_s{
226 u32 rsvd:8;
227 u32 dap:24; /* port identifier */
228 u8 spn_len; /* symbolic port name length */
229 u8 spn[256]; /* symbolic port name */
230};
231
232/**
233 * RPN_ID
234 */
235struct fcgs_rpnid_req_s{
236 u32 rsvd:8;
237 u32 port_id:24;
238 wwn_t port_name;
239};
240
241/**
242 * RNN_ID
243 */
244struct fcgs_rnnid_req_s{
245 u32 rsvd:8;
246 u32 port_id:24;
247 wwn_t node_name;
248};
249
250/**
251 * RCS_ID
252 */
253struct fcgs_rcsid_req_s{
254 u32 rsvd:8;
255 u32 port_id:24;
256 u32 cos;
257};
258
259/**
260 * RPT_ID
261 */
262struct fcgs_rptid_req_s{
263 u32 rsvd:8;
264 u32 port_id:24;
265 u32 port_type:8;
266 u32 rsvd1:24;
267};
268
269/**
270 * GA_NXT Request
271 */
272struct fcgs_ganxt_req_s{
273 u32 rsvd:8;
274 u32 port_id:24;
275};
276
277/**
278 * GA_NXT Response
279 */
280struct fcgs_ganxt_rsp_s{
281 u32 port_type:8; /* Port Type */
282 u32 port_id:24; /* Port Identifier */
283 wwn_t port_name; /* Port Name */
284 u8 spn_len; /* Length of Symbolic Port Name */
285 char spn[255]; /* Symbolic Port Name */
286 wwn_t node_name; /* Node Name */
287 u8 snn_len; /* Length of Symbolic Node Name */
288 char snn[255]; /* Symbolic Node Name */
289 u8 ipa[8]; /* Initial Process Associator */
290 u8 ip[16]; /* IP Address */
291 u32 cos; /* Class of Service */
292 u32 fc4types[8]; /* FC-4 TYPEs */
293 wwn_t fabric_port_name;
294 /* Fabric Port Name */
295 u32 rsvd:8; /* Reserved */
296 u32 hard_addr:24; /* Hard Address */
297};
298
299/*
300 * Fabric Config Server
301 */
302
303/*
304 * Command codes for Fabric Configuration Server
305 */
306enum {
307 GS_FC_GFN_CMD = 0x0114, /* GS FC Get Fabric Name */
308 GS_FC_GMAL_CMD = 0x0116, /* GS FC GMAL */
309 GS_FC_TRACE_CMD = 0x0400, /* GS FC Trace Route */
310 GS_FC_PING_CMD = 0x0401, /* GS FC Ping */
311};
312
313/*
314 * Source or Destination Port Tags.
315 */
316enum {
317 GS_FTRACE_TAG_NPORT_ID = 1,
318 GS_FTRACE_TAG_NPORT_NAME = 2,
319};
320
321/*
322* Port Value : Could be a Port id or wwn
323 */
324union fcgs_port_val_u{
325 u32 nport_id;
326 wwn_t nport_wwn;
327};
328
329#define GS_FTRACE_MAX_HOP_COUNT 20
330#define GS_FTRACE_REVISION 1
331
332/*
333 * Ftrace Related Structures.
334 */
335
336/*
337 * STR (Switch Trace) Reject Reason Codes. From FC-SW.
338 */
339enum {
340 GS_FTRACE_STR_CMD_COMPLETED_SUCC = 0,
341 GS_FTRACE_STR_CMD_NOT_SUPP_IN_NEXT_SWITCH,
342 GS_FTRACE_STR_NO_RESP_FROM_NEXT_SWITCH,
343 GS_FTRACE_STR_MAX_HOP_CNT_REACHED,
344 GS_FTRACE_STR_SRC_PORT_NOT_FOUND,
345 GS_FTRACE_STR_DST_PORT_NOT_FOUND,
346 GS_FTRACE_STR_DEVICES_NOT_IN_COMMON_ZONE,
347 GS_FTRACE_STR_NO_ROUTE_BW_PORTS,
348 GS_FTRACE_STR_NO_ADDL_EXPLN,
349 GS_FTRACE_STR_FABRIC_BUSY,
350 GS_FTRACE_STR_FABRIC_BUILD_IN_PROGRESS,
351 GS_FTRACE_STR_VENDOR_SPECIFIC_ERR_START = 0xf0,
352 GS_FTRACE_STR_VENDOR_SPECIFIC_ERR_END = 0xff,
353};
354
355/*
356 * Ftrace Request
357 */
358struct fcgs_ftrace_req_s{
359 u32 revision;
360 u16 src_port_tag; /* Source Port tag */
361 u16 src_port_len; /* Source Port len */
362 union fcgs_port_val_u src_port_val; /* Source Port value */
363 u16 dst_port_tag; /* Destination Port tag */
364 u16 dst_port_len; /* Destination Port len */
365 union fcgs_port_val_u dst_port_val; /* Destination Port value */
366 u32 token;
367 u8 vendor_id[8]; /* T10 Vendor Identifier */
368 u8 vendor_info[8]; /* Vendor specific Info */
369 u32 max_hop_cnt; /* Max Hop Count */
370};
371
372/*
373 * Path info structure
374 */
375struct fcgs_ftrace_path_info_s{
376 wwn_t switch_name; /* Switch WWN */
377 u32 domain_id;
378 wwn_t ingress_port_name; /* Ingress ports wwn */
379 u32 ingress_phys_port_num; /* Ingress ports physical port
380 * number
381 */
382 wwn_t egress_port_name; /* Ingress ports wwn */
383 u32 egress_phys_port_num; /* Ingress ports physical port
384 * number
385 */
386};
387
388/*
389 * Ftrace Acc Response
390 */
391struct fcgs_ftrace_resp_s{
392 u32 revision;
393 u32 token;
394 u8 vendor_id[8]; /* T10 Vendor Identifier */
395 u8 vendor_info[8]; /* Vendor specific Info */
396 u32 str_rej_reason_code; /* STR Reject Reason Code */
397 u32 num_path_info_entries; /* No. of path info entries */
398 /*
399 * path info entry/entries.
400 */
401 struct fcgs_ftrace_path_info_s path_info[1];
402
403};
404
405/*
406* Fabric Config Server : FCPing
407 */
408
409/*
410 * FC Ping Request
411 */
412struct fcgs_fcping_req_s{
413 u32 revision;
414 u16 port_tag;
415 u16 port_len; /* Port len */
416 union fcgs_port_val_u port_val; /* Port value */
417 u32 token;
418};
419
420/*
421 * FC Ping Response
422 */
423struct fcgs_fcping_resp_s{
424 u32 token;
425};
426
427/*
428 * Command codes for zone server query.
429 */
430enum {
431 ZS_GZME = 0x0124, /* Get zone member extended */
432};
433
434/*
435 * ZS GZME request
436 */
437#define ZS_GZME_ZNAMELEN 32
438struct zs_gzme_req_s{
439 u8 znamelen;
440 u8 rsvd[3];
441 u8 zname[ZS_GZME_ZNAMELEN];
442};
443
444enum zs_mbr_type{
445 ZS_MBR_TYPE_PWWN = 1,
446 ZS_MBR_TYPE_DOMPORT = 2,
447 ZS_MBR_TYPE_PORTID = 3,
448 ZS_MBR_TYPE_NWWN = 4,
449};
450
451struct zs_mbr_wwn_s{
452 u8 mbr_type;
453 u8 rsvd[3];
454 wwn_t wwn;
455};
456
457struct zs_query_resp_s{
458 u32 nmbrs; /* number of zone members */
459 struct zs_mbr_wwn_s mbr[1];
460};
461
462/*
463 * GMAL Command ( Get ( interconnect Element) Management Address List)
464 * To retrieve the IP Address of a Switch.
465 */
466
467#define CT_GMAL_RESP_PREFIX_TELNET "telnet://"
468#define CT_GMAL_RESP_PREFIX_HTTP "http://"
469
470/* GMAL/GFN request */
471struct fcgs_req_s {
472 wwn_t wwn; /* PWWN/NWWN */
473};
474
475#define fcgs_gmal_req_t struct fcgs_req_s
476#define fcgs_gfn_req_t struct fcgs_req_s
477
478/* Accept Response to GMAL */
479struct fcgs_gmal_resp_s {
480 u32 ms_len; /* Num of entries */
481 u8 ms_ma[256];
482};
483
484struct fc_gmal_entry_s {
485 u8 len;
486 u8 prefix[7]; /* like "http://" */
487 u8 ip_addr[248];
488};
489
490#pragma pack()
491
492#endif
diff --git a/drivers/scsi/bfa/include/protocol/fc.h b/drivers/scsi/bfa/include/protocol/fc.h
new file mode 100644
index 000000000000..3e39ba58cfb5
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/fc.h
@@ -0,0 +1,1105 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __FC_H__
19#define __FC_H__
20
21#include <protocol/types.h>
22
23#pragma pack(1)
24
25/*
26 * Fibre Channel Header Structure (FCHS) definition
27 */
28struct fchs_s {
29#ifdef __BIGENDIAN
30 u32 routing:4; /* routing bits */
31 u32 cat_info:4; /* category info */
32#else
33 u32 cat_info:4; /* category info */
34 u32 routing:4; /* routing bits */
35#endif
36 u32 d_id:24; /* destination identifier */
37
38 u32 cs_ctl:8; /* class specific control */
39 u32 s_id:24; /* source identifier */
40
41 u32 type:8; /* data structure type */
42 u32 f_ctl:24; /* initial frame control */
43
44 u8 seq_id; /* sequence identifier */
45 u8 df_ctl; /* data field control */
46 u16 seq_cnt; /* sequence count */
47
48 u16 ox_id; /* originator exchange ID */
49 u16 rx_id; /* responder exchange ID */
50
51 u32 ro; /* relative offset */
52};
53/*
54 * Fibre Channel BB_E Header Structure
55 */
56struct fcbbehs_s {
57 u16 ver_rsvd;
58 u32 rsvd[2];
59 u32 rsvd__sof;
60};
61
62#define FC_SEQ_ID_MAX 256
63
64/*
65 * routing bit definitions
66 */
67enum {
68 FC_RTG_FC4_DEV_DATA = 0x0, /* FC-4 Device Data */
69 FC_RTG_EXT_LINK = 0x2, /* Extended Link Data */
70 FC_RTG_FC4_LINK_DATA = 0x3, /* FC-4 Link Data */
71 FC_RTG_VIDEO_DATA = 0x4, /* Video Data */
72 FC_RTG_EXT_HDR = 0x5, /* VFT, IFR or Encapsuled */
73 FC_RTG_BASIC_LINK = 0x8, /* Basic Link data */
74 FC_RTG_LINK_CTRL = 0xC, /* Link Control */
75};
76
77/*
78 * information category for extended link data and FC-4 Link Data
79 */
80enum {
81 FC_CAT_LD_REQUEST = 0x2, /* Request */
82 FC_CAT_LD_REPLY = 0x3, /* Reply */
83 FC_CAT_LD_DIAG = 0xF, /* for DIAG use only */
84};
85
86/*
87 * information category for extended headers (VFT, IFR or encapsulation)
88 */
89enum {
90 FC_CAT_VFT_HDR = 0x0, /* Virtual fabric tagging header */
91 FC_CAT_IFR_HDR = 0x1, /* Inter-Fabric routing header */
92 FC_CAT_ENC_HDR = 0x2, /* Encapsulation header */
93};
94
95/*
96 * information category for FC-4 device data
97 */
98enum {
99 FC_CAT_UNCATEG_INFO = 0x0, /* Uncategorized information */
100 FC_CAT_SOLICIT_DATA = 0x1, /* Solicited Data */
101 FC_CAT_UNSOLICIT_CTRL = 0x2, /* Unsolicited Control */
102 FC_CAT_SOLICIT_CTRL = 0x3, /* Solicited Control */
103 FC_CAT_UNSOLICIT_DATA = 0x4, /* Unsolicited Data */
104 FC_CAT_DATA_DESC = 0x5, /* Data Descriptor */
105 FC_CAT_UNSOLICIT_CMD = 0x6, /* Unsolicited Command */
106 FC_CAT_CMD_STATUS = 0x7, /* Command Status */
107};
108
109/*
110 * information category for Link Control
111 */
112enum {
113 FC_CAT_ACK_1 = 0x00,
114 FC_CAT_ACK_0_N = 0x01,
115 FC_CAT_P_RJT = 0x02,
116 FC_CAT_F_RJT = 0x03,
117 FC_CAT_P_BSY = 0x04,
118 FC_CAT_F_BSY_DATA = 0x05,
119 FC_CAT_F_BSY_LINK_CTL = 0x06,
120 FC_CAT_F_LCR = 0x07,
121 FC_CAT_NTY = 0x08,
122 FC_CAT_END = 0x09,
123};
124
125/*
126 * Type Field Definitions. FC-PH Section 18.5 pg. 165
127 */
128enum {
129 FC_TYPE_BLS = 0x0, /* Basic Link Service */
130 FC_TYPE_ELS = 0x1, /* Extended Link Service */
131 FC_TYPE_IP = 0x5, /* IP */
132 FC_TYPE_FCP = 0x8, /* SCSI-FCP */
133 FC_TYPE_GPP = 0x9, /* SCSI_GPP */
134 FC_TYPE_SERVICES = 0x20, /* Fibre Channel Services */
135 FC_TYPE_FC_FSS = 0x22, /* Fabric Switch Services */
136 FC_TYPE_FC_AL = 0x23, /* FC-AL */
137 FC_TYPE_FC_SNMP = 0x24, /* FC-SNMP */
138 FC_TYPE_MAX = 256, /* 256 FC-4 types */
139};
140
141struct fc_fc4types_s{
142 u8 bits[FC_TYPE_MAX / 8];
143};
144
145/*
146 * Frame Control Definitions. FC-PH Table-45. pg. 168
147 */
148enum {
149 FCTL_EC_ORIG = 0x000000, /* exchange originator */
150 FCTL_EC_RESP = 0x800000, /* exchange responder */
151 FCTL_SEQ_INI = 0x000000, /* sequence initiator */
152 FCTL_SEQ_REC = 0x400000, /* sequence recipient */
153 FCTL_FS_EXCH = 0x200000, /* first sequence of xchg */
154 FCTL_LS_EXCH = 0x100000, /* last sequence of xchg */
155 FCTL_END_SEQ = 0x080000, /* last frame of sequence */
156 FCTL_SI_XFER = 0x010000, /* seq initiative transfer */
157 FCTL_RO_PRESENT = 0x000008, /* relative offset present */
158 FCTL_FILLBYTE_MASK = 0x000003 /* , fill byte mask */
159};
160
161/*
162 * Fabric Well Known Addresses
163 */
164enum {
165 FC_MIN_WELL_KNOWN_ADDR = 0xFFFFF0,
166 FC_DOMAIN_CONTROLLER_MASK = 0xFFFC00,
167 FC_ALIAS_SERVER = 0xFFFFF8,
168 FC_MGMT_SERVER = 0xFFFFFA,
169 FC_TIME_SERVER = 0xFFFFFB,
170 FC_NAME_SERVER = 0xFFFFFC,
171 FC_FABRIC_CONTROLLER = 0xFFFFFD,
172 FC_FABRIC_PORT = 0xFFFFFE,
173 FC_BROADCAST_SERVER = 0xFFFFFF
174};
175
176/*
177 * domain/area/port defines
178 */
179#define FC_DOMAIN_MASK 0xFF0000
180#define FC_DOMAIN_SHIFT 16
181#define FC_AREA_MASK 0x00FF00
182#define FC_AREA_SHIFT 8
183#define FC_PORT_MASK 0x0000FF
184#define FC_PORT_SHIFT 0
185
186#define FC_GET_DOMAIN(p) (((p) & FC_DOMAIN_MASK) >> FC_DOMAIN_SHIFT)
187#define FC_GET_AREA(p) (((p) & FC_AREA_MASK) >> FC_AREA_SHIFT)
188#define FC_GET_PORT(p) (((p) & FC_PORT_MASK) >> FC_PORT_SHIFT)
189
190#define FC_DOMAIN_CTRLR(p) (FC_DOMAIN_CONTROLLER_MASK | (FC_GET_DOMAIN(p)))
191
192enum {
193 FC_RXID_ANY = 0xFFFFU,
194};
195
196/*
197 * generic ELS command
198 */
199struct fc_els_cmd_s{
200 u32 els_code:8; /* ELS Command Code */
201 u32 reserved:24;
202};
203
204/*
205 * ELS Command Codes. FC-PH Table-75. pg. 223
206 */
207enum {
208 FC_ELS_LS_RJT = 0x1, /* Link Service Reject. */
209 FC_ELS_ACC = 0x02, /* Accept */
210 FC_ELS_PLOGI = 0x03, /* N_Port Login. */
211 FC_ELS_FLOGI = 0x04, /* F_Port Login. */
212 FC_ELS_LOGO = 0x05, /* Logout. */
213 FC_ELS_ABTX = 0x06, /* Abort Exchange */
214 FC_ELS_RES = 0x08, /* Read Exchange status */
215 FC_ELS_RSS = 0x09, /* Read sequence status block */
216 FC_ELS_RSI = 0x0A, /* Request Sequence Initiative */
217 FC_ELS_ESTC = 0x0C, /* Estimate Credit. */
218 FC_ELS_RTV = 0x0E, /* Read Timeout Value. */
219 FC_ELS_RLS = 0x0F, /* Read Link Status. */
220 FC_ELS_ECHO = 0x10, /* Echo */
221 FC_ELS_TEST = 0x11, /* Test */
222 FC_ELS_RRQ = 0x12, /* Reinstate Recovery Qualifier. */
223 FC_ELS_REC = 0x13, /* Add this for TAPE support in FCR */
224 FC_ELS_PRLI = 0x20, /* Process Login */
225 FC_ELS_PRLO = 0x21, /* Process Logout. */
226 FC_ELS_SCN = 0x22, /* State Change Notification. */
227 FC_ELS_TPRLO = 0x24, /* Third Party Process Logout. */
228 FC_ELS_PDISC = 0x50, /* Discover N_Port Parameters. */
229 FC_ELS_FDISC = 0x51, /* Discover F_Port Parameters. */
230 FC_ELS_ADISC = 0x52, /* Discover Address. */
231 FC_ELS_FAN = 0x60, /* Fabric Address Notification */
232 FC_ELS_RSCN = 0x61, /* Reg State Change Notification */
233 FC_ELS_SCR = 0x62, /* State Change Registration. */
234 FC_ELS_RTIN = 0x77, /* Mangement server request */
235 FC_ELS_RNID = 0x78, /* Mangement server request */
236 FC_ELS_RLIR = 0x79, /* Registered Link Incident Record */
237
238 FC_ELS_RPSC = 0x7D, /* Report Port Speed Capabilities */
239 FC_ELS_QSA = 0x7E, /* Query Security Attributes. Ref FC-SP */
240 FC_ELS_E2E_LBEACON = 0x81,
241 /* End-to-End Link Beacon */
242 FC_ELS_AUTH = 0x90, /* Authentication. Ref FC-SP */
243 FC_ELS_RFCN = 0x97, /* Request Fabric Change Notification. Ref
244 *FC-SP */
245
246};
247
248/*
249 * Version numbers for FC-PH standards,
250 * used in login to indicate what port
251 * supports. See FC-PH-X table 158.
252 */
253enum {
254 FC_PH_VER_4_3 = 0x09,
255 FC_PH_VER_PH_3 = 0x20,
256};
257
258/*
259 * PDU size defines
260 */
261enum {
262 FC_MIN_PDUSZ = 512,
263 FC_MAX_PDUSZ = 2112,
264};
265
266/*
267 * N_Port PLOGI Common Service Parameters.
268 * FC-PH-x. Figure-76. pg. 308.
269 */
270struct fc_plogi_csp_s{
271 u8 verhi; /* FC-PH high version */
272 u8 verlo; /* FC-PH low version */
273 u16 bbcred; /* BB_Credit */
274
275#ifdef __BIGENDIAN
276 u8 ciro:1, /* continuously increasing RO */
277 rro:1, /* random relative offset */
278 npiv_supp:1, /* NPIV supported */
279 port_type:1, /* N_Port/F_port */
280 altbbcred:1, /* alternate BB_Credit */
281 resolution:1, /* ms/ns ED_TOV resolution */
282 vvl_info:1, /* VVL Info included */
283 reserved1:1;
284
285 u8 hg_supp:1,
286 query_dbc:1,
287 security:1,
288 sync_cap:1,
289 r_t_tov:1,
290 dh_dup_supp:1,
291 cisc:1, /* continuously increasing seq count */
292 payload:1;
293#else
294 u8 reserved2:2,
295 resolution:1, /* ms/ns ED_TOV resolution */
296 altbbcred:1, /* alternate BB_Credit */
297 port_type:1, /* N_Port/F_port */
298 npiv_supp:1, /* NPIV supported */
299 rro:1, /* random relative offset */
300 ciro:1; /* continuously increasing RO */
301
302 u8 payload:1,
303 cisc:1, /* continuously increasing seq count */
304 dh_dup_supp:1,
305 r_t_tov:1,
306 sync_cap:1,
307 security:1,
308 query_dbc:1,
309 hg_supp:1;
310#endif
311
312 u16 rxsz; /* recieve data_field size */
313
314 u16 conseq;
315 u16 ro_bitmap;
316
317 u32 e_d_tov;
318};
319
320/*
321 * N_Port PLOGI Class Specific Parameters.
322 * FC-PH-x. Figure 78. pg. 318.
323 */
324struct fc_plogi_clp_s{
325#ifdef __BIGENDIAN
326 u32 class_valid:1;
327 u32 intermix:1; /* class intermix supported if set =1.
328 * valid only for class1. Reserved for
329 * class2 & class3
330 */
331 u32 reserved1:2;
332 u32 sequential:1;
333 u32 reserved2:3;
334#else
335 u32 reserved2:3;
336 u32 sequential:1;
337 u32 reserved1:2;
338 u32 intermix:1; /* class intermix supported if set =1.
339 * valid only for class1. Reserved for
340 * class2 & class3
341 */
342 u32 class_valid:1;
343#endif
344
345 u32 reserved3:24;
346
347 u32 reserved4:16;
348 u32 rxsz:16; /* Receive data_field size */
349
350 u32 reserved5:8;
351 u32 conseq:8;
352 u32 e2e_credit:16; /* end to end credit */
353
354 u32 reserved7:8;
355 u32 ospx:8;
356 u32 reserved8:16;
357};
358
359#define FLOGI_VVL_BRCD 0x42524344 /* ASCII value for each character in
360 * string "BRCD" */
361
362/*
363 * PLOGI els command and reply payload
364 */
365struct fc_logi_s{
366 struct fc_els_cmd_s els_cmd; /* ELS command code */
367 struct fc_plogi_csp_s csp; /* common service params */
368 wwn_t port_name;
369 wwn_t node_name;
370 struct fc_plogi_clp_s class1; /* class 1 service parameters */
371 struct fc_plogi_clp_s class2; /* class 2 service parameters */
372 struct fc_plogi_clp_s class3; /* class 3 service parameters */
373 struct fc_plogi_clp_s class4; /* class 4 service parameters */
374 u8 vvl[16]; /* vendor version level */
375};
376
377/*
378 * LOGO els command payload
379 */
380struct fc_logo_s{
381 struct fc_els_cmd_s els_cmd; /* ELS command code */
382 u32 res1:8;
383 u32 nport_id:24; /* N_Port identifier of source */
384 wwn_t orig_port_name; /* Port name of the LOGO originator */
385};
386
387/*
388 * ADISC els command payload
389 */
390struct fc_adisc_s {
391 struct fc_els_cmd_s els_cmd; /* ELS command code */
392 u32 res1:8;
393 u32 orig_HA:24; /* originator hard address */
394 wwn_t orig_port_name; /* originator port name */
395 wwn_t orig_node_name; /* originator node name */
396 u32 res2:8;
397 u32 nport_id:24; /* originator NPortID */
398};
399
400/*
401 * Exchange status block
402 */
403struct fc_exch_status_blk_s{
404 u32 oxid:16;
405 u32 rxid:16;
406 u32 res1:8;
407 u32 orig_np:24; /* originator NPortID */
408 u32 res2:8;
409 u32 resp_np:24; /* responder NPortID */
410 u32 es_bits;
411 u32 res3;
412 /*
413 * un modified section of the fields
414 */
415};
416
417/*
418 * RES els command payload
419 */
420struct fc_res_s {
421 struct fc_els_cmd_s els_cmd; /* ELS command code */
422 u32 res1:8;
423 u32 nport_id:24; /* N_Port identifier of source */
424 u32 oxid:16;
425 u32 rxid:16;
426 u8 assoc_hdr[32];
427};
428
429/*
430 * RES els accept payload
431 */
432struct fc_res_acc_s{
433 struct fc_els_cmd_s els_cmd; /* ELS command code */
434 struct fc_exch_status_blk_s fc_exch_blk; /* Exchange status block */
435};
436
437/*
438 * REC els command payload
439 */
440struct fc_rec_s {
441 struct fc_els_cmd_s els_cmd; /* ELS command code */
442 u32 res1:8;
443 u32 nport_id:24; /* N_Port identifier of source */
444 u32 oxid:16;
445 u32 rxid:16;
446};
447
448#define FC_REC_ESB_OWN_RSP 0x80000000 /* responder owns */
449#define FC_REC_ESB_SI 0x40000000 /* SI is owned */
450#define FC_REC_ESB_COMP 0x20000000 /* exchange is complete */
451#define FC_REC_ESB_ENDCOND_ABN 0x10000000 /* abnormal ending */
452#define FC_REC_ESB_RQACT 0x04000000 /* recovery qual active */
453#define FC_REC_ESB_ERRP_MSK 0x03000000
454#define FC_REC_ESB_OXID_INV 0x00800000 /* invalid OXID */
455#define FC_REC_ESB_RXID_INV 0x00400000 /* invalid RXID */
456#define FC_REC_ESB_PRIO_INUSE 0x00200000
457
458/*
459 * REC els accept payload
460 */
461struct fc_rec_acc_s {
462 struct fc_els_cmd_s els_cmd; /* ELS command code */
463 u32 oxid:16;
464 u32 rxid:16;
465 u32 res1:8;
466 u32 orig_id:24; /* N_Port id of exchange originator */
467 u32 res2:8;
468 u32 resp_id:24; /* N_Port id of exchange responder */
469 u32 count; /* data transfer count */
470 u32 e_stat; /* exchange status */
471};
472
473/*
474 * RSI els payload
475 */
476struct fc_rsi_s {
477 struct fc_els_cmd_s els_cmd;
478 u32 res1:8;
479 u32 orig_sid:24;
480 u32 oxid:16;
481 u32 rxid:16;
482};
483
484/*
485 * structure for PRLI paramater pages, both request & response
486 * see FC-PH-X table 113 & 115 for explanation also FCP table 8
487 */
488struct fc_prli_params_s{
489 u32 reserved: 16;
490#ifdef __BIGENDIAN
491 u32 reserved1: 5;
492 u32 rec_support : 1;
493 u32 task_retry_id : 1;
494 u32 retry : 1;
495
496 u32 confirm : 1;
497 u32 doverlay:1;
498 u32 initiator:1;
499 u32 target:1;
500 u32 cdmix:1;
501 u32 drmix:1;
502 u32 rxrdisab:1;
503 u32 wxrdisab:1;
504#else
505 u32 retry : 1;
506 u32 task_retry_id : 1;
507 u32 rec_support : 1;
508 u32 reserved1: 5;
509
510 u32 wxrdisab:1;
511 u32 rxrdisab:1;
512 u32 drmix:1;
513 u32 cdmix:1;
514 u32 target:1;
515 u32 initiator:1;
516 u32 doverlay:1;
517 u32 confirm : 1;
518#endif
519};
520
521/*
522 * valid values for rspcode in PRLI ACC payload
523 */
524enum {
525 FC_PRLI_ACC_XQTD = 0x1, /* request executed */
526 FC_PRLI_ACC_PREDEF_IMG = 0x5, /* predefined image - no prli needed */
527};
528
529struct fc_prli_params_page_s{
530 u32 type:8;
531 u32 codext:8;
532#ifdef __BIGENDIAN
533 u32 origprocasv:1;
534 u32 rsppav:1;
535 u32 imagepair:1;
536 u32 reserved1:1;
537 u32 rspcode:4;
538#else
539 u32 rspcode:4;
540 u32 reserved1:1;
541 u32 imagepair:1;
542 u32 rsppav:1;
543 u32 origprocasv:1;
544#endif
545 u32 reserved2:8;
546
547 u32 origprocas;
548 u32 rspprocas;
549 struct fc_prli_params_s servparams;
550};
551
552/*
553 * PRLI request and accept payload, FC-PH-X tables 112 & 114
554 */
555struct fc_prli_s{
556 u32 command:8;
557 u32 pglen:8;
558 u32 pagebytes:16;
559 struct fc_prli_params_page_s parampage;
560};
561
562/*
563 * PRLO logout params page
564 */
565struct fc_prlo_params_page_s{
566 u32 type:8;
567 u32 type_ext:8;
568#ifdef __BIGENDIAN
569 u32 opa_valid:1; /* originator process associator
570 * valid
571 */
572 u32 rpa_valid:1; /* responder process associator valid */
573 u32 res1:14;
574#else
575 u32 res1:14;
576 u32 rpa_valid:1; /* responder process associator valid */
577 u32 opa_valid:1; /* originator process associator
578 * valid
579 */
580#endif
581 u32 orig_process_assc;
582 u32 resp_process_assc;
583
584 u32 res2;
585};
586
587/*
588 * PRLO els command payload
589 */
590struct fc_prlo_s{
591 u32 command:8;
592 u32 page_len:8;
593 u32 payload_len:16;
594 struct fc_prlo_params_page_s prlo_params[1];
595};
596
597/*
598 * PRLO Logout response parameter page
599 */
600struct fc_prlo_acc_params_page_s{
601 u32 type:8;
602 u32 type_ext:8;
603
604#ifdef __BIGENDIAN
605 u32 opa_valid:1; /* originator process associator
606 * valid
607 */
608 u32 rpa_valid:1; /* responder process associator valid */
609 u32 res1:14;
610#else
611 u32 res1:14;
612 u32 rpa_valid:1; /* responder process associator valid */
613 u32 opa_valid:1; /* originator process associator
614 * valid
615 */
616#endif
617 u32 orig_process_assc;
618 u32 resp_process_assc;
619
620 u32 fc4type_csp;
621};
622
623/*
624 * PRLO els command ACC payload
625 */
626struct fc_prlo_acc_s{
627 u32 command:8;
628 u32 page_len:8;
629 u32 payload_len:16;
630 struct fc_prlo_acc_params_page_s prlo_acc_params[1];
631};
632
633/*
634 * SCR els command payload
635 */
636enum {
637 FC_SCR_REG_FUNC_FABRIC_DETECTED = 0x01,
638 FC_SCR_REG_FUNC_N_PORT_DETECTED = 0x02,
639 FC_SCR_REG_FUNC_FULL = 0x03,
640 FC_SCR_REG_FUNC_CLEAR_REG = 0xFF,
641};
642
643/* SCR VU registrations */
644enum {
645 FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE = 0x01
646};
647
648struct fc_scr_s{
649 u32 command:8;
650 u32 res:24;
651 u32 vu_reg_func:8; /* Vendor Unique Registrations */
652 u32 res1:16;
653 u32 reg_func:8;
654};
655
656/*
657 * Information category for Basic link data
658 */
659enum {
660 FC_CAT_NOP = 0x0,
661 FC_CAT_ABTS = 0x1,
662 FC_CAT_RMC = 0x2,
663 FC_CAT_BA_ACC = 0x4,
664 FC_CAT_BA_RJT = 0x5,
665 FC_CAT_PRMT = 0x6,
666};
667
668/*
669 * LS_RJT els reply payload
670 */
671struct fc_ls_rjt_s {
672 struct fc_els_cmd_s els_cmd; /* ELS command code */
673 u32 res1:8;
674 u32 reason_code:8; /* Reason code for reject */
675 u32 reason_code_expl:8; /* Reason code explanation */
676 u32 vendor_unique:8; /* Vendor specific */
677};
678
679/*
680 * LS_RJT reason codes
681 */
682enum {
683 FC_LS_RJT_RSN_INV_CMD_CODE = 0x01,
684 FC_LS_RJT_RSN_LOGICAL_ERROR = 0x03,
685 FC_LS_RJT_RSN_LOGICAL_BUSY = 0x05,
686 FC_LS_RJT_RSN_PROTOCOL_ERROR = 0x07,
687 FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD = 0x09,
688 FC_LS_RJT_RSN_CMD_NOT_SUPP = 0x0B,
689};
690
691/*
692 * LS_RJT reason code explanation
693 */
694enum {
695 FC_LS_RJT_EXP_NO_ADDL_INFO = 0x00,
696 FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS = 0x01,
697 FC_LS_RJT_EXP_SPARMS_ERR_INI_CTL = 0x03,
698 FC_LS_RJT_EXP_SPARMS_ERR_REC_CTL = 0x05,
699 FC_LS_RJT_EXP_SPARMS_ERR_RXSZ = 0x07,
700 FC_LS_RJT_EXP_SPARMS_ERR_CONSEQ = 0x09,
701 FC_LS_RJT_EXP_SPARMS_ERR_CREDIT = 0x0B,
702 FC_LS_RJT_EXP_INV_PORT_NAME = 0x0D,
703 FC_LS_RJT_EXP_INV_NODE_FABRIC_NAME = 0x0E,
704 FC_LS_RJT_EXP_INV_CSP = 0x0F,
705 FC_LS_RJT_EXP_INV_ASSOC_HDR = 0x11,
706 FC_LS_RJT_EXP_ASSOC_HDR_REQD = 0x13,
707 FC_LS_RJT_EXP_INV_ORIG_S_ID = 0x15,
708 FC_LS_RJT_EXP_INV_OXID_RXID_COMB = 0x17,
709 FC_LS_RJT_EXP_CMD_ALREADY_IN_PROG = 0x19,
710 FC_LS_RJT_EXP_LOGIN_REQUIRED = 0x1E,
711 FC_LS_RJT_EXP_INVALID_NPORT_ID = 0x1F,
712 FC_LS_RJT_EXP_INSUFF_RES = 0x29,
713 FC_LS_RJT_EXP_CMD_NOT_SUPP = 0x2C,
714 FC_LS_RJT_EXP_INV_PAYLOAD_LEN = 0x2D,
715};
716
717/*
718 * RRQ els command payload
719 */
720struct fc_rrq_s{
721 struct fc_els_cmd_s els_cmd; /* ELS command code */
722 u32 res1:8;
723 u32 s_id:24; /* exchange originator S_ID */
724
725 u32 ox_id:16; /* originator exchange ID */
726 u32 rx_id:16; /* responder exchange ID */
727
728 u32 res2[8]; /* optional association header */
729};
730
731/*
732 * ABTS BA_ACC reply payload
733 */
734struct fc_ba_acc_s{
735 u32 seq_id_valid:8; /* set to 0x00 for Abort Exchange */
736 u32 seq_id:8; /* invalid for Abort Exchange */
737 u32 res2:16;
738 u32 ox_id:16; /* OX_ID from ABTS frame */
739 u32 rx_id:16; /* RX_ID from ABTS frame */
740 u32 low_seq_cnt:16; /* set to 0x0000 for Abort Exchange */
741 u32 high_seq_cnt:16;/* set to 0xFFFF for Abort Exchange */
742};
743
744/*
745 * ABTS BA_RJT reject payload
746 */
747struct fc_ba_rjt_s{
748 u32 res1:8; /* Reserved */
749 u32 reason_code:8; /* reason code for reject */
750 u32 reason_expl:8; /* reason code explanation */
751 u32 vendor_unique:8;/* vendor unique reason code,set to 0 */
752};
753
754/*
755 * TPRLO logout parameter page
756 */
757struct fc_tprlo_params_page_s{
758 u32 type:8;
759 u32 type_ext:8;
760
761#ifdef __BIGENDIAN
762 u32 opa_valid:1;
763 u32 rpa_valid:1;
764 u32 tpo_nport_valid:1;
765 u32 global_process_logout:1;
766 u32 res1:12;
767#else
768 u32 res1:12;
769 u32 global_process_logout:1;
770 u32 tpo_nport_valid:1;
771 u32 rpa_valid:1;
772 u32 opa_valid:1;
773#endif
774
775 u32 orig_process_assc;
776 u32 resp_process_assc;
777
778 u32 res2:8;
779 u32 tpo_nport_id;
780};
781
782/*
783 * TPRLO ELS command payload
784 */
785struct fc_tprlo_s{
786 u32 command:8;
787 u32 page_len:8;
788 u32 payload_len:16;
789
790 struct fc_tprlo_params_page_s tprlo_params[1];
791};
792
793enum fc_tprlo_type{
794 FC_GLOBAL_LOGO = 1,
795 FC_TPR_LOGO
796};
797
798/*
799 * TPRLO els command ACC payload
800 */
801struct fc_tprlo_acc_s{
802 u32 command:8;
803 u32 page_len:8;
804 u32 payload_len:16;
805 struct fc_prlo_acc_params_page_s tprlo_acc_params[1];
806};
807
808/*
809 * RSCN els command req payload
810 */
811#define FC_RSCN_PGLEN 0x4
812
813enum fc_rscn_format{
814 FC_RSCN_FORMAT_PORTID = 0x0,
815 FC_RSCN_FORMAT_AREA = 0x1,
816 FC_RSCN_FORMAT_DOMAIN = 0x2,
817 FC_RSCN_FORMAT_FABRIC = 0x3,
818};
819
820struct fc_rscn_event_s{
821 u32 format:2;
822 u32 qualifier:4;
823 u32 resvd:2;
824 u32 portid:24;
825};
826
827struct fc_rscn_pl_s{
828 u8 command;
829 u8 pagelen;
830 u16 payldlen;
831 struct fc_rscn_event_s event[1];
832};
833
834/*
835 * ECHO els command req payload
836 */
837struct fc_echo_s {
838 struct fc_els_cmd_s els_cmd;
839};
840
841/*
842 * RNID els command
843 */
844
845#define RNID_NODEID_DATA_FORMAT_COMMON 0x00
846#define RNID_NODEID_DATA_FORMAT_FCP3 0x08
847#define RNID_NODEID_DATA_FORMAT_DISCOVERY 0xDF
848
849#define RNID_ASSOCIATED_TYPE_UNKNOWN 0x00000001
850#define RNID_ASSOCIATED_TYPE_OTHER 0x00000002
851#define RNID_ASSOCIATED_TYPE_HUB 0x00000003
852#define RNID_ASSOCIATED_TYPE_SWITCH 0x00000004
853#define RNID_ASSOCIATED_TYPE_GATEWAY 0x00000005
854#define RNID_ASSOCIATED_TYPE_STORAGE_DEVICE 0x00000009
855#define RNID_ASSOCIATED_TYPE_HOST 0x0000000A
856#define RNID_ASSOCIATED_TYPE_STORAGE_SUBSYSTEM 0x0000000B
857#define RNID_ASSOCIATED_TYPE_STORAGE_ACCESS_DEVICE 0x0000000E
858#define RNID_ASSOCIATED_TYPE_NAS_SERVER 0x00000011
859#define RNID_ASSOCIATED_TYPE_BRIDGE 0x00000002
860#define RNID_ASSOCIATED_TYPE_VIRTUALIZATION_DEVICE 0x00000003
861#define RNID_ASSOCIATED_TYPE_MULTI_FUNCTION_DEVICE 0x000000FF
862
863/*
864 * RNID els command payload
865 */
866struct fc_rnid_cmd_s{
867 struct fc_els_cmd_s els_cmd;
868 u32 node_id_data_format:8;
869 u32 reserved:24;
870};
871
872/*
873 * RNID els response payload
874 */
875
876struct fc_rnid_common_id_data_s{
877 wwn_t port_name;
878 wwn_t node_name;
879};
880
881struct fc_rnid_general_topology_data_s{
882 u32 vendor_unique[4];
883 u32 asso_type;
884 u32 phy_port_num;
885 u32 num_attached_nodes;
886 u32 node_mgmt:8;
887 u32 ip_version:8;
888 u32 udp_tcp_port_num:16;
889 u32 ip_address[4];
890 u32 reserved:16;
891 u32 vendor_specific:16;
892};
893
894struct fc_rnid_acc_s{
895 struct fc_els_cmd_s els_cmd;
896 u32 node_id_data_format:8;
897 u32 common_id_data_length:8;
898 u32 reserved:8;
899 u32 specific_id_data_length:8;
900 struct fc_rnid_common_id_data_s common_id_data;
901 struct fc_rnid_general_topology_data_s gen_topology_data;
902};
903
904#define RNID_ASSOCIATED_TYPE_UNKNOWN 0x00000001
905#define RNID_ASSOCIATED_TYPE_OTHER 0x00000002
906#define RNID_ASSOCIATED_TYPE_HUB 0x00000003
907#define RNID_ASSOCIATED_TYPE_SWITCH 0x00000004
908#define RNID_ASSOCIATED_TYPE_GATEWAY 0x00000005
909#define RNID_ASSOCIATED_TYPE_STORAGE_DEVICE 0x00000009
910#define RNID_ASSOCIATED_TYPE_HOST 0x0000000A
911#define RNID_ASSOCIATED_TYPE_STORAGE_SUBSYSTEM 0x0000000B
912#define RNID_ASSOCIATED_TYPE_STORAGE_ACCESS_DEVICE 0x0000000E
913#define RNID_ASSOCIATED_TYPE_NAS_SERVER 0x00000011
914#define RNID_ASSOCIATED_TYPE_BRIDGE 0x00000002
915#define RNID_ASSOCIATED_TYPE_VIRTUALIZATION_DEVICE 0x00000003
916#define RNID_ASSOCIATED_TYPE_MULTI_FUNCTION_DEVICE 0x000000FF
917
918enum fc_rpsc_speed_cap{
919 RPSC_SPEED_CAP_1G = 0x8000,
920 RPSC_SPEED_CAP_2G = 0x4000,
921 RPSC_SPEED_CAP_4G = 0x2000,
922 RPSC_SPEED_CAP_10G = 0x1000,
923 RPSC_SPEED_CAP_8G = 0x0800,
924 RPSC_SPEED_CAP_16G = 0x0400,
925
926 RPSC_SPEED_CAP_UNKNOWN = 0x0001,
927};
928
929enum fc_rpsc_op_speed_s{
930 RPSC_OP_SPEED_1G = 0x8000,
931 RPSC_OP_SPEED_2G = 0x4000,
932 RPSC_OP_SPEED_4G = 0x2000,
933 RPSC_OP_SPEED_10G = 0x1000,
934 RPSC_OP_SPEED_8G = 0x0800,
935 RPSC_OP_SPEED_16G = 0x0400,
936
937 RPSC_OP_SPEED_NOT_EST = 0x0001, /*! speed not established */
938};
939
940struct fc_rpsc_speed_info_s{
941 u16 port_speed_cap; /*! see fc_rpsc_speed_cap_t */
942 u16 port_op_speed; /*! see fc_rpsc_op_speed_t */
943};
944
945enum link_e2e_beacon_subcmd{
946 LINK_E2E_BEACON_ON = 1,
947 LINK_E2E_BEACON_OFF = 2
948};
949
950enum beacon_type{
951 BEACON_TYPE_NORMAL = 1, /*! Normal Beaconing. Green */
952 BEACON_TYPE_WARN = 2, /*! Warning Beaconing. Yellow/Amber */
953 BEACON_TYPE_CRITICAL = 3 /*! Critical Beaconing. Red */
954};
955
956struct link_e2e_beacon_param_s {
957 u8 beacon_type; /* Beacon Type. See beacon_type_t */
958 u8 beacon_frequency;
959 /* Beacon frequency. Number of blinks
960 * per 10 seconds
961 */
962 u16 beacon_duration;/* Beacon duration (in Seconds). The
963 * command operation should be
964 * terminated at the end of this
965 * timeout value.
966 *
967 * Ignored if diag_sub_cmd is
968 * LINK_E2E_BEACON_OFF.
969 *
970 * If 0, beaconing will continue till a
971 * BEACON OFF request is received
972 */
973};
974
975/*
976 * Link E2E beacon request/good response format. For LS_RJTs use fc_ls_rjt_t
977 */
978struct link_e2e_beacon_req_s{
979 u32 ls_code; /*! FC_ELS_E2E_LBEACON in requests *
980 *or FC_ELS_ACC in good replies */
981 u32 ls_sub_cmd; /*! See link_e2e_beacon_subcmd_t */
982 struct link_e2e_beacon_param_s beacon_parm;
983};
984
985/**
986 * If RPSC request is sent to the Domain Controller, the request is for
987 * all the ports within that domain (TODO - I don't think FOS implements
988 * this...).
989 */
990struct fc_rpsc_cmd_s{
991 struct fc_els_cmd_s els_cmd;
992};
993
994/*
995 * RPSC Acc
996 */
997struct fc_rpsc_acc_s{
998 u32 command:8;
999 u32 rsvd:8;
1000 u32 num_entries:16;
1001
1002 struct fc_rpsc_speed_info_s speed_info[1];
1003};
1004
1005/**
1006 * If RPSC2 request is sent to the Domain Controller,
1007 */
1008#define FC_BRCD_TOKEN 0x42524344
1009
1010struct fc_rpsc2_cmd_s{
1011 struct fc_els_cmd_s els_cmd;
1012 u32 token;
1013 u16 resvd;
1014 u16 num_pids; /* Number of pids in the request */
1015 struct {
1016 u32 rsvd1:8;
1017 u32 pid:24; /* port identifier */
1018 } pid_list[1];
1019};
1020
1021enum fc_rpsc2_port_type{
1022 RPSC2_PORT_TYPE_UNKNOWN = 0,
1023 RPSC2_PORT_TYPE_NPORT = 1,
1024 RPSC2_PORT_TYPE_NLPORT = 2,
1025 RPSC2_PORT_TYPE_NPIV_PORT = 0x5f,
1026 RPSC2_PORT_TYPE_NPORT_TRUNK = 0x6f,
1027};
1028
1029/*
1030 * RPSC2 portInfo entry structure
1031 */
1032struct fc_rpsc2_port_info_s{
1033 u32 pid; /* PID */
1034 u16 resvd1;
1035 u16 index; /* port number / index */
1036 u8 resvd2;
1037 u8 type; /* port type N/NL/... */
1038 u16 speed; /* port Operating Speed */
1039};
1040
1041/*
1042 * RPSC2 Accept payload
1043 */
1044struct fc_rpsc2_acc_s{
1045 u8 els_cmd;
1046 u8 resvd;
1047 u16 num_pids; /* Number of pids in the request */
1048 struct fc_rpsc2_port_info_s port_info[1]; /* port information */
1049};
1050
1051/**
1052 * bit fields so that multiple classes can be specified
1053 */
1054enum fc_cos{
1055 FC_CLASS_2 = 0x04,
1056 FC_CLASS_3 = 0x08,
1057 FC_CLASS_2_3 = 0x0C,
1058};
1059
1060/*
1061 * symbolic name
1062 */
1063struct fc_symname_s{
1064 u8 symname[FC_SYMNAME_MAX];
1065};
1066
1067struct fc_alpabm_s{
1068 u8 alpa_bm[FC_ALPA_MAX / 8];
1069};
1070
1071/*
1072 * protocol default timeout values
1073 */
1074#define FC_ED_TOV 2
1075#define FC_REC_TOV (FC_ED_TOV + 1)
1076#define FC_RA_TOV 10
1077#define FC_ELS_TOV (2 * FC_RA_TOV)
1078
1079/*
1080 * virtual fabric related defines
1081 */
1082#define FC_VF_ID_NULL 0 /* must not be used as VF_ID */
1083#define FC_VF_ID_MIN 1
1084#define FC_VF_ID_MAX 0xEFF
1085#define FC_VF_ID_CTL 0xFEF /* control VF_ID */
1086
1087/**
1088 * Virtual Fabric Tagging header format
1089 * @caution This is defined only in BIG ENDIAN format.
1090 */
1091struct fc_vft_s{
1092 u32 r_ctl:8;
1093 u32 ver:2;
1094 u32 type:4;
1095 u32 res_a:2;
1096 u32 priority:3;
1097 u32 vf_id:12;
1098 u32 res_b:1;
1099 u32 hopct:8;
1100 u32 res_c:24;
1101};
1102
1103#pragma pack()
1104
1105#endif
diff --git a/drivers/scsi/bfa/include/protocol/fc_sp.h b/drivers/scsi/bfa/include/protocol/fc_sp.h
new file mode 100644
index 000000000000..55bb0b31d04b
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/fc_sp.h
@@ -0,0 +1,224 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __FC_SP_H__
19#define __FC_SP_H__
20
21#include <protocol/types.h>
22
23#pragma pack(1)
24
25enum auth_els_flags{
26 FC_AUTH_ELS_MORE_FRAGS_FLAG = 0x80, /*! bit-7. More Fragments
27 * Follow
28 */
29 FC_AUTH_ELS_CONCAT_FLAG = 0x40, /*! bit-6. Concatenation Flag */
30 FC_AUTH_ELS_SEQ_NUM_FLAG = 0x01 /*! bit-0. Sequence Number */
31};
32
33enum auth_msg_codes{
34 FC_AUTH_MC_AUTH_RJT = 0x0A, /*! Auth Reject */
35 FC_AUTH_MC_AUTH_NEG = 0x0B, /*! Auth Negotiate */
36 FC_AUTH_MC_AUTH_DONE = 0x0C, /*! Auth Done */
37
38 FC_AUTH_MC_DHCHAP_CHAL = 0x10, /*! DHCHAP Challenge */
39 FC_AUTH_MC_DHCHAP_REPLY = 0x11, /*! DHCHAP Reply */
40 FC_AUTH_MC_DHCHAP_SUCC = 0x12, /*! DHCHAP Success */
41
42 FC_AUTH_MC_FCAP_REQ = 0x13, /*! FCAP Request */
43 FC_AUTH_MC_FCAP_ACK = 0x14, /*! FCAP Acknowledge */
44 FC_AUTH_MC_FCAP_CONF = 0x15, /*! FCAP Confirm */
45
46 FC_AUTH_MC_FCPAP_INIT = 0x16, /*! FCPAP Init */
47 FC_AUTH_MC_FCPAP_ACC = 0x17, /*! FCPAP Accept */
48 FC_AUTH_MC_FCPAP_COMP = 0x18, /*! FCPAP Complete */
49
50 FC_AUTH_MC_IKE_SA_INIT = 0x22, /*! IKE SA INIT */
51 FC_AUTH_MC_IKE_SA_AUTH = 0x23, /*! IKE SA Auth */
52 FC_AUTH_MC_IKE_CREATE_CHILD_SA = 0x24, /*! IKE Create Child SA */
53 FC_AUTH_MC_IKE_INFO = 0x25, /*! IKE informational */
54};
55
56enum auth_proto_version{
57 FC_AUTH_PROTO_VER_1 = 1, /*! Protocol Version 1 */
58};
59
60enum {
61 FC_AUTH_ELS_COMMAND_CODE = 0x90,/*! Authentication ELS Command code */
62 FC_AUTH_PROTO_PARAM_LEN_SZ = 4, /*! Size of Proto Parameter Len Field */
63 FC_AUTH_PROTO_PARAM_VAL_SZ = 4, /*! Size of Proto Parameter Val Field */
64 FC_MAX_AUTH_SECRET_LEN = 256,
65 /*! Maximum secret string length */
66 FC_AUTH_NUM_USABLE_PROTO_LEN_SZ = 4,
67 /*! Size of usable protocols field */
68 FC_AUTH_RESP_VALUE_LEN_SZ = 4,
69 /*! Size of response value length */
70 FC_MAX_CHAP_KEY_LEN = 256, /*! Maximum md5 digest length */
71 FC_MAX_AUTH_RETRIES = 3, /*! Maximum number of retries */
72 FC_MD5_DIGEST_LEN = 16, /*! MD5 digest length */
73 FC_SHA1_DIGEST_LEN = 20, /*! SHA1 digest length */
74 FC_MAX_DHG_SUPPORTED = 1, /*! Maximum DH Groups supported */
75 FC_MAX_ALG_SUPPORTED = 1, /*! Maximum algorithms supported */
76 FC_MAX_PROTO_SUPPORTED = 1, /*! Maximum protocols supported */
77 FC_START_TXN_ID = 2, /*! Starting transaction ID */
78};
79
80enum auth_proto_id{
81 FC_AUTH_PROTO_DHCHAP = 0x00000001,
82 FC_AUTH_PROTO_FCAP = 0x00000002,
83 FC_AUTH_PROTO_FCPAP = 0x00000003,
84 FC_AUTH_PROTO_IKEv2 = 0x00000004,
85 FC_AUTH_PROTO_IKEv2_AUTH = 0x00000005,
86};
87
88struct auth_name_s{
89 u16 name_tag; /*! Name Tag = 1 for Authentication */
90 u16 name_len; /*! Name Length = 8 for Authentication
91 */
92 wwn_t name; /*! Name. TODO - is this PWWN */
93};
94
95
96enum auth_hash_func{
97 FC_AUTH_HASH_FUNC_MD5 = 0x00000005,
98 FC_AUTH_HASH_FUNC_SHA_1 = 0x00000006,
99};
100
101enum auth_dh_gid{
102 FC_AUTH_DH_GID_0_DHG_NULL = 0x00000000,
103 FC_AUTH_DH_GID_1_DHG_1024 = 0x00000001,
104 FC_AUTH_DH_GID_2_DHG_1280 = 0x00000002,
105 FC_AUTH_DH_GID_3_DHG_1536 = 0x00000003,
106 FC_AUTH_DH_GID_4_DHG_2048 = 0x00000004,
107 FC_AUTH_DH_GID_6_DHG_3072 = 0x00000006,
108 FC_AUTH_DH_GID_7_DHG_4096 = 0x00000007,
109 FC_AUTH_DH_GID_8_DHG_6144 = 0x00000008,
110 FC_AUTH_DH_GID_9_DHG_8192 = 0x00000009,
111};
112
113struct auth_els_msg_s {
114 u8 auth_els_code; /* Authentication ELS Code (0x90) */
115 u8 auth_els_flag; /* Authentication ELS Flags */
116 u8 auth_msg_code; /* Authentication Message Code */
117 u8 proto_version; /* Protocol Version */
118 u32 msg_len; /* Message Length */
119 u32 trans_id; /* Transaction Identifier (T_ID) */
120
121 /* Msg payload follows... */
122};
123
124
125enum auth_neg_param_tags {
126 FC_AUTH_NEG_DHCHAP_HASHLIST = 0x0001,
127 FC_AUTH_NEG_DHCHAP_DHG_ID_LIST = 0x0002,
128};
129
130
131struct dhchap_param_format_s {
132 u16 tag; /*! Parameter Tag. See
133 * auth_neg_param_tags_t
134 */
135 u16 word_cnt;
136
137 /* followed by variable length parameter value... */
138};
139
140struct auth_proto_params_s {
141 u32 proto_param_len;
142 u32 proto_id;
143
144 /*
145 * Followed by variable length Protocol specific parameters. DH-CHAP
146 * uses dhchap_param_format_t
147 */
148};
149
150struct auth_neg_msg_s {
151 struct auth_name_s auth_ini_name;
152 u32 usable_auth_protos;
153 struct auth_proto_params_s proto_params[1]; /*! (1..usable_auth_proto)
154 * protocol params
155 */
156};
157
158struct auth_dh_val_s {
159 u32 dh_val_len;
160 u32 dh_val[1];
161};
162
163struct auth_dhchap_chal_msg_s {
164 struct auth_els_msg_s hdr;
165 struct auth_name_s auth_responder_name; /* TODO VRK - is auth_name_t
166 * type OK?
167 */
168 u32 hash_id;
169 u32 dh_grp_id;
170 u32 chal_val_len;
171 char chal_val[1];
172
173 /* ...followed by variable Challenge length/value and DH length/value */
174};
175
176
177enum auth_rjt_codes {
178 FC_AUTH_RJT_CODE_AUTH_FAILURE = 0x01,
179 FC_AUTH_RJT_CODE_LOGICAL_ERR = 0x02,
180};
181
182enum auth_rjt_code_exps {
183 FC_AUTH_CEXP_AUTH_MECH_NOT_USABLE = 0x01,
184 FC_AUTH_CEXP_DH_GROUP_NOT_USABLE = 0x02,
185 FC_AUTH_CEXP_HASH_FUNC_NOT_USABLE = 0x03,
186 FC_AUTH_CEXP_AUTH_XACT_STARTED = 0x04,
187 FC_AUTH_CEXP_AUTH_FAILED = 0x05,
188 FC_AUTH_CEXP_INCORRECT_PLD = 0x06,
189 FC_AUTH_CEXP_INCORRECT_PROTO_MSG = 0x07,
190 FC_AUTH_CEXP_RESTART_AUTH_PROTO = 0x08,
191 FC_AUTH_CEXP_AUTH_CONCAT_NOT_SUPP = 0x09,
192 FC_AUTH_CEXP_PROTO_VER_NOT_SUPP = 0x0A,
193};
194
195enum auth_status {
196 FC_AUTH_STATE_INPROGRESS = 0, /*! authentication in progress */
197 FC_AUTH_STATE_FAILED = 1, /*! authentication failed */
198 FC_AUTH_STATE_SUCCESS = 2 /*! authentication successful */
199};
200
201struct auth_rjt_msg_s {
202 struct auth_els_msg_s hdr;
203 u8 reason_code;
204 u8 reason_code_exp;
205 u8 rsvd[2];
206};
207
208
209struct auth_dhchap_neg_msg_s {
210 struct auth_els_msg_s hdr;
211 struct auth_neg_msg_s nego;
212};
213
214struct auth_dhchap_reply_msg_s {
215 struct auth_els_msg_s hdr;
216
217 /*
218 * followed by response value length & Value + DH Value Length & Value
219 */
220};
221
222#pragma pack()
223
224#endif /* __FC_SP_H__ */
diff --git a/drivers/scsi/bfa/include/protocol/fcp.h b/drivers/scsi/bfa/include/protocol/fcp.h
new file mode 100644
index 000000000000..9ade68ad2853
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/fcp.h
@@ -0,0 +1,186 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __FCPPROTO_H__
19#define __FCPPROTO_H__
20
21#include <protocol/scsi.h>
22
23#pragma pack(1)
24
25enum {
26 FCP_RJT = 0x01000000, /* SRR reject */
27 FCP_SRR_ACCEPT = 0x02000000, /* SRR accept */
28 FCP_SRR = 0x14000000, /* Sequence Retransmission Request */
29};
30
31/*
32 * SRR FC-4 LS payload
33 */
34struct fc_srr_s{
35 u32 ls_cmd;
36 u32 ox_id:16; /* ox-id */
37 u32 rx_id:16; /* rx-id */
38 u32 ro; /* relative offset */
39 u32 r_ctl:8; /* R_CTL for I.U. */
40 u32 res:24;
41};
42
43
44/*
45 * FCP_CMND definitions
46 */
47#define FCP_CMND_CDB_LEN 16
48#define FCP_CMND_LUN_LEN 8
49
50struct fcp_cmnd_s{
51 lun_t lun; /* 64-bit LU number */
52 u8 crn; /* command reference number */
53#ifdef __BIGENDIAN
54 u8 resvd:1,
55 priority:4, /* FCP-3: SAM-3 priority */
56 taskattr:3; /* scsi task attribute */
57#else
58 u8 taskattr:3, /* scsi task attribute */
59 priority:4, /* FCP-3: SAM-3 priority */
60 resvd:1;
61#endif
62 u8 tm_flags; /* task management flags */
63#ifdef __BIGENDIAN
64 u8 addl_cdb_len:6, /* additional CDB length words */
65 iodir:2; /* read/write FCP_DATA IUs */
66#else
67 u8 iodir:2, /* read/write FCP_DATA IUs */
68 addl_cdb_len:6; /* additional CDB length */
69#endif
70 struct scsi_cdb_s cdb;
71
72 /*
73 * !!! additional cdb bytes follows here!!!
74 */
75 u32 fcp_dl; /* bytes to be transferred */
76};
77
78#define fcp_cmnd_cdb_len(_cmnd) ((_cmnd)->addl_cdb_len * 4 + FCP_CMND_CDB_LEN)
79#define fcp_cmnd_fcpdl(_cmnd) ((&(_cmnd)->fcp_dl)[(_cmnd)->addl_cdb_len])
80
81/*
82 * fcp_cmnd_t.iodir field values
83 */
84enum fcp_iodir{
85 FCP_IODIR_NONE = 0,
86 FCP_IODIR_WRITE = 1,
87 FCP_IODIR_READ = 2,
88 FCP_IODIR_RW = 3,
89};
90
91/*
92 * Task attribute field
93 */
94enum {
95 FCP_TASK_ATTR_SIMPLE = 0,
96 FCP_TASK_ATTR_HOQ = 1,
97 FCP_TASK_ATTR_ORDERED = 2,
98 FCP_TASK_ATTR_ACA = 4,
99 FCP_TASK_ATTR_UNTAGGED = 5, /* obsolete in FCP-3 */
100};
101
102/*
103 * Task management flags field - only one bit shall be set
104 */
105#ifndef BIT
106#define BIT(_x) (1 << (_x))
107#endif
108enum fcp_tm_cmnd{
109 FCP_TM_ABORT_TASK_SET = BIT(1),
110 FCP_TM_CLEAR_TASK_SET = BIT(2),
111 FCP_TM_LUN_RESET = BIT(4),
112 FCP_TM_TARGET_RESET = BIT(5), /* obsolete in FCP-3 */
113 FCP_TM_CLEAR_ACA = BIT(6),
114};
115
116/*
117 * FCP_XFER_RDY IU defines
118 */
119struct fcp_xfer_rdy_s{
120 u32 data_ro;
121 u32 burst_len;
122 u32 reserved;
123};
124
125/*
126 * FCP_RSP residue flags
127 */
128enum fcp_residue{
129 FCP_NO_RESIDUE = 0, /* no residue */
130 FCP_RESID_OVER = 1, /* more data left that was not sent */
131 FCP_RESID_UNDER = 2, /* less data than requested */
132};
133
134enum {
135 FCP_RSPINFO_GOOD = 0,
136 FCP_RSPINFO_DATALEN_MISMATCH = 1,
137 FCP_RSPINFO_CMND_INVALID = 2,
138 FCP_RSPINFO_ROLEN_MISMATCH = 3,
139 FCP_RSPINFO_TM_NOT_SUPP = 4,
140 FCP_RSPINFO_TM_FAILED = 5,
141};
142
143struct fcp_rspinfo_s{
144 u32 res0:24;
145 u32 rsp_code:8; /* response code (as above) */
146 u32 res1;
147};
148
149struct fcp_resp_s{
150 u32 reserved[2]; /* 2 words reserved */
151 u16 reserved2;
152#ifdef __BIGENDIAN
153 u8 reserved3:3;
154 u8 fcp_conf_req:1; /* FCP_CONF is requested */
155 u8 resid_flags:2; /* underflow/overflow */
156 u8 sns_len_valid:1;/* sense len is valid */
157 u8 rsp_len_valid:1;/* response len is valid */
158#else
159 u8 rsp_len_valid:1;/* response len is valid */
160 u8 sns_len_valid:1;/* sense len is valid */
161 u8 resid_flags:2; /* underflow/overflow */
162 u8 fcp_conf_req:1; /* FCP_CONF is requested */
163 u8 reserved3:3;
164#endif
165 u8 scsi_status; /* one byte SCSI status */
166 u32 residue; /* residual data bytes */
167 u32 sns_len; /* length od sense info */
168 u32 rsp_len; /* length of response info */
169};
170
171#define fcp_snslen(__fcprsp) ((__fcprsp)->sns_len_valid ? \
172 (__fcprsp)->sns_len : 0)
173#define fcp_rsplen(__fcprsp) ((__fcprsp)->rsp_len_valid ? \
174 (__fcprsp)->rsp_len : 0)
175#define fcp_rspinfo(__fcprsp) ((struct fcp_rspinfo_s *)((__fcprsp) + 1))
176#define fcp_snsinfo(__fcprsp) (((u8 *)fcp_rspinfo(__fcprsp)) + \
177 fcp_rsplen(__fcprsp))
178
179struct fcp_cmnd_fr_s{
180 struct fchs_s fchs;
181 struct fcp_cmnd_s fcp;
182};
183
184#pragma pack()
185
186#endif
diff --git a/drivers/scsi/bfa/include/protocol/fdmi.h b/drivers/scsi/bfa/include/protocol/fdmi.h
new file mode 100644
index 000000000000..6c05c268c71b
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/fdmi.h
@@ -0,0 +1,163 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __FDMI_H__
19#define __FDMI_H__
20
21#include <protocol/types.h>
22#include <protocol/fc.h>
23#include <protocol/ct.h>
24
25#pragma pack(1)
26
27/*
28 * FDMI Command Codes
29 */
30#define FDMI_GRHL 0x0100
31#define FDMI_GHAT 0x0101
32#define FDMI_GRPL 0x0102
33#define FDMI_GPAT 0x0110
34#define FDMI_RHBA 0x0200
35#define FDMI_RHAT 0x0201
36#define FDMI_RPRT 0x0210
37#define FDMI_RPA 0x0211
38#define FDMI_DHBA 0x0300
39#define FDMI_DPRT 0x0310
40
41/*
42 * FDMI reason codes
43 */
44#define FDMI_NO_ADDITIONAL_EXP 0x00
45#define FDMI_HBA_ALREADY_REG 0x10
46#define FDMI_HBA_ATTRIB_NOT_REG 0x11
47#define FDMI_HBA_ATTRIB_MULTIPLE 0x12
48#define FDMI_HBA_ATTRIB_LENGTH_INVALID 0x13
49#define FDMI_HBA_ATTRIB_NOT_PRESENT 0x14
50#define FDMI_PORT_ORIG_NOT_IN_LIST 0x15
51#define FDMI_PORT_HBA_NOT_IN_LIST 0x16
52#define FDMI_PORT_ATTRIB_NOT_REG 0x20
53#define FDMI_PORT_NOT_REG 0x21
54#define FDMI_PORT_ATTRIB_MULTIPLE 0x22
55#define FDMI_PORT_ATTRIB_LENGTH_INVALID 0x23
56#define FDMI_PORT_ALREADY_REGISTEREED 0x24
57
58/*
59 * FDMI Transmission Speed Mask values
60 */
61#define FDMI_TRANS_SPEED_1G 0x00000001
62#define FDMI_TRANS_SPEED_2G 0x00000002
63#define FDMI_TRANS_SPEED_10G 0x00000004
64#define FDMI_TRANS_SPEED_4G 0x00000008
65#define FDMI_TRANS_SPEED_8G 0x00000010
66#define FDMI_TRANS_SPEED_16G 0x00000020
67#define FDMI_TRANS_SPEED_UNKNOWN 0x00008000
68
69/*
70 * FDMI HBA attribute types
71 */
72enum fdmi_hba_attribute_type {
73 FDMI_HBA_ATTRIB_NODENAME = 1, /* 0x0001 */
74 FDMI_HBA_ATTRIB_MANUFACTURER, /* 0x0002 */
75 FDMI_HBA_ATTRIB_SERIALNUM, /* 0x0003 */
76 FDMI_HBA_ATTRIB_MODEL, /* 0x0004 */
77 FDMI_HBA_ATTRIB_MODEL_DESC, /* 0x0005 */
78 FDMI_HBA_ATTRIB_HW_VERSION, /* 0x0006 */
79 FDMI_HBA_ATTRIB_DRIVER_VERSION, /* 0x0007 */
80 FDMI_HBA_ATTRIB_ROM_VERSION, /* 0x0008 */
81 FDMI_HBA_ATTRIB_FW_VERSION, /* 0x0009 */
82 FDMI_HBA_ATTRIB_OS_NAME, /* 0x000A */
83 FDMI_HBA_ATTRIB_MAX_CT, /* 0x000B */
84
85 FDMI_HBA_ATTRIB_MAX_TYPE
86};
87
88/*
89 * FDMI Port attribute types
90 */
91enum fdmi_port_attribute_type {
92 FDMI_PORT_ATTRIB_FC4_TYPES = 1, /* 0x0001 */
93 FDMI_PORT_ATTRIB_SUPP_SPEED, /* 0x0002 */
94 FDMI_PORT_ATTRIB_PORT_SPEED, /* 0x0003 */
95 FDMI_PORT_ATTRIB_FRAME_SIZE, /* 0x0004 */
96 FDMI_PORT_ATTRIB_DEV_NAME, /* 0x0005 */
97 FDMI_PORT_ATTRIB_HOST_NAME, /* 0x0006 */
98
99 FDMI_PORT_ATTR_MAX_TYPE
100};
101
102/*
103 * FDMI attribute
104 */
105struct fdmi_attr_s {
106 u16 type;
107 u16 len;
108 u8 value[1];
109};
110
111/*
112 * HBA Attribute Block
113 */
114struct fdmi_hba_attr_s {
115 u32 attr_count; /* # of attributes */
116 struct fdmi_attr_s hba_attr; /* n attributes */
117};
118
119/*
120 * Registered Port List
121 */
122struct fdmi_port_list_s {
123 u32 num_ports; /* number Of Port Entries */
124 wwn_t port_entry; /* one or more */
125};
126
127/*
128 * Port Attribute Block
129 */
130struct fdmi_port_attr_s {
131 u32 attr_count; /* # of attributes */
132 struct fdmi_attr_s port_attr; /* n attributes */
133};
134
135/*
136 * FDMI Register HBA Attributes
137 */
138struct fdmi_rhba_s {
139 wwn_t hba_id; /* HBA Identifier */
140 struct fdmi_port_list_s port_list; /* Registered Port List */
141 struct fdmi_hba_attr_s hba_attr_blk; /* HBA attribute block */
142};
143
144/*
145 * FDMI Register Port
146 */
147struct fdmi_rprt_s {
148 wwn_t hba_id; /* HBA Identifier */
149 wwn_t port_name; /* Port wwn */
150 struct fdmi_port_attr_s port_attr_blk; /* Port Attr Block */
151};
152
153/*
154 * FDMI Register Port Attributes
155 */
156struct fdmi_rpa_s {
157 wwn_t port_name; /* port wwn */
158 struct fdmi_port_attr_s port_attr_blk; /* Port Attr Block */
159};
160
161#pragma pack()
162
163#endif
diff --git a/drivers/scsi/bfa/include/protocol/pcifw.h b/drivers/scsi/bfa/include/protocol/pcifw.h
new file mode 100644
index 000000000000..6830dc3ee58a
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/pcifw.h
@@ -0,0 +1,75 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * pcifw.h PCI FW related headers
20 */
21
22#ifndef __PCIFW_H__
23#define __PCIFW_H__
24
25#pragma pack(1)
26
27struct pnp_hdr_s{
28 u32 signature; /* "$PnP" */
29 u8 rev; /* Struct revision */
30 u8 len; /* Header structure len in multiples
31 * of 16 bytes */
32 u16 off; /* Offset to next header 00 if none */
33 u8 rsvd; /* Reserved byte */
34 u8 cksum; /* 8-bit checksum for this header */
35 u32 pnp_dev_id; /* PnP Device Id */
36 u16 mfstr; /* Pointer to manufacturer string */
37 u16 prstr; /* Pointer to product string */
38 u8 devtype[3]; /* Device Type Code */
39 u8 devind; /* Device Indicator */
40 u16 bcventr; /* Bootstrap entry vector */
41 u16 rsvd2; /* Reserved */
42 u16 sriv; /* Static resource information vector */
43};
44
45struct pci_3_0_ds_s{
46 u32 sig; /* Signature "PCIR" */
47 u16 vendid; /* Vendor ID */
48 u16 devid; /* Device ID */
49 u16 devlistoff; /* Device List Offset */
50 u16 len; /* PCI Data Structure Length */
51 u8 rev; /* PCI Data Structure Revision */
52 u8 clcode[3]; /* Class Code */
53 u16 imglen; /* Code image length in multiples of
54 * 512 bytes */
55 u16 coderev; /* Revision level of code/data */
56 u8 codetype; /* Code type 0x00 - BIOS */
57 u8 indr; /* Last image indicator */
58 u16 mrtimglen; /* Max Run Time Image Length */
59 u16 cuoff; /* Config Utility Code Header Offset */
60 u16 dmtfclp; /* DMTF CLP entry point offset */
61};
62
63struct pci_optrom_hdr_s{
64 u16 sig; /* Signature 0x55AA */
65 u8 len; /* Option ROM length in units of 512 bytes */
66 u8 inivec[3]; /* Initialization vector */
67 u8 rsvd[16]; /* Reserved field */
68 u16 verptr; /* Pointer to version string - private */
69 u16 pcids; /* Pointer to PCI data structure */
70 u16 pnphdr; /* Pointer to PnP expansion header */
71};
72
73#pragma pack()
74
75#endif
diff --git a/drivers/scsi/bfa/include/protocol/scsi.h b/drivers/scsi/bfa/include/protocol/scsi.h
new file mode 100644
index 000000000000..b220e6b4f6e1
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/scsi.h
@@ -0,0 +1,1648 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __SCSI_H__
19#define __SCSI_H__
20
21#include <protocol/types.h>
22
23#pragma pack(1)
24
25/*
26 * generic SCSI cdb definition
27 */
28#define SCSI_MAX_CDBLEN 16
29struct scsi_cdb_s{
30 u8 scsi_cdb[SCSI_MAX_CDBLEN];
31};
32
33/*
34 * scsi lun serial number definition
35 */
36#define SCSI_LUN_SN_LEN 32
37struct scsi_lun_sn_s{
38 u8 lun_sn[SCSI_LUN_SN_LEN];
39};
40
41/*
42 * SCSI Direct Access Commands
43 */
44enum {
45 SCSI_OP_TEST_UNIT_READY = 0x00,
46 SCSI_OP_REQUEST_SENSE = 0x03,
47 SCSI_OP_FORMAT_UNIT = 0x04,
48 SCSI_OP_READ6 = 0x08,
49 SCSI_OP_WRITE6 = 0x0A,
50 SCSI_OP_WRITE_FILEMARKS = 0x10,
51 SCSI_OP_INQUIRY = 0x12,
52 SCSI_OP_MODE_SELECT6 = 0x15,
53 SCSI_OP_RESERVE6 = 0x16,
54 SCSI_OP_RELEASE6 = 0x17,
55 SCSI_OP_MODE_SENSE6 = 0x1A,
56 SCSI_OP_START_STOP_UNIT = 0x1B,
57 SCSI_OP_SEND_DIAGNOSTIC = 0x1D,
58 SCSI_OP_READ_CAPACITY = 0x25,
59 SCSI_OP_READ10 = 0x28,
60 SCSI_OP_WRITE10 = 0x2A,
61 SCSI_OP_VERIFY10 = 0x2F,
62 SCSI_OP_READ_DEFECT_DATA = 0x37,
63 SCSI_OP_LOG_SELECT = 0x4C,
64 SCSI_OP_LOG_SENSE = 0x4D,
65 SCSI_OP_MODE_SELECT10 = 0x55,
66 SCSI_OP_RESERVE10 = 0x56,
67 SCSI_OP_RELEASE10 = 0x57,
68 SCSI_OP_MODE_SENSE10 = 0x5A,
69 SCSI_OP_PER_RESERVE_IN = 0x5E,
70 SCSI_OP_PER_RESERVE_OUR = 0x5E,
71 SCSI_OP_READ16 = 0x88,
72 SCSI_OP_WRITE16 = 0x8A,
73 SCSI_OP_VERIFY16 = 0x8F,
74 SCSI_OP_READ_CAPACITY16 = 0x9E,
75 SCSI_OP_REPORT_LUNS = 0xA0,
76 SCSI_OP_READ12 = 0xA8,
77 SCSI_OP_WRITE12 = 0xAA,
78 SCSI_OP_UNDEF = 0xFF,
79};
80
81/*
82 * SCSI START_STOP_UNIT command
83 */
84struct scsi_start_stop_unit_s{
85 u8 opcode;
86#ifdef __BIGENDIAN
87 u8 lun:3;
88 u8 reserved1:4;
89 u8 immed:1;
90#else
91 u8 immed:1;
92 u8 reserved1:4;
93 u8 lun:3;
94#endif
95 u8 reserved2;
96 u8 reserved3;
97#ifdef __BIGENDIAN
98 u8 power_conditions:4;
99 u8 reserved4:2;
100 u8 loEj:1;
101 u8 start:1;
102#else
103 u8 start:1;
104 u8 loEj:1;
105 u8 reserved4:2;
106 u8 power_conditions:4;
107#endif
108 u8 control;
109};
110
111/*
112 * SCSI SEND_DIAGNOSTIC command
113 */
114struct scsi_send_diagnostic_s{
115 u8 opcode;
116#ifdef __BIGENDIAN
117 u8 self_test_code:3;
118 u8 pf:1;
119 u8 reserved1:1;
120 u8 self_test:1;
121 u8 dev_offl:1;
122 u8 unit_offl:1;
123#else
124 u8 unit_offl:1;
125 u8 dev_offl:1;
126 u8 self_test:1;
127 u8 reserved1:1;
128 u8 pf:1;
129 u8 self_test_code:3;
130#endif
131 u8 reserved2;
132
133 u8 param_list_length[2]; /* MSB first */
134 u8 control;
135
136};
137
138/*
139 * SCSI READ10/WRITE10 commands
140 */
141struct scsi_rw10_s{
142 u8 opcode;
143#ifdef __BIGENDIAN
144 u8 lun:3;
145 u8 dpo:1; /* Disable Page Out */
146 u8 fua:1; /* Force Unit Access */
147 u8 reserved1:2;
148 u8 rel_adr:1; /* relative address */
149#else
150 u8 rel_adr:1;
151 u8 reserved1:2;
152 u8 fua:1;
153 u8 dpo:1;
154 u8 lun:3;
155#endif
156 u8 lba0; /* logical block address - MSB */
157 u8 lba1;
158 u8 lba2;
159 u8 lba3; /* LSB */
160 u8 reserved3;
161 u8 xfer_length0; /* transfer length in blocks - MSB */
162 u8 xfer_length1; /* LSB */
163 u8 control;
164};
165
166#define SCSI_CDB10_GET_LBA(cdb) \
167 (((cdb)->lba0 << 24) | ((cdb)->lba1 << 16) | \
168 ((cdb)->lba2 << 8) | (cdb)->lba3)
169
170#define SCSI_CDB10_SET_LBA(cdb, lba) { \
171 (cdb)->lba0 = lba >> 24; \
172 (cdb)->lba1 = (lba >> 16) & 0xFF; \
173 (cdb)->lba2 = (lba >> 8) & 0xFF; \
174 (cdb)->lba3 = lba & 0xFF; \
175}
176
177#define SCSI_CDB10_GET_TL(cdb) \
178 ((cdb)->xfer_length0 << 8 | (cdb)->xfer_length1)
179#define SCSI_CDB10_SET_TL(cdb, tl) { \
180 (cdb)->xfer_length0 = tl >> 8; \
181 (cdb)->xfer_length1 = tl & 0xFF; \
182}
183
184/*
185 * SCSI READ6/WRITE6 commands
186 */
187struct scsi_rw6_s{
188 u8 opcode;
189#ifdef __BIGENDIAN
190 u8 lun:3;
191 u8 lba0:5; /* MSb */
192#else
193 u8 lba0:5; /* MSb */
194 u8 lun:3;
195#endif
196 u8 lba1;
197 u8 lba2; /* LSB */
198 u8 xfer_length;
199 u8 control;
200};
201
202#define SCSI_TAPE_CDB6_GET_TL(cdb) \
203 (((cdb)->tl0 << 16) | ((cdb)->tl1 << 8) | (cdb)->tl2)
204
205#define SCSI_TAPE_CDB6_SET_TL(cdb, tl) { \
206 (cdb)->tl0 = tl >> 16; \
207 (cdb)->tl1 = (tl >> 8) & 0xFF; \
208 (cdb)->tl2 = tl & 0xFF; \
209}
210
211/*
212 * SCSI sequential (TAPE) wrtie command
213 */
214struct scsi_tape_wr_s{
215 u8 opcode;
216#ifdef __BIGENDIAN
217 u8 rsvd:7;
218 u8 fixed:1; /* MSb */
219#else
220 u8 fixed:1; /* MSb */
221 u8 rsvd:7;
222#endif
223 u8 tl0; /* Msb */
224 u8 tl1;
225 u8 tl2; /* Lsb */
226
227 u8 control;
228};
229
230#define SCSI_CDB6_GET_LBA(cdb) \
231 (((cdb)->lba0 << 16) | ((cdb)->lba1 << 8) | (cdb)->lba2)
232
233#define SCSI_CDB6_SET_LBA(cdb, lba) { \
234 (cdb)->lba0 = lba >> 16; \
235 (cdb)->lba1 = (lba >> 8) & 0xFF; \
236 (cdb)->lba2 = lba & 0xFF; \
237}
238
239#define SCSI_CDB6_GET_TL(cdb) ((cdb)->xfer_length)
240#define SCSI_CDB6_SET_TL(cdb, tl) { \
241 (cdb)->xfer_length = tl; \
242}
243
244/*
245 * SCSI sense data format
246 */
247struct scsi_sense_s{
248#ifdef __BIGENDIAN
249 u8 valid:1;
250 u8 rsp_code:7;
251#else
252 u8 rsp_code:7;
253 u8 valid:1;
254#endif
255 u8 seg_num;
256#ifdef __BIGENDIAN
257 u8 file_mark:1;
258 u8 eom:1; /* end of media */
259 u8 ili:1; /* incorrect length indicator */
260 u8 reserved:1;
261 u8 sense_key:4;
262#else
263 u8 sense_key:4;
264 u8 reserved:1;
265 u8 ili:1; /* incorrect length indicator */
266 u8 eom:1; /* end of media */
267 u8 file_mark:1;
268#endif
269 u8 information[4]; /* device-type or command specific info
270 */
271 u8 add_sense_length;
272 /* additional sense length */
273 u8 command_info[4];/* command specific information
274 */
275 u8 asc; /* additional sense code */
276 u8 ascq; /* additional sense code qualifier */
277 u8 fru_code; /* field replaceable unit code */
278#ifdef __BIGENDIAN
279 u8 sksv:1; /* sense key specific valid */
280 u8 c_d:1; /* command/data bit */
281 u8 res1:2;
282 u8 bpv:1; /* bit pointer valid */
283 u8 bpointer:3; /* bit pointer */
284#else
285 u8 bpointer:3; /* bit pointer */
286 u8 bpv:1; /* bit pointer valid */
287 u8 res1:2;
288 u8 c_d:1; /* command/data bit */
289 u8 sksv:1; /* sense key specific valid */
290#endif
291 u8 fpointer[2]; /* field pointer */
292};
293
294#define SCSI_SENSE_CUR_ERR 0x70
295#define SCSI_SENSE_DEF_ERR 0x71
296
297/*
298 * SCSI sense key values
299 */
300#define SCSI_SK_NO_SENSE 0x0
301#define SCSI_SK_REC_ERR 0x1 /* recovered error */
302#define SCSI_SK_NOT_READY 0x2
303#define SCSI_SK_MED_ERR 0x3 /* medium error */
304#define SCSI_SK_HW_ERR 0x4 /* hardware error */
305#define SCSI_SK_ILLEGAL_REQ 0x5
306#define SCSI_SK_UNIT_ATT 0x6 /* unit attention */
307#define SCSI_SK_DATA_PROTECT 0x7
308#define SCSI_SK_BLANK_CHECK 0x8
309#define SCSI_SK_VENDOR_SPEC 0x9
310#define SCSI_SK_COPY_ABORTED 0xA
311#define SCSI_SK_ABORTED_CMND 0xB
312#define SCSI_SK_VOL_OVERFLOW 0xD
313#define SCSI_SK_MISCOMPARE 0xE
314
315/*
316 * SCSI additional sense codes
317 */
318#define SCSI_ASC_NO_ADD_SENSE 0x00
319#define SCSI_ASC_LUN_NOT_READY 0x04
320#define SCSI_ASC_LUN_COMMUNICATION 0x08
321#define SCSI_ASC_WRITE_ERROR 0x0C
322#define SCSI_ASC_INVALID_CMND_CODE 0x20
323#define SCSI_ASC_BAD_LBA 0x21
324#define SCSI_ASC_INVALID_FIELD_IN_CDB 0x24
325#define SCSI_ASC_LUN_NOT_SUPPORTED 0x25
326#define SCSI_ASC_LUN_WRITE_PROTECT 0x27
327#define SCSI_ASC_POWERON_BDR 0x29 /* power on reset, bus reset,
328 * bus device reset
329 */
330#define SCSI_ASC_PARAMS_CHANGED 0x2A
331#define SCSI_ASC_CMND_CLEARED_BY_A_I 0x2F
332#define SCSI_ASC_SAVING_PARAM_NOTSUPP 0x39
333#define SCSI_ASC_TOCC 0x3F /* target operating condtions
334 * changed
335 */
336#define SCSI_ASC_PARITY_ERROR 0x47
337#define SCSI_ASC_CMND_PHASE_ERROR 0x4A
338#define SCSI_ASC_DATA_PHASE_ERROR 0x4B
339#define SCSI_ASC_VENDOR_SPEC 0x7F
340
341/*
342 * SCSI additional sense code qualifiers
343 */
344#define SCSI_ASCQ_CAUSE_NOT_REPORT 0x00
345#define SCSI_ASCQ_BECOMING_READY 0x01
346#define SCSI_ASCQ_INIT_CMD_REQ 0x02
347#define SCSI_ASCQ_FORMAT_IN_PROGRESS 0x04
348#define SCSI_ASCQ_OPERATION_IN_PROGRESS 0x07
349#define SCSI_ASCQ_SELF_TEST_IN_PROGRESS 0x09
350#define SCSI_ASCQ_WR_UNEXP_UNSOL_DATA 0x0C
351#define SCSI_ASCQ_WR_NOTENG_UNSOL_DATA 0x0D
352
353#define SCSI_ASCQ_LBA_OUT_OF_RANGE 0x00
354#define SCSI_ASCQ_INVALID_ELEMENT_ADDR 0x01
355
356#define SCSI_ASCQ_LUN_WRITE_PROTECTED 0x00
357#define SCSI_ASCQ_LUN_HW_WRITE_PROTECTED 0x01
358#define SCSI_ASCQ_LUN_SW_WRITE_PROTECTED 0x02
359
360#define SCSI_ASCQ_POR 0x01 /* power on reset */
361#define SCSI_ASCQ_SBR 0x02 /* scsi bus reset */
362#define SCSI_ASCQ_BDR 0x03 /* bus device reset */
363#define SCSI_ASCQ_DIR 0x04 /* device internal reset */
364
365#define SCSI_ASCQ_MODE_PARAMS_CHANGED 0x01
366#define SCSI_ASCQ_LOG_PARAMS_CHANGED 0x02
367#define SCSI_ASCQ_RESERVATIONS_PREEMPTED 0x03
368#define SCSI_ASCQ_RESERVATIONS_RELEASED 0x04
369#define SCSI_ASCQ_REGISTRATIONS_PREEMPTED 0x05
370
371#define SCSI_ASCQ_MICROCODE_CHANGED 0x01
372#define SCSI_ASCQ_CHANGED_OPER_COND 0x02
373#define SCSI_ASCQ_INQ_CHANGED 0x03 /* inquiry data changed */
374#define SCSI_ASCQ_DI_CHANGED 0x05 /* device id changed */
375#define SCSI_ASCQ_RL_DATA_CHANGED 0x0E /* report luns data changed */
376
377#define SCSI_ASCQ_DP_CRC_ERR 0x01 /* data phase crc error */
378#define SCSI_ASCQ_DP_SCSI_PARITY_ERR 0x02 /* data phase scsi parity error
379 */
380#define SCSI_ASCQ_IU_CRC_ERR 0x03 /* information unit crc error */
381#define SCSI_ASCQ_PROTO_SERV_CRC_ERR 0x05
382
383#define SCSI_ASCQ_LUN_TIME_OUT 0x01
384
385/* ------------------------------------------------------------
386 * SCSI INQUIRY
387 * ------------------------------------------------------------*/
388
389struct scsi_inquiry_s{
390 u8 opcode;
391#ifdef __BIGENDIAN
392 u8 lun:3;
393 u8 reserved1:3;
394 u8 cmd_dt:1;
395 u8 evpd:1;
396#else
397 u8 evpd:1;
398 u8 cmd_dt:1;
399 u8 reserved1:3;
400 u8 lun:3;
401#endif
402 u8 page_code;
403 u8 reserved2;
404 u8 alloc_length;
405 u8 control;
406};
407
408struct scsi_inquiry_vendor_s{
409 u8 vendor_id[8];
410};
411
412struct scsi_inquiry_prodid_s{
413 u8 product_id[16];
414};
415
416struct scsi_inquiry_prodrev_s{
417 u8 product_rev[4];
418};
419
420struct scsi_inquiry_data_s{
421#ifdef __BIGENDIAN
422 u8 peripheral_qual:3; /* peripheral qualifier */
423 u8 device_type:5; /* peripheral device type */
424
425 u8 rmb:1; /* removable medium bit */
426 u8 device_type_mod:7; /* device type modifier */
427
428 u8 version;
429
430 u8 aenc:1; /* async event notification capability
431 */
432 u8 trm_iop:1; /* terminate I/O process */
433 u8 norm_aca:1; /* normal ACA supported */
434 u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */
435 u8 rsp_data_format:4;
436
437 u8 additional_len;
438 u8 sccs:1;
439 u8 reserved1:7;
440
441 u8 reserved2:1;
442 u8 enc_serv:1; /* enclosure service component */
443 u8 reserved3:1;
444 u8 multi_port:1; /* multi-port device */
445 u8 m_chngr:1; /* device in medium transport element */
446 u8 ack_req_q:1; /* SIP specific bit */
447 u8 addr32:1; /* SIP specific bit */
448 u8 addr16:1; /* SIP specific bit */
449
450 u8 rel_adr:1; /* relative address */
451 u8 w_bus32:1;
452 u8 w_bus16:1;
453 u8 synchronous:1;
454 u8 linked_commands:1;
455 u8 trans_dis:1;
456 u8 cmd_queue:1; /* command queueing supported */
457 u8 soft_reset:1; /* soft reset alternative (VS) */
458#else
459 u8 device_type:5; /* peripheral device type */
460 u8 peripheral_qual:3;
461 /* peripheral qualifier */
462
463 u8 device_type_mod:7;
464 /* device type modifier */
465 u8 rmb:1; /* removable medium bit */
466
467 u8 version;
468
469 u8 rsp_data_format:4;
470 u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */
471 u8 norm_aca:1; /* normal ACA supported */
472 u8 terminate_iop:1;/* terminate I/O process */
473 u8 aenc:1; /* async event notification capability
474 */
475
476 u8 additional_len;
477 u8 reserved1:7;
478 u8 sccs:1;
479
480 u8 addr16:1; /* SIP specific bit */
481 u8 addr32:1; /* SIP specific bit */
482 u8 ack_req_q:1; /* SIP specific bit */
483 u8 m_chngr:1; /* device in medium transport element */
484 u8 multi_port:1; /* multi-port device */
485 u8 reserved3:1; /* TBD - Vendor Specific */
486 u8 enc_serv:1; /* enclosure service component */
487 u8 reserved2:1;
488
489 u8 soft_seset:1; /* soft reset alternative (VS) */
490 u8 cmd_queue:1; /* command queueing supported */
491 u8 trans_dis:1;
492 u8 linked_commands:1;
493 u8 synchronous:1;
494 u8 w_bus16:1;
495 u8 w_bus32:1;
496 u8 rel_adr:1; /* relative address */
497#endif
498 struct scsi_inquiry_vendor_s vendor_id;
499 struct scsi_inquiry_prodid_s product_id;
500 struct scsi_inquiry_prodrev_s product_rev;
501 u8 vendor_specific[20];
502 u8 reserved4[40];
503};
504
505/*
506 * inquiry.peripheral_qual field values
507 */
508#define SCSI_DEVQUAL_DEFAULT 0
509#define SCSI_DEVQUAL_NOT_CONNECTED 1
510#define SCSI_DEVQUAL_NOT_SUPPORTED 3
511
512/*
513 * inquiry.device_type field values
514 */
515#define SCSI_DEVICE_DIRECT_ACCESS 0x00
516#define SCSI_DEVICE_SEQ_ACCESS 0x01
517#define SCSI_DEVICE_ARRAY_CONTROLLER 0x0C
518#define SCSI_DEVICE_UNKNOWN 0x1F
519
520/*
521 * inquiry.version
522 */
523#define SCSI_VERSION_ANSI_X3131 2 /* ANSI X3.131 SCSI-2 */
524#define SCSI_VERSION_SPC 3 /* SPC (SCSI-3), ANSI X3.301:1997 */
525#define SCSI_VERSION_SPC_2 4 /* SPC-2 */
526
527/*
528 * response data format
529 */
530#define SCSI_RSP_DATA_FORMAT 2 /* SCSI-2 & SPC */
531
532/*
533 * SCSI inquiry page codes
534 */
535#define SCSI_INQ_PAGE_VPD_PAGES 0x00 /* supported vpd pages */
536#define SCSI_INQ_PAGE_USN_PAGE 0x80 /* unit serial number page */
537#define SCSI_INQ_PAGE_DEV_IDENT 0x83 /* device indentification page
538 */
539#define SCSI_INQ_PAGES_MAX 3
540
541/*
542 * supported vital product data pages
543 */
544struct scsi_inq_page_vpd_pages_s{
545#ifdef __BIGENDIAN
546 u8 peripheral_qual:3;
547 u8 device_type:5;
548#else
549 u8 device_type:5;
550 u8 peripheral_qual:3;
551#endif
552 u8 page_code;
553 u8 reserved;
554 u8 page_length;
555 u8 pages[SCSI_INQ_PAGES_MAX];
556};
557
558/*
559 * Unit serial number page
560 */
561#define SCSI_INQ_USN_LEN 32
562
563struct scsi_inq_usn_s{
564 char usn[SCSI_INQ_USN_LEN];
565};
566
567struct scsi_inq_page_usn_s{
568#ifdef __BIGENDIAN
569 u8 peripheral_qual:3;
570 u8 device_type:5;
571#else
572 u8 device_type:5;
573 u8 peripheral_qual:3;
574#endif
575 u8 page_code;
576 u8 reserved1;
577 u8 page_length;
578 struct scsi_inq_usn_s usn;
579};
580
581enum {
582 SCSI_INQ_DIP_CODE_BINARY = 1, /* identifier has binary value */
583 SCSI_INQ_DIP_CODE_ASCII = 2, /* identifier has ascii value */
584};
585
586enum {
587 SCSI_INQ_DIP_ASSOC_LUN = 0, /* id is associated with device */
588 SCSI_INQ_DIP_ASSOC_PORT = 1, /* id is associated with port that
589 * received the request
590 */
591};
592
593enum {
594 SCSI_INQ_ID_TYPE_VENDOR = 1,
595 SCSI_INQ_ID_TYPE_IEEE = 2,
596 SCSI_INQ_ID_TYPE_FC_FS = 3,
597 SCSI_INQ_ID_TYPE_OTHER = 4,
598};
599
600struct scsi_inq_dip_desc_s{
601#ifdef __BIGENDIAN
602 u8 res0:4;
603 u8 code_set:4;
604 u8 res1:2;
605 u8 association:2;
606 u8 id_type:4;
607#else
608 u8 code_set:4;
609 u8 res0:4;
610 u8 id_type:4;
611 u8 association:2;
612 u8 res1:2;
613#endif
614 u8 res2;
615 u8 id_len;
616 struct scsi_lun_sn_s id;
617};
618
619/*
620 * Device indentification page
621 */
622struct scsi_inq_page_dev_ident_s{
623#ifdef __BIGENDIAN
624 u8 peripheral_qual:3;
625 u8 device_type:5;
626#else
627 u8 device_type:5;
628 u8 peripheral_qual:3;
629#endif
630 u8 page_code;
631 u8 reserved1;
632 u8 page_length;
633 struct scsi_inq_dip_desc_s desc;
634};
635
636/* ------------------------------------------------------------
637 * READ CAPACITY
638 * ------------------------------------------------------------
639 */
640
641struct scsi_read_capacity_s{
642 u8 opcode;
643#ifdef __BIGENDIAN
644 u8 lun:3;
645 u8 reserved1:4;
646 u8 rel_adr:1;
647#else
648 u8 rel_adr:1;
649 u8 reserved1:4;
650 u8 lun:3;
651#endif
652 u8 lba0; /* MSB */
653 u8 lba1;
654 u8 lba2;
655 u8 lba3; /* LSB */
656 u8 reserved2;
657 u8 reserved3;
658#ifdef __BIGENDIAN
659 u8 reserved4:7;
660 u8 pmi:1; /* partial medium indicator */
661#else
662 u8 pmi:1; /* partial medium indicator */
663 u8 reserved4:7;
664#endif
665 u8 control;
666};
667
668struct scsi_read_capacity_data_s{
669 u32 max_lba; /* maximum LBA available */
670 u32 block_length; /* in bytes */
671};
672
673struct scsi_read_capacity16_data_s{
674 u64 lba; /* maximum LBA available */
675 u32 block_length; /* in bytes */
676#ifdef __BIGENDIAN
677 u8 reserved1:4,
678 p_type:3,
679 prot_en:1;
680 u8 reserved2:4,
681 lb_pbe:4; /* logical blocks per physical block
682 * exponent */
683 u16 reserved3:2,
684 lba_align:14; /* lowest aligned logical block
685 * address */
686#else
687 u16 lba_align:14, /* lowest aligned logical block
688 * address */
689 reserved3:2;
690 u8 lb_pbe:4, /* logical blocks per physical block
691 * exponent */
692 reserved2:4;
693 u8 prot_en:1,
694 p_type:3,
695 reserved1:4;
696#endif
697 u64 reserved4;
698 u64 reserved5;
699};
700
701/* ------------------------------------------------------------
702 * REPORT LUNS command
703 * ------------------------------------------------------------
704 */
705
706struct scsi_report_luns_s{
707 u8 opcode; /* A0h - REPORT LUNS opCode */
708 u8 reserved1[5];
709 u8 alloc_length[4];/* allocation length MSB first */
710 u8 reserved2;
711 u8 control;
712};
713
714#define SCSI_REPORT_LUN_ALLOC_LENGTH(rl) \
715 ((rl->alloc_length[0] << 24) | (rl->alloc_length[1] << 16) | \
716 (rl->alloc_length[2] << 8) | (rl->alloc_length[3]))
717
718#define SCSI_REPORT_LUNS_SET_ALLOCLEN(rl, alloc_len) { \
719 (rl)->alloc_length[0] = (alloc_len) >> 24; \
720 (rl)->alloc_length[1] = ((alloc_len) >> 16) & 0xFF; \
721 (rl)->alloc_length[2] = ((alloc_len) >> 8) & 0xFF; \
722 (rl)->alloc_length[3] = (alloc_len) & 0xFF; \
723}
724
725struct scsi_report_luns_data_s{
726 u32 lun_list_length; /* length of LUN list length */
727 u32 reserved;
728 lun_t lun[1]; /* first LUN in lun list */
729};
730
731/* -------------------------------------------------------------
732 * SCSI mode parameters
733 * -----------------------------------------------------------
734 */
735enum {
736 SCSI_DA_MEDIUM_DEF = 0, /* direct access default medium type */
737 SCSI_DA_MEDIUM_SS = 1, /* direct access single sided */
738 SCSI_DA_MEDIUM_DS = 2, /* direct access double sided */
739};
740
741/*
742 * SCSI Mode Select(6) cdb
743 */
744struct scsi_mode_select6_s{
745 u8 opcode;
746#ifdef __BIGENDIAN
747 u8 reserved1:3;
748 u8 pf:1; /* page format */
749 u8 reserved2:3;
750 u8 sp:1; /* save pages if set to 1 */
751#else
752 u8 sp:1; /* save pages if set to 1 */
753 u8 reserved2:3;
754 u8 pf:1; /* page format */
755 u8 reserved1:3;
756#endif
757 u8 reserved3[2];
758 u8 alloc_len;
759 u8 control;
760};
761
762/*
763 * SCSI Mode Select(10) cdb
764 */
765struct scsi_mode_select10_s{
766 u8 opcode;
767#ifdef __BIGENDIAN
768 u8 reserved1:3;
769 u8 pf:1; /* page format */
770 u8 reserved2:3;
771 u8 sp:1; /* save pages if set to 1 */
772#else
773 u8 sp:1; /* save pages if set to 1 */
774 u8 reserved2:3;
775 u8 pf:1; /* page format */
776 u8 reserved1:3;
777#endif
778 u8 reserved3[5];
779 u8 alloc_len_msb;
780 u8 alloc_len_lsb;
781 u8 control;
782};
783
784/*
785 * SCSI Mode Sense(6) cdb
786 */
787struct scsi_mode_sense6_s{
788 u8 opcode;
789#ifdef __BIGENDIAN
790 u8 reserved1:4;
791 u8 dbd:1; /* disable block discriptors if set to 1 */
792 u8 reserved2:3;
793
794 u8 pc:2; /* page control */
795 u8 page_code:6;
796#else
797 u8 reserved2:3;
798 u8 dbd:1; /* disable block descriptors if set to 1 */
799 u8 reserved1:4;
800
801 u8 page_code:6;
802 u8 pc:2; /* page control */
803#endif
804 u8 reserved3;
805 u8 alloc_len;
806 u8 control;
807};
808
809/*
810 * SCSI Mode Sense(10) cdb
811 */
812struct scsi_mode_sense10_s{
813 u8 opcode;
814#ifdef __BIGENDIAN
815 u8 reserved1:3;
816 u8 LLBAA:1; /* long LBA accepted if set to 1 */
817 u8 dbd:1; /* disable block descriptors if set
818 * to 1
819 */
820 u8 reserved2:3;
821
822 u8 pc:2; /* page control */
823 u8 page_code:6;
824#else
825 u8 reserved2:3;
826 u8 dbd:1; /* disable block descriptors if set to
827 * 1
828 */
829 u8 LLBAA:1; /* long LBA accepted if set to 1 */
830 u8 reserved1:3;
831
832 u8 page_code:6;
833 u8 pc:2; /* page control */
834#endif
835 u8 reserved3[4];
836 u8 alloc_len_msb;
837 u8 alloc_len_lsb;
838 u8 control;
839};
840
841#define SCSI_CDB10_GET_AL(cdb) \
842 ((cdb)->alloc_len_msb << 8 | (cdb)->alloc_len_lsb)
843
844#define SCSI_CDB10_SET_AL(cdb, al) { \
845 (cdb)->alloc_len_msb = al >> 8; \
846 (cdb)->alloc_len_lsb = al & 0xFF; \
847}
848
849#define SCSI_CDB6_GET_AL(cdb) ((cdb)->alloc_len)
850
851#define SCSI_CDB6_SET_AL(cdb, al) { \
852 (cdb)->alloc_len = al; \
853}
854
855/*
856 * page control field values
857 */
858#define SCSI_PC_CURRENT_VALUES 0x0
859#define SCSI_PC_CHANGEABLE_VALUES 0x1
860#define SCSI_PC_DEFAULT_VALUES 0x2
861#define SCSI_PC_SAVED_VALUES 0x3
862
863/*
864 * SCSI mode page codes
865 */
866#define SCSI_MP_VENDOR_SPEC 0x00
867#define SCSI_MP_DISC_RECN 0x02 /* disconnect-reconnect page */
868#define SCSI_MP_FORMAT_DEVICE 0x03
869#define SCSI_MP_RDG 0x04 /* rigid disk geometry page */
870#define SCSI_MP_FDP 0x05 /* flexible disk page */
871#define SCSI_MP_CACHING 0x08 /* caching page */
872#define SCSI_MP_CONTROL 0x0A /* control mode page */
873#define SCSI_MP_MED_TYPES_SUP 0x0B /* medium types supported page */
874#define SCSI_MP_INFO_EXCP_CNTL 0x1C /* informational exception control */
875#define SCSI_MP_ALL 0x3F /* return all pages - mode sense only */
876
877/*
878 * mode parameter header
879 */
880struct scsi_mode_param_header6_s{
881 u8 mode_datalen;
882 u8 medium_type;
883
884 /*
885 * device specific parameters expanded for direct access devices
886 */
887#ifdef __BIGENDIAN
888 u32 wp:1; /* write protected */
889 u32 reserved1:2;
890 u32 dpofua:1; /* disable page out + force unit access
891 */
892 u32 reserved2:4;
893#else
894 u32 reserved2:4;
895 u32 dpofua:1; /* disable page out + force unit access
896 */
897 u32 reserved1:2;
898 u32 wp:1; /* write protected */
899#endif
900
901 u8 block_desclen;
902};
903
904struct scsi_mode_param_header10_s{
905 u32 mode_datalen:16;
906 u32 medium_type:8;
907
908 /*
909 * device specific parameters expanded for direct access devices
910 */
911#ifdef __BIGENDIAN
912 u32 wp:1; /* write protected */
913 u32 reserved1:2;
914 u32 dpofua:1; /* disable page out + force unit access
915 */
916 u32 reserved2:4;
917#else
918 u32 reserved2:4;
919 u32 dpofua:1; /* disable page out + force unit access
920 */
921 u32 reserved1:2;
922 u32 wp:1; /* write protected */
923#endif
924
925#ifdef __BIGENDIAN
926 u32 reserved3:7;
927 u32 longlba:1;
928#else
929 u32 longlba:1;
930 u32 reserved3:7;
931#endif
932 u32 reserved4:8;
933 u32 block_desclen:16;
934};
935
936/*
937 * mode parameter block descriptor
938 */
939struct scsi_mode_param_desc_s{
940 u32 nblks;
941 u32 density_code:8;
942 u32 block_length:24;
943};
944
945/*
946 * Disconnect-reconnect mode page format
947 */
948struct scsi_mp_disc_recn_s{
949#ifdef __BIGENDIAN
950 u8 ps:1;
951 u8 reserved1:1;
952 u8 page_code:6;
953#else
954 u8 page_code:6;
955 u8 reserved1:1;
956 u8 ps:1;
957#endif
958 u8 page_len;
959 u8 buf_full_ratio;
960 u8 buf_empty_ratio;
961
962 u8 bil_msb; /* bus inactivity limit -MSB */
963 u8 bil_lsb; /* bus inactivity limit -LSB */
964
965 u8 dtl_msb; /* disconnect time limit - MSB */
966 u8 dtl_lsb; /* disconnect time limit - LSB */
967
968 u8 ctl_msb; /* connect time limit - MSB */
969 u8 ctl_lsb; /* connect time limit - LSB */
970
971 u8 max_burst_len_msb;
972 u8 max_burst_len_lsb;
973#ifdef __BIGENDIAN
974 u8 emdp:1; /* enable modify data pointers */
975 u8 fa:3; /* fair arbitration */
976 u8 dimm:1; /* disconnect immediate */
977 u8 dtdc:3; /* data transfer disconnect control */
978#else
979 u8 dtdc:3; /* data transfer disconnect control */
980 u8 dimm:1; /* disconnect immediate */
981 u8 fa:3; /* fair arbitration */
982 u8 emdp:1; /* enable modify data pointers */
983#endif
984
985 u8 reserved3;
986
987 u8 first_burst_len_msb;
988 u8 first_burst_len_lsb;
989};
990
991/*
992 * SCSI format device mode page
993 */
994struct scsi_mp_format_device_s{
995#ifdef __BIGENDIAN
996 u32 ps:1;
997 u32 reserved1:1;
998 u32 page_code:6;
999#else
1000 u32 page_code:6;
1001 u32 reserved1:1;
1002 u32 ps:1;
1003#endif
1004 u32 page_len:8;
1005 u32 tracks_per_zone:16;
1006
1007 u32 a_sec_per_zone:16;
1008 u32 a_tracks_per_zone:16;
1009
1010 u32 a_tracks_per_lun:16; /* alternate tracks/lun-MSB */
1011 u32 sec_per_track:16; /* sectors/track-MSB */
1012
1013 u32 bytes_per_sector:16;
1014 u32 interleave:16;
1015
1016 u32 tsf:16; /* track skew factor-MSB */
1017 u32 csf:16; /* cylinder skew factor-MSB */
1018
1019#ifdef __BIGENDIAN
1020 u32 ssec:1; /* soft sector formatting */
1021 u32 hsec:1; /* hard sector formatting */
1022 u32 rmb:1; /* removable media */
1023 u32 surf:1; /* surface */
1024 u32 reserved2:4;
1025#else
1026 u32 reserved2:4;
1027 u32 surf:1; /* surface */
1028 u32 rmb:1; /* removable media */
1029 u32 hsec:1; /* hard sector formatting */
1030 u32 ssec:1; /* soft sector formatting */
1031#endif
1032 u32 reserved3:24;
1033};
1034
1035/*
1036 * SCSI rigid disk device geometry page
1037 */
1038struct scsi_mp_rigid_device_geometry_s{
1039#ifdef __BIGENDIAN
1040 u32 ps:1;
1041 u32 reserved1:1;
1042 u32 page_code:6;
1043#else
1044 u32 page_code:6;
1045 u32 reserved1:1;
1046 u32 ps:1;
1047#endif
1048 u32 page_len:8;
1049 u32 num_cylinders0:8;
1050 u32 num_cylinders1:8;
1051
1052 u32 num_cylinders2:8;
1053 u32 num_heads:8;
1054 u32 scwp0:8;
1055 u32 scwp1:8;
1056
1057 u32 scwp2:8;
1058 u32 scrwc0:8;
1059 u32 scrwc1:8;
1060 u32 scrwc2:8;
1061
1062 u32 dsr:16;
1063 u32 lscyl0:8;
1064 u32 lscyl1:8;
1065
1066 u32 lscyl2:8;
1067#ifdef __BIGENDIAN
1068 u32 reserved2:6;
1069 u32 rpl:2; /* rotational position locking */
1070#else
1071 u32 rpl:2; /* rotational position locking */
1072 u32 reserved2:6;
1073#endif
1074 u32 rot_off:8;
1075 u32 reserved3:8;
1076
1077 u32 med_rot_rate:16;
1078 u32 reserved4:16;
1079};
1080
1081/*
1082 * SCSI caching mode page
1083 */
1084struct scsi_mp_caching_s{
1085#ifdef __BIGENDIAN
1086 u8 ps:1;
1087 u8 res1:1;
1088 u8 page_code:6;
1089#else
1090 u8 page_code:6;
1091 u8 res1:1;
1092 u8 ps:1;
1093#endif
1094 u8 page_len;
1095#ifdef __BIGENDIAN
1096 u8 ic:1; /* initiator control */
1097 u8 abpf:1; /* abort pre-fetch */
1098 u8 cap:1; /* caching analysis permitted */
1099 u8 disc:1; /* discontinuity */
1100 u8 size:1; /* size enable */
1101 u8 wce:1; /* write cache enable */
1102 u8 mf:1; /* multiplication factor */
1103 u8 rcd:1; /* read cache disable */
1104
1105 u8 drrp:4; /* demand read retention priority */
1106 u8 wrp:4; /* write retention priority */
1107#else
1108 u8 rcd:1; /* read cache disable */
1109 u8 mf:1; /* multiplication factor */
1110 u8 wce:1; /* write cache enable */
1111 u8 size:1; /* size enable */
1112 u8 disc:1; /* discontinuity */
1113 u8 cap:1; /* caching analysis permitted */
1114 u8 abpf:1; /* abort pre-fetch */
1115 u8 ic:1; /* initiator control */
1116
1117 u8 wrp:4; /* write retention priority */
1118 u8 drrp:4; /* demand read retention priority */
1119#endif
1120 u8 dptl[2];/* disable pre-fetch transfer length */
1121 u8 min_prefetch[2];
1122 u8 max_prefetch[2];
1123 u8 max_prefetch_limit[2];
1124#ifdef __BIGENDIAN
1125 u8 fsw:1; /* force sequential write */
1126 u8 lbcss:1;/* logical block cache segment size */
1127 u8 dra:1; /* disable read ahead */
1128 u8 vs:2; /* vendor specific */
1129 u8 res2:3;
1130#else
1131 u8 res2:3;
1132 u8 vs:2; /* vendor specific */
1133 u8 dra:1; /* disable read ahead */
1134 u8 lbcss:1;/* logical block cache segment size */
1135 u8 fsw:1; /* force sequential write */
1136#endif
1137 u8 num_cache_segs;
1138
1139 u8 cache_seg_size[2];
1140 u8 res3;
1141 u8 non_cache_seg_size[3];
1142};
1143
1144/*
1145 * SCSI control mode page
1146 */
1147struct scsi_mp_control_page_s{
1148#ifdef __BIGENDIAN
1149u8 ps:1;
1150u8 reserved1:1;
1151u8 page_code:6;
1152#else
1153u8 page_code:6;
1154u8 reserved1:1;
1155u8 ps:1;
1156#endif
1157 u8 page_len;
1158#ifdef __BIGENDIAN
1159 u8 tst:3; /* task set type */
1160 u8 reserved3:3;
1161 u8 gltsd:1; /* global logging target save disable */
1162 u8 rlec:1; /* report log exception condition */
1163
1164 u8 qalgo_mod:4; /* queue alogorithm modifier */
1165 u8 reserved4:1;
1166 u8 qerr:2; /* queue error management */
1167 u8 dque:1; /* disable queuing */
1168
1169 u8 reserved5:1;
1170 u8 rac:1; /* report a check */
1171 u8 reserved6:2;
1172 u8 swp:1; /* software write protect */
1173 u8 raerp:1; /* ready AER permission */
1174 u8 uaaerp:1; /* unit attenstion AER permission */
1175 u8 eaerp:1; /* error AER permission */
1176
1177 u8 reserved7:5;
1178 u8 autoload_mod:3;
1179#else
1180 u8 rlec:1; /* report log exception condition */
1181 u8 gltsd:1; /* global logging target save disable */
1182 u8 reserved3:3;
1183 u8 tst:3; /* task set type */
1184
1185 u8 dque:1; /* disable queuing */
1186 u8 qerr:2; /* queue error management */
1187 u8 reserved4:1;
1188 u8 qalgo_mod:4; /* queue alogorithm modifier */
1189
1190 u8 eaerp:1; /* error AER permission */
1191 u8 uaaerp:1; /* unit attenstion AER permission */
1192 u8 raerp:1; /* ready AER permission */
1193 u8 swp:1; /* software write protect */
1194 u8 reserved6:2;
1195 u8 rac:1; /* report a check */
1196 u8 reserved5:1;
1197
1198 u8 autoload_mod:3;
1199 u8 reserved7:5;
1200#endif
1201 u8 rahp_msb; /* ready AER holdoff period - MSB */
1202 u8 rahp_lsb; /* ready AER holdoff period - LSB */
1203
1204 u8 busy_timeout_period_msb;
1205 u8 busy_timeout_period_lsb;
1206
1207 u8 ext_selftest_compl_time_msb;
1208 u8 ext_selftest_compl_time_lsb;
1209};
1210
1211/*
1212 * SCSI medium types supported mode page
1213 */
1214struct scsi_mp_medium_types_sup_s{
1215#ifdef __BIGENDIAN
1216 u8 ps:1;
1217 u8 reserved1:1;
1218 u8 page_code:6;
1219#else
1220 u8 page_code:6;
1221 u8 reserved1:1;
1222 u8 ps:1;
1223#endif
1224 u8 page_len;
1225
1226 u8 reserved3[2];
1227 u8 med_type1_sup; /* medium type one supported */
1228 u8 med_type2_sup; /* medium type two supported */
1229 u8 med_type3_sup; /* medium type three supported */
1230 u8 med_type4_sup; /* medium type four supported */
1231};
1232
1233/*
1234 * SCSI informational exception control mode page
1235 */
1236struct scsi_mp_info_excpt_cntl_s{
1237#ifdef __BIGENDIAN
1238 u8 ps:1;
1239 u8 reserved1:1;
1240 u8 page_code:6;
1241#else
1242 u8 page_code:6;
1243 u8 reserved1:1;
1244 u8 ps:1;
1245#endif
1246 u8 page_len;
1247#ifdef __BIGENDIAN
1248 u8 perf:1; /* performance */
1249 u8 reserved3:1;
1250 u8 ebf:1; /* enable background fucntion */
1251 u8 ewasc:1; /* enable warning */
1252 u8 dexcpt:1; /* disable exception control */
1253 u8 test:1; /* enable test device failure
1254 * notification
1255 */
1256 u8 reserved4:1;
1257 u8 log_error:1;
1258
1259 u8 reserved5:4;
1260 u8 mrie:4; /* method of reporting info
1261 * exceptions
1262 */
1263#else
1264 u8 log_error:1;
1265 u8 reserved4:1;
1266 u8 test:1; /* enable test device failure
1267 * notification
1268 */
1269 u8 dexcpt:1; /* disable exception control */
1270 u8 ewasc:1; /* enable warning */
1271 u8 ebf:1; /* enable background fucntion */
1272 u8 reserved3:1;
1273 u8 perf:1; /* performance */
1274
1275 u8 mrie:4; /* method of reporting info
1276 * exceptions
1277 */
1278 u8 reserved5:4;
1279#endif
1280 u8 interval_timer_msb;
1281 u8 interval_timer_lsb;
1282
1283 u8 report_count_msb;
1284 u8 report_count_lsb;
1285};
1286
1287/*
1288 * Methods of reporting informational exceptions
1289 */
1290#define SCSI_MP_IEC_NO_REPORT 0x0 /* no reporting of exceptions */
1291#define SCSI_MP_IEC_AER 0x1 /* async event reporting */
1292#define SCSI_MP_IEC_UNIT_ATTN 0x2 /* generate unit attenstion */
1293#define SCSI_MO_IEC_COND_REC_ERR 0x3 /* conditionally generate recovered
1294 * error
1295 */
1296#define SCSI_MP_IEC_UNCOND_REC_ERR 0x4 /* unconditionally generate recovered
1297 * error
1298 */
1299#define SCSI_MP_IEC_NO_SENSE 0x5 /* generate no sense */
1300#define SCSI_MP_IEC_ON_REQUEST 0x6 /* only report exceptions on request */
1301
1302/*
1303 * SCSI flexible disk page
1304 */
1305struct scsi_mp_flexible_disk_s{
1306#ifdef __BIGENDIAN
1307 u8 ps:1;
1308 u8 reserved1:1;
1309 u8 page_code:6;
1310#else
1311 u8 page_code:6;
1312 u8 reserved1:1;
1313 u8 ps:1;
1314#endif
1315 u8 page_len;
1316
1317 u8 transfer_rate_msb;
1318 u8 transfer_rate_lsb;
1319
1320 u8 num_heads;
1321 u8 num_sectors;
1322
1323 u8 bytes_per_sector_msb;
1324 u8 bytes_per_sector_lsb;
1325
1326 u8 num_cylinders_msb;
1327 u8 num_cylinders_lsb;
1328
1329 u8 sc_wpc_msb; /* starting cylinder-write
1330 * precompensation msb
1331 */
1332 u8 sc_wpc_lsb; /* starting cylinder-write
1333 * precompensation lsb
1334 */
1335 u8 sc_rwc_msb; /* starting cylinder-reduced write
1336 * current msb
1337 */
1338 u8 sc_rwc_lsb; /* starting cylinder-reduced write
1339 * current lsb
1340 */
1341
1342 u8 dev_step_rate_msb;
1343 u8 dev_step_rate_lsb;
1344
1345 u8 dev_step_pulse_width;
1346
1347 u8 head_sd_msb; /* head settle delay msb */
1348 u8 head_sd_lsb; /* head settle delay lsb */
1349
1350 u8 motor_on_delay;
1351 u8 motor_off_delay;
1352#ifdef __BIGENDIAN
1353 u8 trdy:1; /* true ready bit */
1354 u8 ssn:1; /* start sector number bit */
1355 u8 mo:1; /* motor on bit */
1356 u8 reserved3:5;
1357
1358 u8 reserved4:4;
1359 u8 spc:4; /* step pulse per cylinder */
1360#else
1361 u8 reserved3:5;
1362 u8 mo:1; /* motor on bit */
1363 u8 ssn:1; /* start sector number bit */
1364 u8 trdy:1; /* true ready bit */
1365
1366 u8 spc:4; /* step pulse per cylinder */
1367 u8 reserved4:4;
1368#endif
1369 u8 write_comp;
1370 u8 head_load_delay;
1371 u8 head_unload_delay;
1372#ifdef __BIGENDIAN
1373 u8 pin34:4; /* pin34 usage */
1374 u8 pin2:4; /* pin2 usage */
1375
1376 u8 pin4:4; /* pin4 usage */
1377 u8 pin1:4; /* pin1 usage */
1378#else
1379 u8 pin2:4; /* pin2 usage */
1380 u8 pin34:4; /* pin34 usage */
1381
1382 u8 pin1:4; /* pin1 usage */
1383 u8 pin4:4; /* pin4 usage */
1384#endif
1385 u8 med_rot_rate_msb;
1386 u8 med_rot_rate_lsb;
1387
1388 u8 reserved5[2];
1389};
1390
1391struct scsi_mode_page_format_data6_s{
1392 struct scsi_mode_param_header6_s mph; /* mode page header */
1393 struct scsi_mode_param_desc_s desc; /* block descriptor */
1394 struct scsi_mp_format_device_s format; /* format device data */
1395};
1396
1397struct scsi_mode_page_format_data10_s{
1398 struct scsi_mode_param_header10_s mph; /* mode page header */
1399 struct scsi_mode_param_desc_s desc; /* block descriptor */
1400 struct scsi_mp_format_device_s format; /* format device data */
1401};
1402
1403struct scsi_mode_page_rdg_data6_s{
1404 struct scsi_mode_param_header6_s mph; /* mode page header */
1405 struct scsi_mode_param_desc_s desc; /* block descriptor */
1406 struct scsi_mp_rigid_device_geometry_s rdg;
1407 /* rigid geometry data */
1408};
1409
1410struct scsi_mode_page_rdg_data10_s{
1411 struct scsi_mode_param_header10_s mph; /* mode page header */
1412 struct scsi_mode_param_desc_s desc; /* block descriptor */
1413 struct scsi_mp_rigid_device_geometry_s rdg;
1414 /* rigid geometry data */
1415};
1416
1417struct scsi_mode_page_cache6_s{
1418 struct scsi_mode_param_header6_s mph; /* mode page header */
1419 struct scsi_mode_param_desc_s desc; /* block descriptor */
1420 struct scsi_mp_caching_s cache; /* cache page data */
1421};
1422
1423struct scsi_mode_page_cache10_s{
1424 struct scsi_mode_param_header10_s mph; /* mode page header */
1425 struct scsi_mode_param_desc_s desc; /* block descriptor */
1426 struct scsi_mp_caching_s cache; /* cache page data */
1427};
1428
1429/* --------------------------------------------------------------
1430 * Format Unit command
1431 * ------------------------------------------------------------
1432 */
1433
1434/*
1435 * Format Unit CDB
1436 */
1437struct scsi_format_unit_s{
1438 u8 opcode;
1439#ifdef __BIGENDIAN
1440 u8 res1:3;
1441 u8 fmtdata:1; /* if set, data out phase has format
1442 * data
1443 */
1444 u8 cmplst:1; /* if set, defect list is complete */
1445 u8 def_list:3; /* format of defect descriptor is
1446 * fmtdata =1
1447 */
1448#else
1449 u8 def_list:3; /* format of defect descriptor is
1450 * fmtdata = 1
1451 */
1452 u8 cmplst:1; /* if set, defect list is complete */
1453 u8 fmtdata:1; /* if set, data out phase has format
1454 * data
1455 */
1456 u8 res1:3;
1457#endif
1458 u8 interleave_msb;
1459 u8 interleave_lsb;
1460 u8 vendor_spec;
1461 u8 control;
1462};
1463
1464/*
1465 * h
1466 */
1467struct scsi_reserve6_s{
1468 u8 opcode;
1469#ifdef __BIGENDIAN
1470 u8 reserved:3;
1471 u8 obsolete:4;
1472 u8 extent:1;
1473#else
1474 u8 extent:1;
1475 u8 obsolete:4;
1476 u8 reserved:3;
1477#endif
1478 u8 reservation_id;
1479 u16 param_list_len;
1480 u8 control;
1481};
1482
1483/*
1484 * h
1485 */
1486struct scsi_release6_s{
1487 u8 opcode;
1488#ifdef __BIGENDIAN
1489 u8 reserved1:3;
1490 u8 obsolete:4;
1491 u8 extent:1;
1492#else
1493 u8 extent:1;
1494 u8 obsolete:4;
1495 u8 reserved1:3;
1496#endif
1497 u8 reservation_id;
1498 u16 reserved2;
1499 u8 control;
1500};
1501
1502/*
1503 * h
1504 */
1505struct scsi_reserve10_s{
1506 u8 opcode;
1507#ifdef __BIGENDIAN
1508 u8 reserved1:3;
1509 u8 third_party:1;
1510 u8 reserved2:2;
1511 u8 long_id:1;
1512 u8 extent:1;
1513#else
1514 u8 extent:1;
1515 u8 long_id:1;
1516 u8 reserved2:2;
1517 u8 third_party:1;
1518 u8 reserved1:3;
1519#endif
1520 u8 reservation_id;
1521 u8 third_pty_dev_id;
1522 u8 reserved3;
1523 u8 reserved4;
1524 u8 reserved5;
1525 u16 param_list_len;
1526 u8 control;
1527};
1528
1529struct scsi_release10_s{
1530 u8 opcode;
1531#ifdef __BIGENDIAN
1532 u8 reserved1:3;
1533 u8 third_party:1;
1534 u8 reserved2:2;
1535 u8 long_id:1;
1536 u8 extent:1;
1537#else
1538 u8 extent:1;
1539 u8 long_id:1;
1540 u8 reserved2:2;
1541 u8 third_party:1;
1542 u8 reserved1:3;
1543#endif
1544 u8 reservation_id;
1545 u8 third_pty_dev_id;
1546 u8 reserved3;
1547 u8 reserved4;
1548 u8 reserved5;
1549 u16 param_list_len;
1550 u8 control;
1551};
1552
1553struct scsi_verify10_s{
1554 u8 opcode;
1555#ifdef __BIGENDIAN
1556 u8 lun:3;
1557 u8 dpo:1;
1558 u8 reserved:2;
1559 u8 bytchk:1;
1560 u8 reladdr:1;
1561#else
1562 u8 reladdr:1;
1563 u8 bytchk:1;
1564 u8 reserved:2;
1565 u8 dpo:1;
1566 u8 lun:3;
1567#endif
1568 u8 lba0;
1569 u8 lba1;
1570 u8 lba2;
1571 u8 lba3;
1572 u8 reserved1;
1573 u8 verification_len0;
1574 u8 verification_len1;
1575 u8 control_byte;
1576};
1577
1578struct scsi_request_sense_s{
1579 u8 opcode;
1580#ifdef __BIGENDIAN
1581 u8 lun:3;
1582 u8 reserved:5;
1583#else
1584 u8 reserved:5;
1585 u8 lun:3;
1586#endif
1587 u8 reserved0;
1588 u8 reserved1;
1589 u8 alloc_len;
1590 u8 control_byte;
1591};
1592
1593/* ------------------------------------------------------------
1594 * SCSI status byte values
1595 * ------------------------------------------------------------
1596 */
1597#define SCSI_STATUS_GOOD 0x00
1598#define SCSI_STATUS_CHECK_CONDITION 0x02
1599#define SCSI_STATUS_CONDITION_MET 0x04
1600#define SCSI_STATUS_BUSY 0x08
1601#define SCSI_STATUS_INTERMEDIATE 0x10
1602#define SCSI_STATUS_ICM 0x14 /* intermediate condition met */
1603#define SCSI_STATUS_RESERVATION_CONFLICT 0x18
1604#define SCSI_STATUS_COMMAND_TERMINATED 0x22
1605#define SCSI_STATUS_QUEUE_FULL 0x28
1606#define SCSI_STATUS_ACA_ACTIVE 0x30
1607
1608#define SCSI_MAX_ALLOC_LEN 0xFF /* maximum allocarion length
1609 * in CDBs
1610 */
1611
1612#define SCSI_OP_WRITE_VERIFY10 0x2E
1613#define SCSI_OP_WRITE_VERIFY12 0xAE
1614#define SCSI_OP_UNDEF 0xFF
1615
1616/*
1617 * SCSI WRITE-VERIFY(10) command
1618 */
1619struct scsi_write_verify10_s{
1620 u8 opcode;
1621#ifdef __BIGENDIAN
1622 u8 reserved1:3;
1623 u8 dpo:1; /* Disable Page Out */
1624 u8 reserved2:1;
1625 u8 ebp:1; /* erse by-pass */
1626 u8 bytchk:1; /* byte check */
1627 u8 rel_adr:1; /* relative address */
1628#else
1629 u8 rel_adr:1; /* relative address */
1630 u8 bytchk:1; /* byte check */
1631 u8 ebp:1; /* erse by-pass */
1632 u8 reserved2:1;
1633 u8 dpo:1; /* Disable Page Out */
1634 u8 reserved1:3;
1635#endif
1636 u8 lba0; /* logical block address - MSB */
1637 u8 lba1;
1638 u8 lba2;
1639 u8 lba3; /* LSB */
1640 u8 reserved3;
1641 u8 xfer_length0; /* transfer length in blocks - MSB */
1642 u8 xfer_length1; /* LSB */
1643 u8 control;
1644};
1645
1646#pragma pack()
1647
1648#endif /* __SCSI_H__ */
diff --git a/drivers/scsi/bfa/include/protocol/types.h b/drivers/scsi/bfa/include/protocol/types.h
new file mode 100644
index 000000000000..2875a6cced3b
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/types.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * types.h Protocol defined base types
20 */
21
22#ifndef __TYPES_H__
23#define __TYPES_H__
24
25#include <bfa_os_inc.h>
26
27#define wwn_t u64
28#define lun_t u64
29
30#define WWN_NULL (0)
31#define FC_SYMNAME_MAX 256 /* max name server symbolic name size */
32#define FC_ALPA_MAX 128
33
34#pragma pack(1)
35
36#define MAC_ADDRLEN (6)
37struct mac_s { u8 mac[MAC_ADDRLEN]; };
38#define mac_t struct mac_s
39
40#pragma pack()
41
42#endif
diff --git a/drivers/scsi/bfa/loop.c b/drivers/scsi/bfa/loop.c
new file mode 100644
index 000000000000..a418dedebe9e
--- /dev/null
+++ b/drivers/scsi/bfa/loop.c
@@ -0,0 +1,422 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * port_loop.c vport private loop implementation.
20 */
21#include <bfa.h>
22#include <bfa_svc.h>
23#include "fcs_lport.h"
24#include "fcs_rport.h"
25#include "fcs_trcmod.h"
26#include "lport_priv.h"
27
28BFA_TRC_FILE(FCS, LOOP);
29
30/**
31 * ALPA to LIXA bitmap mapping
32 *
33 * ALPA 0x00 (Word 0, Bit 30) is invalid for N_Ports. Also Word 0 Bit 31
34 * is for L_bit (login required) and is filled as ALPA 0x00 here.
35 */
36static const u8 port_loop_alpa_map[] = {
37 0xEF, 0xE8, 0xE4, 0xE2, 0xE1, 0xE0, 0xDC, 0xDA, /* Word 3 Bits 0..7 */
38 0xD9, 0xD6, 0xD5, 0xD4, 0xD3, 0xD2, 0xD1, 0xCE, /* Word 3 Bits 8..15 */
39 0xCD, 0xCC, 0xCB, 0xCA, 0xC9, 0xC7, 0xC6, 0xC5, /* Word 3 Bits 16..23 */
40 0xC3, 0xBC, 0xBA, 0xB9, 0xB6, 0xB5, 0xB4, 0xB3, /* Word 3 Bits 24..31 */
41
42 0xB2, 0xB1, 0xAE, 0xAD, 0xAC, 0xAB, 0xAA, 0xA9, /* Word 2 Bits 0..7 */
43 0xA7, 0xA6, 0xA5, 0xA3, 0x9F, 0x9E, 0x9D, 0x9B, /* Word 2 Bits 8..15 */
44 0x98, 0x97, 0x90, 0x8F, 0x88, 0x84, 0x82, 0x81, /* Word 2 Bits 16..23 */
45 0x80, 0x7C, 0x7A, 0x79, 0x76, 0x75, 0x74, 0x73, /* Word 2 Bits 24..31 */
46
47 0x72, 0x71, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, /* Word 1 Bits 0..7 */
48 0x67, 0x66, 0x65, 0x63, 0x5C, 0x5A, 0x59, 0x56, /* Word 1 Bits 8..15 */
49 0x55, 0x54, 0x53, 0x52, 0x51, 0x4E, 0x4D, 0x4C, /* Word 1 Bits 16..23 */
50 0x4B, 0x4A, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3C, /* Word 1 Bits 24..31 */
51
52 0x3A, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, /* Word 0 Bits 0..7 */
53 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x27, 0x26, /* Word 0 Bits 8..15 */
54 0x25, 0x23, 0x1F, 0x1E, 0x1D, 0x1B, 0x18, 0x17, /* Word 0 Bits 16..23 */
55 0x10, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, /* Word 0 Bits 24..31 */
56};
57
58/*
59 * Local Functions
60 */
61bfa_status_t bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port,
62 u8 alpa);
63
64void bfa_fcs_port_loop_plogi_response(void *fcsarg,
65 struct bfa_fcxp_s *fcxp,
66 void *cbarg,
67 bfa_status_t req_status,
68 u32 rsp_len,
69 u32 resid_len,
70 struct fchs_s *rsp_fchs);
71
72bfa_status_t bfa_fcs_port_loop_send_adisc(struct bfa_fcs_port_s *port,
73 u8 alpa);
74
75void bfa_fcs_port_loop_adisc_response(void *fcsarg,
76 struct bfa_fcxp_s *fcxp,
77 void *cbarg,
78 bfa_status_t req_status,
79 u32 rsp_len,
80 u32 resid_len,
81 struct fchs_s *rsp_fchs);
82
83bfa_status_t bfa_fcs_port_loop_send_plogi_acc(struct bfa_fcs_port_s *port,
84 u8 alpa);
85
86void bfa_fcs_port_loop_plogi_acc_response(void *fcsarg,
87 struct bfa_fcxp_s *fcxp,
88 void *cbarg,
89 bfa_status_t req_status,
90 u32 rsp_len,
91 u32 resid_len,
92 struct fchs_s *rsp_fchs);
93
94bfa_status_t bfa_fcs_port_loop_send_adisc_acc(struct bfa_fcs_port_s *port,
95 u8 alpa);
96
97void bfa_fcs_port_loop_adisc_acc_response(void *fcsarg,
98 struct bfa_fcxp_s *fcxp,
99 void *cbarg,
100 bfa_status_t req_status,
101 u32 rsp_len,
102 u32 resid_len,
103 struct fchs_s *rsp_fchs);
104/**
105 * Called by port to initializar in provate LOOP topology.
106 */
107void
108bfa_fcs_port_loop_init(struct bfa_fcs_port_s *port)
109{
110}
111
112/**
113 * Called by port to notify transition to online state.
114 */
115void
116bfa_fcs_port_loop_online(struct bfa_fcs_port_s *port)
117{
118
119 u8 num_alpa = port->port_topo.ploop.num_alpa;
120 u8 *alpa_pos_map = port->port_topo.ploop.alpa_pos_map;
121 struct bfa_fcs_rport_s *r_port;
122 int ii = 0;
123
124 /*
125 * If the port role is Initiator Mode, create Rports.
126 */
127 if (port->port_cfg.roles == BFA_PORT_ROLE_FCP_IM) {
128 /*
129 * Check if the ALPA positional bitmap is available.
130 * if not, we send PLOGI to all possible ALPAs.
131 */
132 if (num_alpa > 0) {
133 for (ii = 0; ii < num_alpa; ii++) {
134 /*
135 * ignore ALPA of bfa port
136 */
137 if (alpa_pos_map[ii] != port->pid) {
138 r_port = bfa_fcs_rport_create(port,
139 alpa_pos_map[ii]);
140 }
141 }
142 } else {
143 for (ii = 0; ii < MAX_ALPA_COUNT; ii++) {
144 /*
145 * ignore ALPA of bfa port
146 */
147 if ((port_loop_alpa_map[ii] > 0)
148 && (port_loop_alpa_map[ii] != port->pid))
149 bfa_fcs_port_loop_send_plogi(port,
150 port_loop_alpa_map[ii]);
151 /**TBD */
152 }
153 }
154 } else {
155 /*
156 * TBD Target Mode ??
157 */
158 }
159
160}
161
162/**
163 * Called by port to notify transition to offline state.
164 */
165void
166bfa_fcs_port_loop_offline(struct bfa_fcs_port_s *port)
167{
168
169}
170
171/**
172 * Called by port to notify a LIP on the loop.
173 */
174void
175bfa_fcs_port_loop_lip(struct bfa_fcs_port_s *port)
176{
177}
178
179/**
180 * Local Functions.
181 */
182bfa_status_t
183bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port, u8 alpa)
184{
185 struct fchs_s fchs;
186 struct bfa_fcxp_s *fcxp = NULL;
187 int len;
188
189 bfa_trc(port->fcs, alpa);
190
191 fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
192 NULL);
193 bfa_assert(fcxp);
194
195 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
196 bfa_fcs_port_get_fcid(port), 0,
197 port->port_cfg.pwwn, port->port_cfg.nwwn,
198 bfa_pport_get_maxfrsize(port->fcs->bfa));
199
200 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
201 FC_CLASS_3, len, &fchs,
202 bfa_fcs_port_loop_plogi_response, (void *)port,
203 FC_MAX_PDUSZ, FC_RA_TOV);
204
205 return BFA_STATUS_OK;
206}
207
208/**
209 * Called by fcxp to notify the Plogi response
210 */
211void
212bfa_fcs_port_loop_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
213 void *cbarg, bfa_status_t req_status,
214 u32 rsp_len, u32 resid_len,
215 struct fchs_s *rsp_fchs)
216{
217 struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
218 struct fc_logi_s *plogi_resp;
219 struct fc_els_cmd_s *els_cmd;
220
221 bfa_trc(port->fcs, req_status);
222
223 /*
224 * Sanity Checks
225 */
226 if (req_status != BFA_STATUS_OK) {
227 bfa_trc(port->fcs, req_status);
228 /*
229 * @todo
230 * This could mean that the device with this APLA does not
231 * exist on the loop.
232 */
233
234 return;
235 }
236
237 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
238 plogi_resp = (struct fc_logi_s *) els_cmd;
239
240 if (els_cmd->els_code == FC_ELS_ACC) {
241 bfa_fcs_rport_start(port, rsp_fchs, plogi_resp);
242 } else {
243 bfa_trc(port->fcs, plogi_resp->els_cmd.els_code);
244 bfa_assert(0);
245 }
246}
247
248bfa_status_t
249bfa_fcs_port_loop_send_plogi_acc(struct bfa_fcs_port_s *port, u8 alpa)
250{
251 struct fchs_s fchs;
252 struct bfa_fcxp_s *fcxp;
253 int len;
254
255 bfa_trc(port->fcs, alpa);
256
257 fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
258 NULL);
259 bfa_assert(fcxp);
260
261 len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
262 bfa_fcs_port_get_fcid(port), 0,
263 port->port_cfg.pwwn, port->port_cfg.nwwn,
264 bfa_pport_get_maxfrsize(port->fcs->bfa));
265
266 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
267 FC_CLASS_3, len, &fchs,
268 bfa_fcs_port_loop_plogi_acc_response,
269 (void *)port, FC_MAX_PDUSZ, 0); /* No response
270 * expected
271 */
272
273 return BFA_STATUS_OK;
274}
275
276/*
277 * Plogi Acc Response
278 * We donot do any processing here.
279 */
280void
281bfa_fcs_port_loop_plogi_acc_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
282 void *cbarg, bfa_status_t req_status,
283 u32 rsp_len, u32 resid_len,
284 struct fchs_s *rsp_fchs)
285{
286
287 struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
288
289 bfa_trc(port->fcs, port->pid);
290
291 /*
292 * Sanity Checks
293 */
294 if (req_status != BFA_STATUS_OK) {
295 bfa_trc(port->fcs, req_status);
296 return;
297 }
298}
299
300bfa_status_t
301bfa_fcs_port_loop_send_adisc(struct bfa_fcs_port_s *port, u8 alpa)
302{
303 struct fchs_s fchs;
304 struct bfa_fcxp_s *fcxp;
305 int len;
306
307 bfa_trc(port->fcs, alpa);
308
309 fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
310 NULL);
311 bfa_assert(fcxp);
312
313 len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
314 bfa_fcs_port_get_fcid(port), 0,
315 port->port_cfg.pwwn, port->port_cfg.nwwn);
316
317 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
318 FC_CLASS_3, len, &fchs,
319 bfa_fcs_port_loop_adisc_response, (void *)port,
320 FC_MAX_PDUSZ, FC_RA_TOV);
321
322 return BFA_STATUS_OK;
323}
324
325/**
326 * Called by fcxp to notify the ADISC response
327 */
328void
329bfa_fcs_port_loop_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
330 void *cbarg, bfa_status_t req_status,
331 u32 rsp_len, u32 resid_len,
332 struct fchs_s *rsp_fchs)
333{
334 struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
335 struct bfa_fcs_rport_s *rport;
336 struct fc_adisc_s *adisc_resp;
337 struct fc_els_cmd_s *els_cmd;
338 u32 pid = rsp_fchs->s_id;
339
340 bfa_trc(port->fcs, req_status);
341
342 /*
343 * Sanity Checks
344 */
345 if (req_status != BFA_STATUS_OK) {
346 /*
347 * TBD : we may need to retry certain requests
348 */
349 bfa_fcxp_free(fcxp);
350 return;
351 }
352
353 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
354 adisc_resp = (struct fc_adisc_s *) els_cmd;
355
356 if (els_cmd->els_code == FC_ELS_ACC) {
357 } else {
358 bfa_trc(port->fcs, adisc_resp->els_cmd.els_code);
359
360 /*
361 * TBD: we may need to check for reject codes and retry
362 */
363 rport = bfa_fcs_port_get_rport_by_pid(port, pid);
364 if (rport) {
365 list_del(&rport->qe);
366 bfa_fcs_rport_delete(rport);
367 }
368
369 }
370 return;
371}
372
373bfa_status_t
374bfa_fcs_port_loop_send_adisc_acc(struct bfa_fcs_port_s *port, u8 alpa)
375{
376 struct fchs_s fchs;
377 struct bfa_fcxp_s *fcxp;
378 int len;
379
380 bfa_trc(port->fcs, alpa);
381
382 fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
383 NULL);
384 bfa_assert(fcxp);
385
386 len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
387 bfa_fcs_port_get_fcid(port), 0,
388 port->port_cfg.pwwn, port->port_cfg.nwwn);
389
390 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
391 FC_CLASS_3, len, &fchs,
392 bfa_fcs_port_loop_adisc_acc_response,
393 (void *)port, FC_MAX_PDUSZ, 0); /* no reponse
394 * expected
395 */
396
397 return BFA_STATUS_OK;
398}
399
400/*
401 * Adisc Acc Response
402 * We donot do any processing here.
403 */
404void
405bfa_fcs_port_loop_adisc_acc_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
406 void *cbarg, bfa_status_t req_status,
407 u32 rsp_len, u32 resid_len,
408 struct fchs_s *rsp_fchs)
409{
410
411 struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
412
413 bfa_trc(port->fcs, port->pid);
414
415 /*
416 * Sanity Checks
417 */
418 if (req_status != BFA_STATUS_OK) {
419 bfa_trc(port->fcs, req_status);
420 return;
421 }
422}
diff --git a/drivers/scsi/bfa/lport_api.c b/drivers/scsi/bfa/lport_api.c
new file mode 100644
index 000000000000..8f51a83f1834
--- /dev/null
+++ b/drivers/scsi/bfa/lport_api.c
@@ -0,0 +1,291 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * port_api.c BFA FCS port
20 */
21
22#include <fcs/bfa_fcs.h>
23#include <fcs/bfa_fcs_lport.h>
24#include <fcs/bfa_fcs_rport.h>
25#include "fcs_rport.h"
26#include "fcs_fabric.h"
27#include "fcs_trcmod.h"
28#include "fcs_vport.h"
29
30BFA_TRC_FILE(FCS, PORT_API);
31
32
33
34/**
35 * fcs_port_api BFA FCS port API
36 */
37
38void
39bfa_fcs_cfg_base_port(struct bfa_fcs_s *fcs, struct bfa_port_cfg_s *port_cfg)
40{
41}
42
43struct bfa_fcs_port_s *
44bfa_fcs_get_base_port(struct bfa_fcs_s *fcs)
45{
46 return (&fcs->fabric.bport);
47}
48
49wwn_t
50bfa_fcs_port_get_rport(struct bfa_fcs_port_s *port, wwn_t wwn, int index,
51 int nrports, bfa_boolean_t bwwn)
52{
53 struct list_head *qh, *qe;
54 struct bfa_fcs_rport_s *rport = NULL;
55 int i;
56 struct bfa_fcs_s *fcs;
57
58 if (port == NULL || nrports == 0)
59 return (wwn_t) 0;
60
61 fcs = port->fcs;
62 bfa_trc(fcs, (u32) nrports);
63
64 i = 0;
65 qh = &port->rport_q;
66 qe = bfa_q_first(qh);
67
68 while ((qe != qh) && (i < nrports)) {
69 rport = (struct bfa_fcs_rport_s *)qe;
70 if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) {
71 qe = bfa_q_next(qe);
72 bfa_trc(fcs, (u32) rport->pwwn);
73 bfa_trc(fcs, rport->pid);
74 bfa_trc(fcs, i);
75 continue;
76 }
77
78 if (bwwn) {
79 if (!memcmp(&wwn, &rport->pwwn, 8))
80 break;
81 } else {
82 if (i == index)
83 break;
84 }
85
86 i++;
87 qe = bfa_q_next(qe);
88 }
89
90 bfa_trc(fcs, i);
91 if (rport) {
92 return rport->pwwn;
93 } else {
94 return (wwn_t) 0;
95 }
96}
97
98void
99bfa_fcs_port_get_rports(struct bfa_fcs_port_s *port, wwn_t rport_wwns[],
100 int *nrports)
101{
102 struct list_head *qh, *qe;
103 struct bfa_fcs_rport_s *rport = NULL;
104 int i;
105 struct bfa_fcs_s *fcs;
106
107 if (port == NULL || rport_wwns == NULL || *nrports == 0)
108 return;
109
110 fcs = port->fcs;
111 bfa_trc(fcs, (u32) *nrports);
112
113 i = 0;
114 qh = &port->rport_q;
115 qe = bfa_q_first(qh);
116
117 while ((qe != qh) && (i < *nrports)) {
118 rport = (struct bfa_fcs_rport_s *)qe;
119 if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) {
120 qe = bfa_q_next(qe);
121 bfa_trc(fcs, (u32) rport->pwwn);
122 bfa_trc(fcs, rport->pid);
123 bfa_trc(fcs, i);
124 continue;
125 }
126
127 rport_wwns[i] = rport->pwwn;
128
129 i++;
130 qe = bfa_q_next(qe);
131 }
132
133 bfa_trc(fcs, i);
134 *nrports = i;
135 return;
136}
137
138/*
139 * Iterate's through all the rport's in the given port to
140 * determine the maximum operating speed.
141 */
142enum bfa_pport_speed
143bfa_fcs_port_get_rport_max_speed(struct bfa_fcs_port_s *port)
144{
145 struct list_head *qh, *qe;
146 struct bfa_fcs_rport_s *rport = NULL;
147 struct bfa_fcs_s *fcs;
148 enum bfa_pport_speed max_speed = 0;
149 struct bfa_pport_attr_s pport_attr;
150 enum bfa_pport_speed pport_speed;
151
152 if (port == NULL)
153 return 0;
154
155 fcs = port->fcs;
156
157 /*
158 * Get Physical port's current speed
159 */
160 bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
161 pport_speed = pport_attr.speed;
162 bfa_trc(fcs, pport_speed);
163
164 qh = &port->rport_q;
165 qe = bfa_q_first(qh);
166
167 while (qe != qh) {
168 rport = (struct bfa_fcs_rport_s *)qe;
169 if ((bfa_os_ntoh3b(rport->pid) > 0xFFF000)
170 || (bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE)) {
171 qe = bfa_q_next(qe);
172 continue;
173 }
174
175 if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_8GBPS)
176 || (rport->rpf.rpsc_speed > pport_speed)) {
177 max_speed = rport->rpf.rpsc_speed;
178 break;
179 } else if (rport->rpf.rpsc_speed > max_speed) {
180 max_speed = rport->rpf.rpsc_speed;
181 }
182
183 qe = bfa_q_next(qe);
184 }
185
186 bfa_trc(fcs, max_speed);
187 return max_speed;
188}
189
190struct bfa_fcs_port_s *
191bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn)
192{
193 struct bfa_fcs_vport_s *vport;
194 bfa_fcs_vf_t *vf;
195
196 bfa_assert(fcs != NULL);
197
198 vf = bfa_fcs_vf_lookup(fcs, vf_id);
199 if (vf == NULL) {
200 bfa_trc(fcs, vf_id);
201 return (NULL);
202 }
203
204 if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn))
205 return (&vf->bport);
206
207 vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn);
208 if (vport)
209 return (&vport->lport);
210
211 return (NULL);
212}
213
214/*
215 * API corresponding to VmWare's NPIV_VPORT_GETINFO.
216 */
217void
218bfa_fcs_port_get_info(struct bfa_fcs_port_s *port,
219 struct bfa_port_info_s *port_info)
220{
221
222 bfa_trc(port->fcs, port->fabric->fabric_name);
223
224 if (port->vport == NULL) {
225 /*
226 * This is a Physical port
227 */
228 port_info->port_type = BFA_PORT_TYPE_PHYSICAL;
229
230 /*
231 * @todo : need to fix the state & reason
232 */
233 port_info->port_state = 0;
234 port_info->offline_reason = 0;
235
236 port_info->port_wwn = bfa_fcs_port_get_pwwn(port);
237 port_info->node_wwn = bfa_fcs_port_get_nwwn(port);
238
239 port_info->max_vports_supp = bfa_fcs_vport_get_max(port->fcs);
240 port_info->num_vports_inuse =
241 bfa_fcs_fabric_vport_count(port->fabric);
242 port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
243 port_info->num_rports_inuse = port->num_rports;
244 } else {
245 /*
246 * This is a virtual port
247 */
248 port_info->port_type = BFA_PORT_TYPE_VIRTUAL;
249
250 /*
251 * @todo : need to fix the state & reason
252 */
253 port_info->port_state = 0;
254 port_info->offline_reason = 0;
255
256 port_info->port_wwn = bfa_fcs_port_get_pwwn(port);
257 port_info->node_wwn = bfa_fcs_port_get_nwwn(port);
258 }
259}
260
261void
262bfa_fcs_port_get_stats(struct bfa_fcs_port_s *fcs_port,
263 struct bfa_port_stats_s *port_stats)
264{
265 bfa_os_memcpy(port_stats, &fcs_port->stats,
266 sizeof(struct bfa_port_stats_s));
267 return;
268}
269
270void
271bfa_fcs_port_clear_stats(struct bfa_fcs_port_s *fcs_port)
272{
273 bfa_os_memset(&fcs_port->stats, 0, sizeof(struct bfa_port_stats_s));
274 return;
275}
276
277void
278bfa_fcs_port_enable_ipfc_roles(struct bfa_fcs_port_s *fcs_port)
279{
280 fcs_port->port_cfg.roles |= BFA_PORT_ROLE_FCP_IPFC;
281 return;
282}
283
284void
285bfa_fcs_port_disable_ipfc_roles(struct bfa_fcs_port_s *fcs_port)
286{
287 fcs_port->port_cfg.roles &= ~BFA_PORT_ROLE_FCP_IPFC;
288 return;
289}
290
291
diff --git a/drivers/scsi/bfa/lport_priv.h b/drivers/scsi/bfa/lport_priv.h
new file mode 100644
index 000000000000..dbae370a599a
--- /dev/null
+++ b/drivers/scsi/bfa/lport_priv.h
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) 2005-2009 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#ifndef __VP_PRIV_H__
19#define __VP_PRIV_H__
20
21#include <fcs/bfa_fcs_lport.h>
22#include <fcs/bfa_fcs_vport.h>
23
24/*
25 * Functions exported by vps
26 */
27void bfa_fcs_vport_init(struct bfa_fcs_vport_s *vport);
28
29/*
30 * Functions exported by vps
31 */
32void bfa_fcs_vps_online(struct bfa_fcs_port_s *port);
33void bfa_fcs_vps_offline(struct bfa_fcs_port_s *port);
34void bfa_fcs_vps_lip(struct bfa_fcs_port_s *port);
35
36/*
37 * Functions exported by port_fab
38 */
39void bfa_fcs_port_fab_init(struct bfa_fcs_port_s *vport);
40void bfa_fcs_port_fab_online(struct bfa_fcs_port_s *vport);
41void bfa_fcs_port_fab_offline(struct bfa_fcs_port_s *vport);
42void bfa_fcs_port_fab_rx_frame(struct bfa_fcs_port_s *port,
43 u8 *rx_frame, u32 len);
44
45/*
46 * Functions exported by VP-NS.
47 */
48void bfa_fcs_port_ns_init(struct bfa_fcs_port_s *vport);
49void bfa_fcs_port_ns_offline(struct bfa_fcs_port_s *vport);
50void bfa_fcs_port_ns_online(struct bfa_fcs_port_s *vport);
51void bfa_fcs_port_ns_query(struct bfa_fcs_port_s *port);
52
53/*
54 * Functions exported by VP-SCN
55 */
56void bfa_fcs_port_scn_init(struct bfa_fcs_port_s *vport);
57void bfa_fcs_port_scn_offline(struct bfa_fcs_port_s *vport);
58void bfa_fcs_port_scn_online(struct bfa_fcs_port_s *vport);
59void bfa_fcs_port_scn_process_rscn(struct bfa_fcs_port_s *port,
60 struct fchs_s *rx_frame, u32 len);
61
62/*
63 * Functions exported by VP-N2N
64 */
65
66void bfa_fcs_port_n2n_init(struct bfa_fcs_port_s *port);
67void bfa_fcs_port_n2n_online(struct bfa_fcs_port_s *port);
68void bfa_fcs_port_n2n_offline(struct bfa_fcs_port_s *port);
69void bfa_fcs_port_n2n_rx_frame(struct bfa_fcs_port_s *port,
70 u8 *rx_frame, u32 len);
71
72/*
73 * Functions exported by VP-LOOP
74 */
75void bfa_fcs_port_loop_init(struct bfa_fcs_port_s *port);
76void bfa_fcs_port_loop_online(struct bfa_fcs_port_s *port);
77void bfa_fcs_port_loop_offline(struct bfa_fcs_port_s *port);
78void bfa_fcs_port_loop_lip(struct bfa_fcs_port_s *port);
79void bfa_fcs_port_loop_rx_frame(struct bfa_fcs_port_s *port,
80 u8 *rx_frame, u32 len);
81
82#endif /* __VP_PRIV_H__ */
diff --git a/drivers/scsi/bfa/ms.c b/drivers/scsi/bfa/ms.c
new file mode 100644
index 000000000000..c96b3ca007ae
--- /dev/null
+++ b/drivers/scsi/bfa/ms.c
@@ -0,0 +1,759 @@
1/*
2 * Copyright (c) 2005-2009 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
19#include <bfa.h>
20#include <bfa_svc.h>
21#include "fcs_lport.h"
22#include "fcs_rport.h"
23#include "fcs_trcmod.h"
24#include "fcs_fcxp.h"
25#include "lport_priv.h"
26
27BFA_TRC_FILE(FCS, MS);
28
29#define BFA_FCS_MS_CMD_MAX_RETRIES 2
30/*
31 * forward declarations
32 */
33static void bfa_fcs_port_ms_send_plogi(void *ms_cbarg,
34 struct bfa_fcxp_s *fcxp_alloced);
35static void bfa_fcs_port_ms_timeout(void *arg);
36static void bfa_fcs_port_ms_plogi_response(void *fcsarg,
37 struct bfa_fcxp_s *fcxp,
38 void *cbarg,
39 bfa_status_t req_status,
40 u32 rsp_len,
41 u32 resid_len,
42 struct fchs_s *rsp_fchs);
43
44static void bfa_fcs_port_ms_send_gmal(void *ms_cbarg,
45 struct bfa_fcxp_s *fcxp_alloced);
46static void bfa_fcs_port_ms_gmal_response(void *fcsarg,
47 struct bfa_fcxp_s *fcxp,
48 void *cbarg,
49 bfa_status_t req_status,
50 u32 rsp_len,
51 u32 resid_len,
52 struct fchs_s *rsp_fchs);
53static void bfa_fcs_port_ms_send_gfn(void *ms_cbarg,
54 struct bfa_fcxp_s *fcxp_alloced);
55static void bfa_fcs_port_ms_gfn_response(void *fcsarg,
56 struct bfa_fcxp_s *fcxp,
57 void *cbarg,
58 bfa_status_t req_status,
59 u32 rsp_len,
60 u32 resid_len,
61 struct fchs_s *rsp_fchs);
62/**
63 * fcs_ms_sm FCS MS state machine
64 */
65
66/**
67 * MS State Machine events
68 */
69enum port_ms_event {
70 MSSM_EVENT_PORT_ONLINE = 1,
71 MSSM_EVENT_PORT_OFFLINE = 2,
72 MSSM_EVENT_RSP_OK = 3,
73 MSSM_EVENT_RSP_ERROR = 4,
74 MSSM_EVENT_TIMEOUT = 5,
75 MSSM_EVENT_FCXP_SENT = 6,
76 MSSM_EVENT_PORT_FABRIC_RSCN = 7
77};
78
79static void bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms,
80 enum port_ms_event event);
81static void bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms,
82 enum port_ms_event event);
83static void bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms,
84 enum port_ms_event event);
85static void bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms,
86 enum port_ms_event event);
87static void bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms,
88 enum port_ms_event event);
89static void bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms,
90 enum port_ms_event event);
91static void bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms,
92 enum port_ms_event event);
93static void bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms,
94 enum port_ms_event event);
95static void bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms,
96 enum port_ms_event event);
97static void bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms,
98 enum port_ms_event event);
99static void bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
100 enum port_ms_event event);
101/**
102 * Start in offline state - awaiting NS to send start.
103 */
104static void
105bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms,
106 enum port_ms_event event)
107{
108 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
109 bfa_trc(ms->port->fcs, event);
110
111 switch (event) {
112 case MSSM_EVENT_PORT_ONLINE:
113 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_sending);
114 bfa_fcs_port_ms_send_plogi(ms, NULL);
115 break;
116
117 case MSSM_EVENT_PORT_OFFLINE:
118 break;
119
120 default:
121 bfa_assert(0);
122 }
123}
124
125static void
126bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms,
127 enum port_ms_event event)
128{
129 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
130 bfa_trc(ms->port->fcs, event);
131
132 switch (event) {
133 case MSSM_EVENT_FCXP_SENT:
134 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi);
135 break;
136
137 case MSSM_EVENT_PORT_OFFLINE:
138 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
139 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
140 &ms->fcxp_wqe);
141 break;
142
143 default:
144 bfa_assert(0);
145 }
146}
147
148static void
149bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
150{
151 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
152 bfa_trc(ms->port->fcs, event);
153
154 switch (event) {
155 case MSSM_EVENT_RSP_ERROR:
156 /*
157 * Start timer for a delayed retry
158 */
159 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_retry);
160 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), &ms->timer,
161 bfa_fcs_port_ms_timeout, ms,
162 BFA_FCS_RETRY_TIMEOUT);
163 break;
164
165 case MSSM_EVENT_RSP_OK:
166 /*
167 * since plogi is done, now invoke MS related sub-modules
168 */
169 bfa_fcs_port_fdmi_online(ms);
170
171 /**
172 * if this is a Vport, go to online state.
173 */
174 if (ms->port->vport) {
175 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
176 break;
177 }
178
179 /*
180 * For a base port we need to get the
181 * switch's IP address.
182 */
183 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_sending);
184 bfa_fcs_port_ms_send_gmal(ms, NULL);
185 break;
186
187 case MSSM_EVENT_PORT_OFFLINE:
188 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
189 bfa_fcxp_discard(ms->fcxp);
190 break;
191
192 default:
193 bfa_assert(0);
194 }
195}
196
197static void
198bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms,
199 enum port_ms_event event)
200{
201 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
202 bfa_trc(ms->port->fcs, event);
203
204 switch (event) {
205 case MSSM_EVENT_TIMEOUT:
206 /*
207 * Retry Timer Expired. Re-send
208 */
209 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_sending);
210 bfa_fcs_port_ms_send_plogi(ms, NULL);
211 break;
212
213 case MSSM_EVENT_PORT_OFFLINE:
214 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
215 bfa_timer_stop(&ms->timer);
216 break;
217
218 default:
219 bfa_assert(0);
220 }
221}
222
223static void
224bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
225 enum port_ms_event event)
226{
227 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
228 bfa_trc(ms->port->fcs, event);
229
230 switch (event) {
231 case MSSM_EVENT_PORT_OFFLINE:
232 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
233 /*
234 * now invoke MS related sub-modules
235 */
236 bfa_fcs_port_fdmi_offline(ms);
237 break;
238
239 case MSSM_EVENT_PORT_FABRIC_RSCN:
240 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
241 ms->retry_cnt = 0;
242 bfa_fcs_port_ms_send_gfn(ms, NULL);
243 break;
244
245 default:
246 bfa_assert(0);
247 }
248}
249
250static void
251bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms,
252 enum port_ms_event event)
253{
254 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
255 bfa_trc(ms->port->fcs, event);
256
257 switch (event) {
258 case MSSM_EVENT_FCXP_SENT:
259 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal);
260 break;
261
262 case MSSM_EVENT_PORT_OFFLINE:
263 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
264 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
265 &ms->fcxp_wqe);
266 break;
267
268 default:
269 bfa_assert(0);
270 }
271}
272
273static void
274bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
275{
276 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
277 bfa_trc(ms->port->fcs, event);
278
279 switch (event) {
280 case MSSM_EVENT_RSP_ERROR:
281 /*
282 * Start timer for a delayed retry
283 */
284 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
285 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_retry);
286 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
287 &ms->timer, bfa_fcs_port_ms_timeout, ms,
288 BFA_FCS_RETRY_TIMEOUT);
289 } else {
290 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
291 bfa_fcs_port_ms_send_gfn(ms, NULL);
292 ms->retry_cnt = 0;
293 }
294 break;
295
296 case MSSM_EVENT_RSP_OK:
297 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
298 bfa_fcs_port_ms_send_gfn(ms, NULL);
299 break;
300
301 case MSSM_EVENT_PORT_OFFLINE:
302 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
303 bfa_fcxp_discard(ms->fcxp);
304 break;
305
306 default:
307 bfa_assert(0);
308 }
309}
310
311static void
312bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms,
313 enum port_ms_event event)
314{
315 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
316 bfa_trc(ms->port->fcs, event);
317
318 switch (event) {
319 case MSSM_EVENT_TIMEOUT:
320 /*
321 * Retry Timer Expired. Re-send
322 */
323 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_sending);
324 bfa_fcs_port_ms_send_gmal(ms, NULL);
325 break;
326
327 case MSSM_EVENT_PORT_OFFLINE:
328 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
329 bfa_timer_stop(&ms->timer);
330 break;
331
332 default:
333 bfa_assert(0);
334 }
335}
336
337/**
338 * ms_pvt MS local functions
339 */
340
341static void
342bfa_fcs_port_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
343{
344 struct bfa_fcs_port_ms_s *ms = ms_cbarg;
345 struct bfa_fcs_port_s *port = ms->port;
346 struct fchs_s fchs;
347 int len;
348 struct bfa_fcxp_s *fcxp;
349
350 bfa_trc(port->fcs, port->pid);
351
352 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
353 if (!fcxp) {
354 bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
355 bfa_fcs_port_ms_send_gmal, ms);
356 return;
357 }
358 ms->fcxp = fcxp;
359
360 len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
361 bfa_fcs_port_get_fcid(port),
362 bfa_lps_get_peer_nwwn(port->fabric->lps));
363
364 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
365 FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gmal_response,
366 (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
367
368 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
369}
370
371static void
372bfa_fcs_port_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
373 void *cbarg, bfa_status_t req_status,
374 u32 rsp_len, u32 resid_len,
375 struct fchs_s *rsp_fchs)
376{
377 struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
378 struct bfa_fcs_port_s *port = ms->port;
379 struct ct_hdr_s *cthdr = NULL;
380 struct fcgs_gmal_resp_s *gmal_resp;
381 struct fc_gmal_entry_s *gmal_entry;
382 u32 num_entries;
383 u8 *rsp_str;
384
385 bfa_trc(port->fcs, req_status);
386 bfa_trc(port->fcs, port->port_cfg.pwwn);
387
388 /*
389 * Sanity Checks
390 */
391 if (req_status != BFA_STATUS_OK) {
392 bfa_trc(port->fcs, req_status);
393 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
394 return;
395 }
396
397 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
398 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
399
400 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
401 gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1);
402 num_entries = bfa_os_ntohl(gmal_resp->ms_len);
403 if (num_entries == 0) {
404 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
405 return;
406 }
407 /*
408 * The response could contain multiple Entries.
409 * Entries for SNMP interface, etc.
410 * We look for the entry with a telnet prefix.
411 * First "http://" entry refers to IP addr
412 */
413
414 gmal_entry = (struct fc_gmal_entry_s *)gmal_resp->ms_ma;
415 while (num_entries > 0) {
416 if (strncmp
417 (gmal_entry->prefix, CT_GMAL_RESP_PREFIX_HTTP,
418 sizeof(gmal_entry->prefix)) == 0) {
419
420 /*
421 * if the IP address is terminating with a '/',
422 * remove it. *Byte 0 consists of the length
423 * of the string.
424 */
425 rsp_str = &(gmal_entry->prefix[0]);
426 if (rsp_str[gmal_entry->len - 1] == '/')
427 rsp_str[gmal_entry->len - 1] = 0;
428 /*
429 * copy IP Address to fabric
430 */
431 strncpy(bfa_fcs_port_get_fabric_ipaddr(port),
432 gmal_entry->ip_addr,
433 BFA_FCS_FABRIC_IPADDR_SZ);
434 break;
435 } else {
436 --num_entries;
437 ++gmal_entry;
438 }
439 }
440
441 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
442 return;
443 }
444
445 bfa_trc(port->fcs, cthdr->reason_code);
446 bfa_trc(port->fcs, cthdr->exp_code);
447 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
448}
449
450static void
451bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms,
452 enum port_ms_event event)
453{
454 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
455 bfa_trc(ms->port->fcs, event);
456
457 switch (event) {
458 case MSSM_EVENT_FCXP_SENT:
459 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn);
460 break;
461
462 case MSSM_EVENT_PORT_OFFLINE:
463 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
464 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
465 &ms->fcxp_wqe);
466 break;
467
468 default:
469 bfa_assert(0);
470 }
471}
472
473static void
474bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
475{
476 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
477 bfa_trc(ms->port->fcs, event);
478
479 switch (event) {
480 case MSSM_EVENT_RSP_ERROR:
481 /*
482 * Start timer for a delayed retry
483 */
484 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
485 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_retry);
486 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
487 &ms->timer, bfa_fcs_port_ms_timeout, ms,
488 BFA_FCS_RETRY_TIMEOUT);
489 } else {
490 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
491 ms->retry_cnt = 0;
492 }
493 break;
494
495 case MSSM_EVENT_RSP_OK:
496 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
497 break;
498
499 case MSSM_EVENT_PORT_OFFLINE:
500 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
501 bfa_fcxp_discard(ms->fcxp);
502 break;
503
504 default:
505 bfa_assert(0);
506 }
507}
508
509static void
510bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms,
511 enum port_ms_event event)
512{
513 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
514 bfa_trc(ms->port->fcs, event);
515
516 switch (event) {
517 case MSSM_EVENT_TIMEOUT:
518 /*
519 * Retry Timer Expired. Re-send
520 */
521 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
522 bfa_fcs_port_ms_send_gfn(ms, NULL);
523 break;
524
525 case MSSM_EVENT_PORT_OFFLINE:
526 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
527 bfa_timer_stop(&ms->timer);
528 break;
529
530 default:
531 bfa_assert(0);
532 }
533}
534
535/**
536 * ms_pvt MS local functions
537 */
538
539static void
540bfa_fcs_port_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
541{
542 struct bfa_fcs_port_ms_s *ms = ms_cbarg;
543 struct bfa_fcs_port_s *port = ms->port;
544 struct fchs_s fchs;
545 int len;
546 struct bfa_fcxp_s *fcxp;
547
548 bfa_trc(port->fcs, port->pid);
549
550 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
551 if (!fcxp) {
552 bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
553 bfa_fcs_port_ms_send_gfn, ms);
554 return;
555 }
556 ms->fcxp = fcxp;
557
558 len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
559 bfa_fcs_port_get_fcid(port),
560 bfa_lps_get_peer_nwwn(port->fabric->lps));
561
562 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
563 FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gfn_response,
564 (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
565
566 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
567}
568
569static void
570bfa_fcs_port_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
571 bfa_status_t req_status, u32 rsp_len,
572 u32 resid_len, struct fchs_s *rsp_fchs)
573{
574 struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
575 struct bfa_fcs_port_s *port = ms->port;
576 struct ct_hdr_s *cthdr = NULL;
577 wwn_t *gfn_resp;
578
579 bfa_trc(port->fcs, req_status);
580 bfa_trc(port->fcs, port->port_cfg.pwwn);
581
582 /*
583 * Sanity Checks
584 */
585 if (req_status != BFA_STATUS_OK) {
586 bfa_trc(port->fcs, req_status);
587 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
588 return;
589 }
590
591 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
592 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
593
594 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
595 gfn_resp = (wwn_t *) (cthdr + 1);
596 /*
597 * check if it has actually changed
598 */
599 if ((memcmp
600 ((void *)&bfa_fcs_port_get_fabric_name(port), gfn_resp,
601 sizeof(wwn_t)) != 0))
602 bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp);
603 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
604 return;
605 }
606
607 bfa_trc(port->fcs, cthdr->reason_code);
608 bfa_trc(port->fcs, cthdr->exp_code);
609 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
610}
611
612/**
613 * ms_pvt MS local functions
614 */
615
616static void
617bfa_fcs_port_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
618{
619 struct bfa_fcs_port_ms_s *ms = ms_cbarg;
620 struct bfa_fcs_port_s *port = ms->port;
621 struct fchs_s fchs;
622 int len;
623 struct bfa_fcxp_s *fcxp;
624
625 bfa_trc(port->fcs, port->pid);
626
627 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
628 if (!fcxp) {
629 port->stats.ms_plogi_alloc_wait++;
630 bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
631 bfa_fcs_port_ms_send_plogi, ms);
632 return;
633 }
634 ms->fcxp = fcxp;
635
636 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
637 bfa_os_hton3b(FC_MGMT_SERVER),
638 bfa_fcs_port_get_fcid(port), 0,
639 port->port_cfg.pwwn, port->port_cfg.nwwn,
640 bfa_pport_get_maxfrsize(port->fcs->bfa));
641
642 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
643 FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response,
644 (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
645
646 port->stats.ms_plogi_sent++;
647 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
648}
649
650static void
651bfa_fcs_port_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
652 void *cbarg, bfa_status_t req_status,
653 u32 rsp_len, u32 resid_len,
654 struct fchs_s *rsp_fchs)
655{
656 struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
657
658 struct bfa_fcs_port_s *port = ms->port;
659 struct fc_els_cmd_s *els_cmd;
660 struct fc_ls_rjt_s *ls_rjt;
661
662 bfa_trc(port->fcs, req_status);
663 bfa_trc(port->fcs, port->port_cfg.pwwn);
664
665 /*
666 * Sanity Checks
667 */
668 if (req_status != BFA_STATUS_OK) {
669 port->stats.ms_plogi_rsp_err++;
670 bfa_trc(port->fcs, req_status);
671 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
672 return;
673 }
674
675 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
676
677 switch (els_cmd->els_code) {
678
679 case FC_ELS_ACC:
680 if (rsp_len < sizeof(struct fc_logi_s)) {
681 bfa_trc(port->fcs, rsp_len);
682 port->stats.ms_plogi_acc_err++;
683 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
684 break;
685 }
686 port->stats.ms_plogi_accepts++;
687 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
688 break;
689
690 case FC_ELS_LS_RJT:
691 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
692
693 bfa_trc(port->fcs, ls_rjt->reason_code);
694 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
695
696 port->stats.ms_rejects++;
697 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
698 break;
699
700 default:
701 port->stats.ms_plogi_unknown_rsp++;
702 bfa_trc(port->fcs, els_cmd->els_code);
703 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
704 }
705}
706
707static void
708bfa_fcs_port_ms_timeout(void *arg)
709{
710 struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)arg;
711
712 ms->port->stats.ms_timeouts++;
713 bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT);
714}
715
716
717void
718bfa_fcs_port_ms_init(struct bfa_fcs_port_s *port)
719{
720 struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
721
722 ms->port = port;
723 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
724
725 /*
726 * Invoke init routines of sub modules.
727 */
728 bfa_fcs_port_fdmi_init(ms);
729}
730
731void
732bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port)
733{
734 struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
735
736 ms->port = port;
737 bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
738}
739
740void
741bfa_fcs_port_ms_online(struct bfa_fcs_port_s *port)
742{
743 struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
744
745 ms->port = port;
746 bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE);
747}
748
749void
750bfa_fcs_port_ms_fabric_rscn(struct bfa_fcs_port_s *port)
751{
752 struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
753
754 /*
755 * @todo. Handle this only when in Online state
756 */
757 if (bfa_sm_cmp_state(ms, bfa_fcs_port_ms_sm_online))
758 bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN);
759}
diff --git a/drivers/scsi/bfa/n2n.c b/drivers/scsi/bfa/n2n.c
new file mode 100644
index 000000000000..735456824346
--- /dev/null
+++ b/drivers/scsi/bfa/n2n.c
@@ -0,0 +1,105 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * n2n.c n2n implementation.
20 */
21#include <bfa.h>
22#include <bfa_svc.h>
23#include "fcs_lport.h"
24#include "fcs_rport.h"
25#include "fcs_trcmod.h"
26#include "lport_priv.h"
27
28BFA_TRC_FILE(FCS, N2N);
29
30/**
31 * Called by fcs/port to initialize N2N topology.
32 */
33void
34bfa_fcs_port_n2n_init(struct bfa_fcs_port_s *port)
35{
36}
37
38/**
39 * Called by fcs/port to notify transition to online state.
40 */
41void
42bfa_fcs_port_n2n_online(struct bfa_fcs_port_s *port)
43{
44 struct bfa_fcs_port_n2n_s *n2n_port = &port->port_topo.pn2n;
45 struct bfa_port_cfg_s *pcfg = &port->port_cfg;
46 struct bfa_fcs_rport_s *rport;
47
48 bfa_trc(port->fcs, pcfg->pwwn);
49
50 /*
51 * If our PWWN is > than that of the r-port, we have to initiate PLOGI
52 * and assign an Address. if not, we need to wait for its PLOGI.
53 *
54 * If our PWWN is < than that of the remote port, it will send a PLOGI
55 * with the PIDs assigned. The rport state machine take care of this
56 * incoming PLOGI.
57 */
58 if (memcmp
59 ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
60 sizeof(wwn_t)) > 0) {
61 port->pid = N2N_LOCAL_PID;
62 /**
63 * First, check if we know the device by pwwn.
64 */
65 rport = bfa_fcs_port_get_rport_by_pwwn(port,
66 n2n_port->rem_port_wwn);
67 if (rport) {
68 bfa_trc(port->fcs, rport->pid);
69 bfa_trc(port->fcs, rport->pwwn);
70 rport->pid = N2N_REMOTE_PID;
71 bfa_fcs_rport_online(rport);
72 return;
73 }
74
75 /*
76 * In n2n there can be only one rport. Delete the old one whose
77 * pid should be zero, because it is offline.
78 */
79 if (port->num_rports > 0) {
80 rport = bfa_fcs_port_get_rport_by_pid(port, 0);
81 bfa_assert(rport != NULL);
82 if (rport) {
83 bfa_trc(port->fcs, rport->pwwn);
84 bfa_fcs_rport_delete(rport);
85 }
86 }
87 bfa_fcs_rport_create(port, N2N_REMOTE_PID);
88 }
89}
90
91/**
92 * Called by fcs/port to notify transition to offline state.
93 */
94void
95bfa_fcs_port_n2n_offline(struct bfa_fcs_port_s *port)
96{
97 struct bfa_fcs_port_n2n_s *n2n_port = &port->port_topo.pn2n;
98
99 bfa_trc(port->fcs, port->pid);
100 port->pid = 0;
101 n2n_port->rem_port_wwn = 0;
102 n2n_port->reply_oxid = 0;
103}
104
105
diff --git a/drivers/scsi/bfa/ns.c b/drivers/scsi/bfa/ns.c
new file mode 100644
index 000000000000..59fea99d67a4
--- /dev/null
+++ b/drivers/scsi/bfa/ns.c
@@ -0,0 +1,1243 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * @page ns_sm_info VPORT NS State Machine
20 *
21 * @section ns_sm_interactions VPORT NS State Machine Interactions
22 *
23 * @section ns_sm VPORT NS State Machine
24 * img ns_sm.jpg
25 */
26#include <bfa.h>
27#include <bfa_svc.h>
28#include <bfa_iocfc.h>
29#include "fcs_lport.h"
30#include "fcs_rport.h"
31#include "fcs_trcmod.h"
32#include "fcs_fcxp.h"
33#include "fcs.h"
34#include "lport_priv.h"
35
36BFA_TRC_FILE(FCS, NS);
37
38/*
39 * forward declarations
40 */
41static void bfa_fcs_port_ns_send_plogi(void *ns_cbarg,
42 struct bfa_fcxp_s *fcxp_alloced);
43static void bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg,
44 struct bfa_fcxp_s *fcxp_alloced);
45static void bfa_fcs_port_ns_send_rft_id(void *ns_cbarg,
46 struct bfa_fcxp_s *fcxp_alloced);
47static void bfa_fcs_port_ns_send_rff_id(void *ns_cbarg,
48 struct bfa_fcxp_s *fcxp_alloced);
49static void bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg,
50 struct bfa_fcxp_s *fcxp_alloced);
51static void bfa_fcs_port_ns_timeout(void *arg);
52static void bfa_fcs_port_ns_plogi_response(void *fcsarg,
53 struct bfa_fcxp_s *fcxp,
54 void *cbarg,
55 bfa_status_t req_status,
56 u32 rsp_len,
57 u32 resid_len,
58 struct fchs_s *rsp_fchs);
59static void bfa_fcs_port_ns_rspn_id_response(void *fcsarg,
60 struct bfa_fcxp_s *fcxp,
61 void *cbarg,
62 bfa_status_t req_status,
63 u32 rsp_len,
64 u32 resid_len,
65 struct fchs_s *rsp_fchs);
66static void bfa_fcs_port_ns_rft_id_response(void *fcsarg,
67 struct bfa_fcxp_s *fcxp,
68 void *cbarg,
69 bfa_status_t req_status,
70 u32 rsp_len,
71 u32 resid_len,
72 struct fchs_s *rsp_fchs);
73static void bfa_fcs_port_ns_rff_id_response(void *fcsarg,
74 struct bfa_fcxp_s *fcxp,
75 void *cbarg,
76 bfa_status_t req_status,
77 u32 rsp_len,
78 u32 resid_len,
79 struct fchs_s *rsp_fchs);
80static void bfa_fcs_port_ns_gid_ft_response(void *fcsarg,
81 struct bfa_fcxp_s *fcxp,
82 void *cbarg,
83 bfa_status_t req_status,
84 u32 rsp_len,
85 u32 resid_len,
86 struct fchs_s *rsp_fchs);
87static void bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port,
88 u32 *pid_buf,
89 u32 n_pids);
90
91static void bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port);
92/**
93 * fcs_ns_sm FCS nameserver interface state machine
94 */
95
96/**
97 * VPort NS State Machine events
98 */
99enum vport_ns_event {
100 NSSM_EVENT_PORT_ONLINE = 1,
101 NSSM_EVENT_PORT_OFFLINE = 2,
102 NSSM_EVENT_PLOGI_SENT = 3,
103 NSSM_EVENT_RSP_OK = 4,
104 NSSM_EVENT_RSP_ERROR = 5,
105 NSSM_EVENT_TIMEOUT = 6,
106 NSSM_EVENT_NS_QUERY = 7,
107 NSSM_EVENT_RSPNID_SENT = 8,
108 NSSM_EVENT_RFTID_SENT = 9,
109 NSSM_EVENT_RFFID_SENT = 10,
110 NSSM_EVENT_GIDFT_SENT = 11,
111};
112
113static void bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns,
114 enum vport_ns_event event);
115static void bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns,
116 enum vport_ns_event event);
117static void bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns,
118 enum vport_ns_event event);
119static void bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns,
120 enum vport_ns_event event);
121static void bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns,
122 enum vport_ns_event event);
123static void bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns,
124 enum vport_ns_event event);
125static void bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns,
126 enum vport_ns_event event);
127static void bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns,
128 enum vport_ns_event event);
129static void bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns,
130 enum vport_ns_event event);
131static void bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns,
132 enum vport_ns_event event);
133static void bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns,
134 enum vport_ns_event event);
135static void bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns,
136 enum vport_ns_event event);
137static void bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns,
138 enum vport_ns_event event);
139static void bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns,
140 enum vport_ns_event event);
141static void bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns,
142 enum vport_ns_event event);
143static void bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns,
144 enum vport_ns_event event);
145static void bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns,
146 enum vport_ns_event event);
147/**
148 * Start in offline state - awaiting linkup
149 */
150static void
151bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns,
152 enum vport_ns_event event)
153{
154 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
155 bfa_trc(ns->port->fcs, event);
156
157 switch (event) {
158 case NSSM_EVENT_PORT_ONLINE:
159 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_sending);
160 bfa_fcs_port_ns_send_plogi(ns, NULL);
161 break;
162
163 case NSSM_EVENT_PORT_OFFLINE:
164 break;
165
166 default:
167 bfa_assert(0);
168 }
169}
170
171static void
172bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns,
173 enum vport_ns_event event)
174{
175 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
176 bfa_trc(ns->port->fcs, event);
177
178 switch (event) {
179 case NSSM_EVENT_PLOGI_SENT:
180 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi);
181 break;
182
183 case NSSM_EVENT_PORT_OFFLINE:
184 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
185 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
186 &ns->fcxp_wqe);
187 break;
188
189 default:
190 bfa_assert(0);
191 }
192}
193
194static void
195bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns,
196 enum vport_ns_event event)
197{
198 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
199 bfa_trc(ns->port->fcs, event);
200
201 switch (event) {
202 case NSSM_EVENT_RSP_ERROR:
203 /*
204 * Start timer for a delayed retry
205 */
206 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_retry);
207 ns->port->stats.ns_retries++;
208 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
209 bfa_fcs_port_ns_timeout, ns,
210 BFA_FCS_RETRY_TIMEOUT);
211 break;
212
213 case NSSM_EVENT_RSP_OK:
214 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rspn_id);
215 bfa_fcs_port_ns_send_rspn_id(ns, NULL);
216 break;
217
218 case NSSM_EVENT_PORT_OFFLINE:
219 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
220 bfa_fcxp_discard(ns->fcxp);
221 break;
222
223 default:
224 bfa_assert(0);
225 }
226}
227
228static void
229bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns,
230 enum vport_ns_event event)
231{
232 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
233 bfa_trc(ns->port->fcs, event);
234
235 switch (event) {
236 case NSSM_EVENT_TIMEOUT:
237 /*
238 * Retry Timer Expired. Re-send
239 */
240 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_sending);
241 bfa_fcs_port_ns_send_plogi(ns, NULL);
242 break;
243
244 case NSSM_EVENT_PORT_OFFLINE:
245 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
246 bfa_timer_stop(&ns->timer);
247 break;
248
249 default:
250 bfa_assert(0);
251 }
252}
253
254static void
255bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns,
256 enum vport_ns_event event)
257{
258 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
259 bfa_trc(ns->port->fcs, event);
260
261 switch (event) {
262 case NSSM_EVENT_RSPNID_SENT:
263 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rspn_id);
264 break;
265
266 case NSSM_EVENT_PORT_OFFLINE:
267 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
268 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
269 &ns->fcxp_wqe);
270 break;
271
272 default:
273 bfa_assert(0);
274 }
275}
276
277static void
278bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns,
279 enum vport_ns_event event)
280{
281 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
282 bfa_trc(ns->port->fcs, event);
283
284 switch (event) {
285 case NSSM_EVENT_RSP_ERROR:
286 /*
287 * Start timer for a delayed retry
288 */
289 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rspn_id_retry);
290 ns->port->stats.ns_retries++;
291 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
292 bfa_fcs_port_ns_timeout, ns,
293 BFA_FCS_RETRY_TIMEOUT);
294 break;
295
296 case NSSM_EVENT_RSP_OK:
297 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rft_id);
298 bfa_fcs_port_ns_send_rft_id(ns, NULL);
299 break;
300
301 case NSSM_EVENT_PORT_OFFLINE:
302 bfa_fcxp_discard(ns->fcxp);
303 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
304 break;
305
306 default:
307 bfa_assert(0);
308 }
309}
310
311static void
312bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns,
313 enum vport_ns_event event)
314{
315 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
316 bfa_trc(ns->port->fcs, event);
317
318 switch (event) {
319 case NSSM_EVENT_TIMEOUT:
320 /*
321 * Retry Timer Expired. Re-send
322 */
323 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rspn_id);
324 bfa_fcs_port_ns_send_rspn_id(ns, NULL);
325 break;
326
327 case NSSM_EVENT_PORT_OFFLINE:
328 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
329 bfa_timer_stop(&ns->timer);
330 break;
331
332 default:
333 bfa_assert(0);
334 }
335}
336
337static void
338bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns,
339 enum vport_ns_event event)
340{
341 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
342 bfa_trc(ns->port->fcs, event);
343
344 switch (event) {
345 case NSSM_EVENT_RFTID_SENT:
346 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rft_id);
347 break;
348
349 case NSSM_EVENT_PORT_OFFLINE:
350 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
351 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
352 &ns->fcxp_wqe);
353 break;
354
355 default:
356 bfa_assert(0);
357 }
358}
359
360static void
361bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns,
362 enum vport_ns_event event)
363{
364 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
365 bfa_trc(ns->port->fcs, event);
366
367 switch (event) {
368 case NSSM_EVENT_RSP_OK:
369 /*
370 * Now move to register FC4 Features
371 */
372 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rff_id);
373 bfa_fcs_port_ns_send_rff_id(ns, NULL);
374 break;
375
376 case NSSM_EVENT_RSP_ERROR:
377 /*
378 * Start timer for a delayed retry
379 */
380 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rft_id_retry);
381 ns->port->stats.ns_retries++;
382 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
383 bfa_fcs_port_ns_timeout, ns,
384 BFA_FCS_RETRY_TIMEOUT);
385 break;
386
387 case NSSM_EVENT_PORT_OFFLINE:
388 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
389 bfa_fcxp_discard(ns->fcxp);
390 break;
391
392 default:
393 bfa_assert(0);
394 }
395}
396
397static void
398bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns,
399 enum vport_ns_event event)
400{
401 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
402 bfa_trc(ns->port->fcs, event);
403
404 switch (event) {
405 case NSSM_EVENT_TIMEOUT:
406 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rft_id);
407 bfa_fcs_port_ns_send_rft_id(ns, NULL);
408 break;
409
410 case NSSM_EVENT_PORT_OFFLINE:
411 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
412 bfa_timer_stop(&ns->timer);
413 break;
414
415 default:
416 bfa_assert(0);
417 }
418}
419
420static void
421bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns,
422 enum vport_ns_event event)
423{
424 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
425 bfa_trc(ns->port->fcs, event);
426
427 switch (event) {
428 case NSSM_EVENT_RFFID_SENT:
429 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rff_id);
430 break;
431
432 case NSSM_EVENT_PORT_OFFLINE:
433 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
434 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
435 &ns->fcxp_wqe);
436 break;
437
438 default:
439 bfa_assert(0);
440 }
441}
442
443static void
444bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns,
445 enum vport_ns_event event)
446{
447 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
448 bfa_trc(ns->port->fcs, event);
449
450 switch (event) {
451 case NSSM_EVENT_RSP_OK:
452
453 /*
454 * If min cfg mode is enabled, we donot initiate rport
455 * discovery with the fabric. Instead, we will retrieve the
456 * boot targets from HAL/FW.
457 */
458 if (__fcs_min_cfg(ns->port->fcs)) {
459 bfa_fcs_port_ns_boot_target_disc(ns->port);
460 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online);
461 return;
462 }
463
464 /*
465 * If the port role is Initiator Mode issue NS query.
466 * If it is Target Mode, skip this and go to online.
467 */
468 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
469 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft);
470 bfa_fcs_port_ns_send_gid_ft(ns, NULL);
471 } else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port)) {
472 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online);
473 }
474 /*
475 * kick off mgmt srvr state machine
476 */
477 bfa_fcs_port_ms_online(ns->port);
478 break;
479
480 case NSSM_EVENT_RSP_ERROR:
481 /*
482 * Start timer for a delayed retry
483 */
484 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rff_id_retry);
485 ns->port->stats.ns_retries++;
486 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
487 bfa_fcs_port_ns_timeout, ns,
488 BFA_FCS_RETRY_TIMEOUT);
489 break;
490
491 case NSSM_EVENT_PORT_OFFLINE:
492 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
493 bfa_fcxp_discard(ns->fcxp);
494 break;
495
496 default:
497 bfa_assert(0);
498 }
499}
500
501static void
502bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns,
503 enum vport_ns_event event)
504{
505 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
506 bfa_trc(ns->port->fcs, event);
507
508 switch (event) {
509 case NSSM_EVENT_TIMEOUT:
510 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rff_id);
511 bfa_fcs_port_ns_send_rff_id(ns, NULL);
512 break;
513
514 case NSSM_EVENT_PORT_OFFLINE:
515 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
516 bfa_timer_stop(&ns->timer);
517 break;
518
519 default:
520 bfa_assert(0);
521 }
522}
523static void
524bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns,
525 enum vport_ns_event event)
526{
527 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
528 bfa_trc(ns->port->fcs, event);
529
530 switch (event) {
531 case NSSM_EVENT_GIDFT_SENT:
532 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_gid_ft);
533 break;
534
535 case NSSM_EVENT_PORT_OFFLINE:
536 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
537 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
538 &ns->fcxp_wqe);
539 break;
540
541 default:
542 bfa_assert(0);
543 }
544}
545
546static void
547bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns,
548 enum vport_ns_event event)
549{
550 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
551 bfa_trc(ns->port->fcs, event);
552
553 switch (event) {
554 case NSSM_EVENT_RSP_OK:
555 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online);
556 break;
557
558 case NSSM_EVENT_RSP_ERROR:
559 /*
560 * TBD: for certain reject codes, we don't need to retry
561 */
562 /*
563 * Start timer for a delayed retry
564 */
565 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_gid_ft_retry);
566 ns->port->stats.ns_retries++;
567 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
568 bfa_fcs_port_ns_timeout, ns,
569 BFA_FCS_RETRY_TIMEOUT);
570 break;
571
572 case NSSM_EVENT_PORT_OFFLINE:
573 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
574 bfa_fcxp_discard(ns->fcxp);
575 break;
576
577 default:
578 bfa_assert(0);
579 }
580}
581
582static void
583bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns,
584 enum vport_ns_event event)
585{
586 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
587 bfa_trc(ns->port->fcs, event);
588
589 switch (event) {
590 case NSSM_EVENT_TIMEOUT:
591 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft);
592 bfa_fcs_port_ns_send_gid_ft(ns, NULL);
593 break;
594
595 case NSSM_EVENT_PORT_OFFLINE:
596 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
597 bfa_timer_stop(&ns->timer);
598 break;
599
600 default:
601 bfa_assert(0);
602 }
603}
604
605static void
606bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns,
607 enum vport_ns_event event)
608{
609 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
610 bfa_trc(ns->port->fcs, event);
611
612 switch (event) {
613 case NSSM_EVENT_PORT_OFFLINE:
614 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
615 break;
616
617 case NSSM_EVENT_NS_QUERY:
618 /*
619 * If the port role is Initiator Mode issue NS query.
620 * If it is Target Mode, skip this and go to online.
621 */
622 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
623 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft);
624 bfa_fcs_port_ns_send_gid_ft(ns, NULL);
625 };
626 break;
627
628 default:
629 bfa_assert(0);
630 }
631}
632
633
634
635/**
636 * ns_pvt Nameserver local functions
637 */
638
639static void
640bfa_fcs_port_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
641{
642 struct bfa_fcs_port_ns_s *ns = ns_cbarg;
643 struct bfa_fcs_port_s *port = ns->port;
644 struct fchs_s fchs;
645 int len;
646 struct bfa_fcxp_s *fcxp;
647
648 bfa_trc(port->fcs, port->pid);
649
650 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
651 if (!fcxp) {
652 port->stats.ns_plogi_alloc_wait++;
653 bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
654 bfa_fcs_port_ns_send_plogi, ns);
655 return;
656 }
657 ns->fcxp = fcxp;
658
659 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
660 bfa_os_hton3b(FC_NAME_SERVER),
661 bfa_fcs_port_get_fcid(port), 0,
662 port->port_cfg.pwwn, port->port_cfg.nwwn,
663 bfa_pport_get_maxfrsize(port->fcs->bfa));
664
665 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
666 FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response,
667 (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
668 port->stats.ns_plogi_sent++;
669
670 bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT);
671}
672
673static void
674bfa_fcs_port_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
675 void *cbarg, bfa_status_t req_status,
676 u32 rsp_len, u32 resid_len,
677 struct fchs_s *rsp_fchs)
678{
679 struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
680 struct bfa_fcs_port_s *port = ns->port;
681 /* struct fc_logi_s *plogi_resp; */
682 struct fc_els_cmd_s *els_cmd;
683 struct fc_ls_rjt_s *ls_rjt;
684
685 bfa_trc(port->fcs, req_status);
686 bfa_trc(port->fcs, port->port_cfg.pwwn);
687
688 /*
689 * Sanity Checks
690 */
691 if (req_status != BFA_STATUS_OK) {
692 bfa_trc(port->fcs, req_status);
693 port->stats.ns_plogi_rsp_err++;
694 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
695 return;
696 }
697
698 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
699
700 switch (els_cmd->els_code) {
701
702 case FC_ELS_ACC:
703 if (rsp_len < sizeof(struct fc_logi_s)) {
704 bfa_trc(port->fcs, rsp_len);
705 port->stats.ns_plogi_acc_err++;
706 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
707 break;
708 }
709 port->stats.ns_plogi_accepts++;
710 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
711 break;
712
713 case FC_ELS_LS_RJT:
714 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
715
716 bfa_trc(port->fcs, ls_rjt->reason_code);
717 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
718
719 port->stats.ns_rejects++;
720
721 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
722 break;
723
724 default:
725 port->stats.ns_plogi_unknown_rsp++;
726 bfa_trc(port->fcs, els_cmd->els_code);
727 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
728 }
729}
730
731/**
732 * Register the symbolic port name.
733 */
734static void
735bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
736{
737 struct bfa_fcs_port_ns_s *ns = ns_cbarg;
738 struct bfa_fcs_port_s *port = ns->port;
739 struct fchs_s fchs;
740 int len;
741 struct bfa_fcxp_s *fcxp;
742 u8 symbl[256];
743 u8 *psymbl = &symbl[0];
744
745 bfa_os_memset(symbl, 0, sizeof(symbl));
746
747 bfa_trc(port->fcs, port->port_cfg.pwwn);
748
749 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
750 if (!fcxp) {
751 port->stats.ns_rspnid_alloc_wait++;
752 bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
753 bfa_fcs_port_ns_send_rspn_id, ns);
754 return;
755 }
756 ns->fcxp = fcxp;
757
758 /*
759 * for V-Port, form a Port Symbolic Name
760 */
761 if (port->vport) {
762 /**For Vports,
763 * we append the vport's port symbolic name to that of the base port.
764 */
765
766 strncpy((char *)psymbl,
767 (char *)
768 &(bfa_fcs_port_get_psym_name
769 (bfa_fcs_get_base_port(port->fcs))),
770 strlen((char *)
771 &bfa_fcs_port_get_psym_name(bfa_fcs_get_base_port
772 (port->fcs))));
773
774 /*
775 * Ensure we have a null terminating string.
776 */
777 ((char *)
778 psymbl)[strlen((char *)
779 &bfa_fcs_port_get_psym_name
780 (bfa_fcs_get_base_port(port->fcs)))] = 0;
781
782 strncat((char *)psymbl,
783 (char *)&(bfa_fcs_port_get_psym_name(port)),
784 strlen((char *)&bfa_fcs_port_get_psym_name(port)));
785 } else {
786 psymbl = (u8 *) &(bfa_fcs_port_get_psym_name(port));
787 }
788
789 len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
790 bfa_fcs_port_get_fcid(port), 0, psymbl);
791
792 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
793 FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rspn_id_response,
794 (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
795
796 port->stats.ns_rspnid_sent++;
797
798 bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT);
799}
800
801static void
802bfa_fcs_port_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
803 void *cbarg, bfa_status_t req_status,
804 u32 rsp_len, u32 resid_len,
805 struct fchs_s *rsp_fchs)
806{
807 struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
808 struct bfa_fcs_port_s *port = ns->port;
809 struct ct_hdr_s *cthdr = NULL;
810
811 bfa_trc(port->fcs, port->port_cfg.pwwn);
812
813 /*
814 * Sanity Checks
815 */
816 if (req_status != BFA_STATUS_OK) {
817 bfa_trc(port->fcs, req_status);
818 port->stats.ns_rspnid_rsp_err++;
819 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
820 return;
821 }
822
823 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
824 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
825
826 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
827 port->stats.ns_rspnid_accepts++;
828 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
829 return;
830 }
831
832 port->stats.ns_rspnid_rejects++;
833 bfa_trc(port->fcs, cthdr->reason_code);
834 bfa_trc(port->fcs, cthdr->exp_code);
835 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
836}
837
838/**
839 * Register FC4-Types
840 * TBD, Need to retrieve this from the OS driver, in case IPFC is enabled ?
841 */
842static void
843bfa_fcs_port_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
844{
845 struct bfa_fcs_port_ns_s *ns = ns_cbarg;
846 struct bfa_fcs_port_s *port = ns->port;
847 struct fchs_s fchs;
848 int len;
849 struct bfa_fcxp_s *fcxp;
850
851 bfa_trc(port->fcs, port->port_cfg.pwwn);
852
853 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
854 if (!fcxp) {
855 port->stats.ns_rftid_alloc_wait++;
856 bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
857 bfa_fcs_port_ns_send_rft_id, ns);
858 return;
859 }
860 ns->fcxp = fcxp;
861
862 len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
863 bfa_fcs_port_get_fcid(port), 0,
864 port->port_cfg.roles);
865
866 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
867 FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rft_id_response,
868 (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
869
870 port->stats.ns_rftid_sent++;
871 bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT);
872}
873
874static void
875bfa_fcs_port_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
876 void *cbarg, bfa_status_t req_status,
877 u32 rsp_len, u32 resid_len,
878 struct fchs_s *rsp_fchs)
879{
880 struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
881 struct bfa_fcs_port_s *port = ns->port;
882 struct ct_hdr_s *cthdr = NULL;
883
884 bfa_trc(port->fcs, port->port_cfg.pwwn);
885
886 /*
887 * Sanity Checks
888 */
889 if (req_status != BFA_STATUS_OK) {
890 bfa_trc(port->fcs, req_status);
891 port->stats.ns_rftid_rsp_err++;
892 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
893 return;
894 }
895
896 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
897 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
898
899 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
900 port->stats.ns_rftid_accepts++;
901 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
902 return;
903 }
904
905 port->stats.ns_rftid_rejects++;
906 bfa_trc(port->fcs, cthdr->reason_code);
907 bfa_trc(port->fcs, cthdr->exp_code);
908 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
909}
910
911/**
912* Register FC4-Features : Should be done after RFT_ID
913 */
914static void
915bfa_fcs_port_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
916{
917 struct bfa_fcs_port_ns_s *ns = ns_cbarg;
918 struct bfa_fcs_port_s *port = ns->port;
919 struct fchs_s fchs;
920 int len;
921 struct bfa_fcxp_s *fcxp;
922 u8 fc4_ftrs = 0;
923
924 bfa_trc(port->fcs, port->port_cfg.pwwn);
925
926 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
927 if (!fcxp) {
928 port->stats.ns_rffid_alloc_wait++;
929 bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
930 bfa_fcs_port_ns_send_rff_id, ns);
931 return;
932 }
933 ns->fcxp = fcxp;
934
935 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
936 fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR;
937 } else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port)) {
938 fc4_ftrs = FC_GS_FCP_FC4_FEATURE_TARGET;
939 }
940
941 len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
942 bfa_fcs_port_get_fcid(port), 0, FC_TYPE_FCP,
943 fc4_ftrs);
944
945 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
946 FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rff_id_response,
947 (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
948
949 port->stats.ns_rffid_sent++;
950 bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT);
951}
952
953static void
954bfa_fcs_port_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
955 void *cbarg, bfa_status_t req_status,
956 u32 rsp_len, u32 resid_len,
957 struct fchs_s *rsp_fchs)
958{
959 struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
960 struct bfa_fcs_port_s *port = ns->port;
961 struct ct_hdr_s *cthdr = NULL;
962
963 bfa_trc(port->fcs, port->port_cfg.pwwn);
964
965 /*
966 * Sanity Checks
967 */
968 if (req_status != BFA_STATUS_OK) {
969 bfa_trc(port->fcs, req_status);
970 port->stats.ns_rffid_rsp_err++;
971 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
972 return;
973 }
974
975 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
976 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
977
978 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
979 port->stats.ns_rffid_accepts++;
980 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
981 return;
982 }
983
984 port->stats.ns_rffid_rejects++;
985 bfa_trc(port->fcs, cthdr->reason_code);
986 bfa_trc(port->fcs, cthdr->exp_code);
987
988 if (cthdr->reason_code == CT_RSN_NOT_SUPP) {
989 /*
990 * if this command is not supported, we don't retry
991 */
992 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
993 } else {
994 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
995 }
996}
997
998/**
999 * Query Fabric for FC4-Types Devices.
1000 *
1001* TBD : Need to use a local (FCS private) response buffer, since the response
1002 * can be larger than 2K.
1003 */
1004static void
1005bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1006{
1007 struct bfa_fcs_port_ns_s *ns = ns_cbarg;
1008 struct bfa_fcs_port_s *port = ns->port;
1009 struct fchs_s fchs;
1010 int len;
1011 struct bfa_fcxp_s *fcxp;
1012
1013 bfa_trc(port->fcs, port->pid);
1014
1015 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1016 if (!fcxp) {
1017 port->stats.ns_gidft_alloc_wait++;
1018 bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
1019 bfa_fcs_port_ns_send_gid_ft, ns);
1020 return;
1021 }
1022 ns->fcxp = fcxp;
1023
1024 /*
1025 * This query is only initiated for FCP initiator mode.
1026 */
1027 len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ns->port->pid,
1028 FC_TYPE_FCP);
1029
1030 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1031 FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_gid_ft_response,
1032 (void *)ns, bfa_fcxp_get_maxrsp(port->fcs->bfa),
1033 FC_RA_TOV);
1034
1035 port->stats.ns_gidft_sent++;
1036
1037 bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT);
1038}
1039
1040static void
1041bfa_fcs_port_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
1042 void *cbarg, bfa_status_t req_status,
1043 u32 rsp_len, u32 resid_len,
1044 struct fchs_s *rsp_fchs)
1045{
1046 struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
1047 struct bfa_fcs_port_s *port = ns->port;
1048 struct ct_hdr_s *cthdr = NULL;
1049 u32 n_pids;
1050
1051 bfa_trc(port->fcs, port->port_cfg.pwwn);
1052
1053 /*
1054 * Sanity Checks
1055 */
1056 if (req_status != BFA_STATUS_OK) {
1057 bfa_trc(port->fcs, req_status);
1058 port->stats.ns_gidft_rsp_err++;
1059 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
1060 return;
1061 }
1062
1063 if (resid_len != 0) {
1064 /*
1065 * TBD : we will need to allocate a larger buffer & retry the
1066 * command
1067 */
1068 bfa_trc(port->fcs, rsp_len);
1069 bfa_trc(port->fcs, resid_len);
1070 return;
1071 }
1072
1073 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1074 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
1075
1076 switch (cthdr->cmd_rsp_code) {
1077
1078 case CT_RSP_ACCEPT:
1079
1080 port->stats.ns_gidft_accepts++;
1081 n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32));
1082 bfa_trc(port->fcs, n_pids);
1083 bfa_fcs_port_ns_process_gidft_pids(port,
1084 (u32 *) (cthdr + 1),
1085 n_pids);
1086 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
1087 break;
1088
1089 case CT_RSP_REJECT:
1090
1091 /*
1092 * Check the reason code & explanation.
1093 * There may not have been any FC4 devices in the fabric
1094 */
1095 port->stats.ns_gidft_rejects++;
1096 bfa_trc(port->fcs, cthdr->reason_code);
1097 bfa_trc(port->fcs, cthdr->exp_code);
1098
1099 if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF)
1100 && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) {
1101
1102 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
1103 } else {
1104 /*
1105 * for all other errors, retry
1106 */
1107 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
1108 }
1109 break;
1110
1111 default:
1112 port->stats.ns_gidft_unknown_rsp++;
1113 bfa_trc(port->fcs, cthdr->cmd_rsp_code);
1114 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
1115 }
1116}
1117
1118/**
1119 * This routine will be called by bfa_timer on timer timeouts.
1120 *
1121 * param[in] port - pointer to bfa_fcs_port_t.
1122 *
1123 * return
1124 * void
1125 *
1126* Special Considerations:
1127 *
1128 * note
1129 */
1130static void
1131bfa_fcs_port_ns_timeout(void *arg)
1132{
1133 struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)arg;
1134
1135 ns->port->stats.ns_timeouts++;
1136 bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT);
1137}
1138
1139/*
1140 * Process the PID list in GID_FT response
1141 */
1142static void
1143bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port,
1144 u32 *pid_buf, u32 n_pids)
1145{
1146 struct fcgs_gidft_resp_s *gidft_entry;
1147 struct bfa_fcs_rport_s *rport;
1148 u32 ii;
1149
1150 for (ii = 0; ii < n_pids; ii++) {
1151 gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];
1152
1153 if (gidft_entry->pid == port->pid)
1154 continue;
1155
1156 /*
1157 * Check if this rport already exists
1158 */
1159 rport = bfa_fcs_port_get_rport_by_pid(port, gidft_entry->pid);
1160 if (rport == NULL) {
1161 /*
1162 * this is a new device. create rport
1163 */
1164 rport = bfa_fcs_rport_create(port, gidft_entry->pid);
1165 } else {
1166 /*
1167 * this rport already exists
1168 */
1169 bfa_fcs_rport_scn(rport);
1170 }
1171
1172 bfa_trc(port->fcs, gidft_entry->pid);
1173
1174 /*
1175 * if the last entry bit is set, bail out.
1176 */
1177 if (gidft_entry->last)
1178 return;
1179 }
1180}
1181
1182/**
1183 * fcs_ns_public FCS nameserver public interfaces
1184 */
1185
1186/*
1187 * Functions called by port/fab.
1188 * These will send relevant Events to the ns state machine.
1189 */
1190void
1191bfa_fcs_port_ns_init(struct bfa_fcs_port_s *port)
1192{
1193 struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
1194
1195 ns->port = port;
1196 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
1197}
1198
1199void
1200bfa_fcs_port_ns_offline(struct bfa_fcs_port_s *port)
1201{
1202 struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
1203
1204 ns->port = port;
1205 bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE);
1206}
1207
1208void
1209bfa_fcs_port_ns_online(struct bfa_fcs_port_s *port)
1210{
1211 struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
1212
1213 ns->port = port;
1214 bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE);
1215}
1216
1217void
1218bfa_fcs_port_ns_query(struct bfa_fcs_port_s *port)
1219{
1220 struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
1221
1222 bfa_trc(port->fcs, port->pid);
1223 bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
1224}
1225
1226static void
1227bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port)
1228{
1229
1230 struct bfa_fcs_rport_s *rport;
1231 u8 nwwns;
1232 wwn_t *wwns;
1233 int ii;
1234
1235 bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, &wwns);
1236
1237 for (ii = 0; ii < nwwns; ++ii) {
1238 rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
1239 bfa_assert(rport);
1240 }
1241}
1242
1243
diff --git a/drivers/scsi/bfa/plog.c b/drivers/scsi/bfa/plog.c
new file mode 100644
index 000000000000..86af818d17bb
--- /dev/null
+++ b/drivers/scsi/bfa/plog.c
@@ -0,0 +1,184 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa_os_inc.h>
19#include <cs/bfa_plog.h>
20#include <cs/bfa_debug.h>
21
22static int
23plkd_validate_logrec(struct bfa_plog_rec_s *pl_rec)
24{
25 if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT)
26 && (pl_rec->log_type != BFA_PL_LOG_TYPE_STRING))
27 return 1;
28
29 if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT)
30 && (pl_rec->log_num_ints > BFA_PL_INT_LOG_SZ))
31 return 1;
32
33 return 0;
34}
35
36static void
37bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec)
38{
39 u16 tail;
40 struct bfa_plog_rec_s *pl_recp;
41
42 if (plog->plog_enabled == 0)
43 return;
44
45 if (plkd_validate_logrec(pl_rec)) {
46 bfa_assert(0);
47 return;
48 }
49
50 tail = plog->tail;
51
52 pl_recp = &(plog->plog_recs[tail]);
53
54 bfa_os_memcpy(pl_recp, pl_rec, sizeof(struct bfa_plog_rec_s));
55
56 pl_recp->tv = BFA_TRC_TS(plog);
57 BFA_PL_LOG_REC_INCR(plog->tail);
58
59 if (plog->head == plog->tail)
60 BFA_PL_LOG_REC_INCR(plog->head);
61}
62
63void
64bfa_plog_init(struct bfa_plog_s *plog)
65{
66 bfa_os_memset((char *)plog, 0, sizeof(struct bfa_plog_s));
67
68 bfa_os_memcpy(plog->plog_sig, BFA_PL_SIG_STR, BFA_PL_SIG_LEN);
69 plog->head = plog->tail = 0;
70 plog->plog_enabled = 1;
71}
72
73void
74bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
75 enum bfa_plog_eid event,
76 u16 misc, char *log_str)
77{
78 struct bfa_plog_rec_s lp;
79
80 if (plog->plog_enabled) {
81 bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
82 lp.mid = mid;
83 lp.eid = event;
84 lp.log_type = BFA_PL_LOG_TYPE_STRING;
85 lp.misc = misc;
86 strncpy(lp.log_entry.string_log, log_str,
87 BFA_PL_STRING_LOG_SZ - 1);
88 lp.log_entry.string_log[BFA_PL_STRING_LOG_SZ - 1] = '\0';
89 bfa_plog_add(plog, &lp);
90 }
91}
92
93void
94bfa_plog_intarr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
95 enum bfa_plog_eid event,
96 u16 misc, u32 *intarr, u32 num_ints)
97{
98 struct bfa_plog_rec_s lp;
99 u32 i;
100
101 if (num_ints > BFA_PL_INT_LOG_SZ)
102 num_ints = BFA_PL_INT_LOG_SZ;
103
104 if (plog->plog_enabled) {
105 bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
106 lp.mid = mid;
107 lp.eid = event;
108 lp.log_type = BFA_PL_LOG_TYPE_INT;
109 lp.misc = misc;
110
111 for (i = 0; i < num_ints; i++)
112 bfa_os_assign(lp.log_entry.int_log[i],
113 intarr[i]);
114
115 lp.log_num_ints = (u8) num_ints;
116
117 bfa_plog_add(plog, &lp);
118 }
119}
120
121void
122bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
123 enum bfa_plog_eid event,
124 u16 misc, struct fchs_s *fchdr)
125{
126 struct bfa_plog_rec_s lp;
127 u32 *tmp_int = (u32 *) fchdr;
128 u32 ints[BFA_PL_INT_LOG_SZ];
129
130 if (plog->plog_enabled) {
131 bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
132
133 ints[0] = tmp_int[0];
134 ints[1] = tmp_int[1];
135 ints[2] = tmp_int[4];
136
137 bfa_plog_intarr(plog, mid, event, misc, ints, 3);
138 }
139}
140
141void
142bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
143 enum bfa_plog_eid event, u16 misc, struct fchs_s *fchdr,
144 u32 pld_w0)
145{
146 struct bfa_plog_rec_s lp;
147 u32 *tmp_int = (u32 *) fchdr;
148 u32 ints[BFA_PL_INT_LOG_SZ];
149
150 if (plog->plog_enabled) {
151 bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
152
153 ints[0] = tmp_int[0];
154 ints[1] = tmp_int[1];
155 ints[2] = tmp_int[4];
156 ints[3] = pld_w0;
157
158 bfa_plog_intarr(plog, mid, event, misc, ints, 4);
159 }
160}
161
162void
163bfa_plog_clear(struct bfa_plog_s *plog)
164{
165 plog->head = plog->tail = 0;
166}
167
168void
169bfa_plog_enable(struct bfa_plog_s *plog)
170{
171 plog->plog_enabled = 1;
172}
173
174void
175bfa_plog_disable(struct bfa_plog_s *plog)
176{
177 plog->plog_enabled = 0;
178}
179
180bfa_boolean_t
181bfa_plog_get_setting(struct bfa_plog_s *plog)
182{
183 return((bfa_boolean_t)plog->plog_enabled);
184}
diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c
new file mode 100644
index 000000000000..9cf58bb138dc
--- /dev/null
+++ b/drivers/scsi/bfa/rport.c
@@ -0,0 +1,2618 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * rport.c Remote port implementation.
20 */
21
22#include <bfa.h>
23#include <bfa_svc.h>
24#include "fcbuild.h"
25#include "fcs_vport.h"
26#include "fcs_lport.h"
27#include "fcs_rport.h"
28#include "fcs_fcpim.h"
29#include "fcs_fcptm.h"
30#include "fcs_trcmod.h"
31#include "fcs_fcxp.h"
32#include "fcs.h"
33#include <fcb/bfa_fcb_rport.h>
34#include <aen/bfa_aen_rport.h>
35
36BFA_TRC_FILE(FCS, RPORT);
37
38#define BFA_FCS_RPORT_MAX_RETRIES (5)
39
40/* In millisecs */
41static u32 bfa_fcs_rport_del_timeout =
42 BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000;
43
44/*
45 * forward declarations
46 */
47static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc(struct bfa_fcs_port_s *port,
48 wwn_t pwwn, u32 rpid);
49static void bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport);
50static void bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport);
51static void bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport);
52static void bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport);
53static void bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport,
54 struct fc_logi_s *plogi);
55static void bfa_fcs_rport_fc4_pause(struct bfa_fcs_rport_s *rport);
56static void bfa_fcs_rport_fc4_resume(struct bfa_fcs_rport_s *rport);
57static void bfa_fcs_rport_timeout(void *arg);
58static void bfa_fcs_rport_send_plogi(void *rport_cbarg,
59 struct bfa_fcxp_s *fcxp_alloced);
60static void bfa_fcs_rport_send_plogiacc(void *rport_cbarg,
61 struct bfa_fcxp_s *fcxp_alloced);
62static void bfa_fcs_rport_plogi_response(void *fcsarg,
63 struct bfa_fcxp_s *fcxp,
64 void *cbarg,
65 bfa_status_t req_status,
66 u32 rsp_len,
67 u32 resid_len,
68 struct fchs_s *rsp_fchs);
69static void bfa_fcs_rport_send_adisc(void *rport_cbarg,
70 struct bfa_fcxp_s *fcxp_alloced);
71static void bfa_fcs_rport_adisc_response(void *fcsarg,
72 struct bfa_fcxp_s *fcxp,
73 void *cbarg,
74 bfa_status_t req_status,
75 u32 rsp_len,
76 u32 resid_len,
77 struct fchs_s *rsp_fchs);
78static void bfa_fcs_rport_send_gidpn(void *rport_cbarg,
79 struct bfa_fcxp_s *fcxp_alloced);
80static void bfa_fcs_rport_gidpn_response(void *fcsarg,
81 struct bfa_fcxp_s *fcxp,
82 void *cbarg,
83 bfa_status_t req_status,
84 u32 rsp_len,
85 u32 resid_len,
86 struct fchs_s *rsp_fchs);
87static void bfa_fcs_rport_send_logo(void *rport_cbarg,
88 struct bfa_fcxp_s *fcxp_alloced);
89static void bfa_fcs_rport_send_logo_acc(void *rport_cbarg);
90static void bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
91 struct fchs_s *rx_fchs, u16 len);
92static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
93 struct fchs_s *rx_fchs, u8 reason_code,
94 u8 reason_code_expl);
95static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
96 struct fchs_s *rx_fchs, u16 len);
97/**
98 * fcs_rport_sm FCS rport state machine events
99 */
100
101enum rport_event {
102 RPSM_EVENT_PLOGI_SEND = 1, /* new rport; start with PLOGI */
103 RPSM_EVENT_PLOGI_RCVD = 2, /* Inbound PLOGI from remote port */
104 RPSM_EVENT_PLOGI_COMP = 3, /* PLOGI completed to rport */
105 RPSM_EVENT_LOGO_RCVD = 4, /* LOGO from remote device */
106 RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */
107 RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */
108 RPSM_EVENT_DELETE = 7, /* RPORT delete request */
109 RPSM_EVENT_SCN = 8, /* state change notification */
110 RPSM_EVENT_ACCEPTED = 9,/* Good response from remote device */
111 RPSM_EVENT_FAILED = 10, /* Request to rport failed. */
112 RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */
113 RPSM_EVENT_HCB_ONLINE = 12, /* BFA rport online callback */
114 RPSM_EVENT_HCB_OFFLINE = 13, /* BFA rport offline callback */
115 RPSM_EVENT_FC4_OFFLINE = 14, /* FC-4 offline complete */
116 RPSM_EVENT_ADDRESS_CHANGE = 15, /* Rport's PID has changed */
117 RPSM_EVENT_ADDRESS_DISC = 16 /* Need to Discover rport's PID */
118};
119
120static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
121 enum rport_event event);
122static void bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
123 enum rport_event event);
124static void bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
125 enum rport_event event);
126static void bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
127 enum rport_event event);
128static void bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport,
129 enum rport_event event);
130static void bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
131 enum rport_event event);
132static void bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport,
133 enum rport_event event);
134static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
135 enum rport_event event);
136static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
137 enum rport_event event);
138static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
139 enum rport_event event);
140static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport,
141 enum rport_event event);
142static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
143 enum rport_event event);
144static void bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
145 enum rport_event event);
146static void bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
147 enum rport_event event);
148static void bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
149 enum rport_event event);
150static void bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
151 enum rport_event event);
152static void bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
153 enum rport_event event);
154static void bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
155 enum rport_event event);
156static void bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport,
157 enum rport_event event);
158static void bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
159 enum rport_event event);
160static void bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
161 enum rport_event event);
162static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
163 enum rport_event event);
164static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
165 enum rport_event event);
166
167static struct bfa_sm_table_s rport_sm_table[] = {
168 {BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT},
169 {BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI},
170 {BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE},
171 {BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY},
172 {BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI},
173 {BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE},
174 {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
175 {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
176 {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
177 {BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC},
178 {BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC},
179 {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
180 {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
181 {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
182 {BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE},
183 {BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV},
184 {BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO},
185 {BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO},
186 {BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE},
187 {BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC},
188 {BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC},
189 {BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC},
190};
191
192/**
193 * Beginning state.
194 */
195static void
196bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
197{
198 bfa_trc(rport->fcs, rport->pwwn);
199 bfa_trc(rport->fcs, rport->pid);
200 bfa_trc(rport->fcs, event);
201
202 switch (event) {
203 case RPSM_EVENT_PLOGI_SEND:
204 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
205 rport->plogi_retries = 0;
206 bfa_fcs_rport_send_plogi(rport, NULL);
207 break;
208
209 case RPSM_EVENT_PLOGI_RCVD:
210 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
211 bfa_fcs_rport_send_plogiacc(rport, NULL);
212 break;
213
214 case RPSM_EVENT_PLOGI_COMP:
215 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
216 bfa_fcs_rport_hal_online(rport);
217 break;
218
219 case RPSM_EVENT_ADDRESS_CHANGE:
220 case RPSM_EVENT_ADDRESS_DISC:
221 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
222 rport->ns_retries = 0;
223 bfa_fcs_rport_send_gidpn(rport, NULL);
224 break;
225
226 default:
227 bfa_assert(0);
228 }
229}
230
231/**
232 * PLOGI is being sent.
233 */
234static void
235bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
236 enum rport_event event)
237{
238 bfa_trc(rport->fcs, rport->pwwn);
239 bfa_trc(rport->fcs, rport->pid);
240 bfa_trc(rport->fcs, event);
241
242 switch (event) {
243 case RPSM_EVENT_FCXP_SENT:
244 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi);
245 break;
246
247 case RPSM_EVENT_DELETE:
248 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
249 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
250 bfa_fcs_rport_free(rport);
251 break;
252
253 case RPSM_EVENT_PLOGI_RCVD:
254 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
255 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
256 bfa_fcs_rport_send_plogiacc(rport, NULL);
257 break;
258
259 case RPSM_EVENT_ADDRESS_CHANGE:
260 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
261 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
262 rport->ns_retries = 0;
263 bfa_fcs_rport_send_gidpn(rport, NULL);
264 break;
265
266 case RPSM_EVENT_LOGO_IMP:
267 rport->pid = 0;
268 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
269 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
270 bfa_timer_start(rport->fcs->bfa, &rport->timer,
271 bfa_fcs_rport_timeout, rport,
272 bfa_fcs_rport_del_timeout);
273 break;
274
275 case RPSM_EVENT_SCN:
276 break;
277
278 default:
279 bfa_assert(0);
280 }
281}
282
283/**
284 * PLOGI is being sent.
285 */
286static void
287bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
288 enum rport_event event)
289{
290 bfa_trc(rport->fcs, rport->pwwn);
291 bfa_trc(rport->fcs, rport->pid);
292 bfa_trc(rport->fcs, event);
293
294 switch (event) {
295 case RPSM_EVENT_FCXP_SENT:
296 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
297 bfa_fcs_rport_hal_online(rport);
298 break;
299
300 case RPSM_EVENT_DELETE:
301 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
302 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
303 bfa_fcs_rport_free(rport);
304 break;
305
306 case RPSM_EVENT_SCN:
307 /**
308 * Ignore, SCN is possibly online notification.
309 */
310 break;
311
312 case RPSM_EVENT_ADDRESS_CHANGE:
313 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
314 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
315 rport->ns_retries = 0;
316 bfa_fcs_rport_send_gidpn(rport, NULL);
317 break;
318
319 case RPSM_EVENT_LOGO_IMP:
320 rport->pid = 0;
321 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
322 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
323 bfa_timer_start(rport->fcs->bfa, &rport->timer,
324 bfa_fcs_rport_timeout, rport,
325 bfa_fcs_rport_del_timeout);
326 break;
327
328 case RPSM_EVENT_HCB_OFFLINE:
329 /**
330 * Ignore BFA callback, on a PLOGI receive we call bfa offline.
331 */
332 break;
333
334 default:
335 bfa_assert(0);
336 }
337}
338
339/**
340 * PLOGI is sent.
341 */
342static void
343bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
344 enum rport_event event)
345{
346 bfa_trc(rport->fcs, rport->pwwn);
347 bfa_trc(rport->fcs, rport->pid);
348 bfa_trc(rport->fcs, event);
349
350 switch (event) {
351 case RPSM_EVENT_SCN:
352 bfa_timer_stop(&rport->timer);
353 /*
354 * !! fall through !!
355 */
356
357 case RPSM_EVENT_TIMEOUT:
358 rport->plogi_retries++;
359 if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) {
360 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
361 bfa_fcs_rport_send_plogi(rport, NULL);
362 } else {
363 rport->pid = 0;
364 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
365 bfa_timer_start(rport->fcs->bfa, &rport->timer,
366 bfa_fcs_rport_timeout, rport,
367 bfa_fcs_rport_del_timeout);
368 }
369 break;
370
371 case RPSM_EVENT_DELETE:
372 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
373 bfa_timer_stop(&rport->timer);
374 bfa_fcs_rport_free(rport);
375 break;
376
377 case RPSM_EVENT_LOGO_RCVD:
378 break;
379
380 case RPSM_EVENT_PLOGI_RCVD:
381 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
382 bfa_timer_stop(&rport->timer);
383 bfa_fcs_rport_send_plogiacc(rport, NULL);
384 break;
385
386 case RPSM_EVENT_ADDRESS_CHANGE:
387 bfa_timer_stop(&rport->timer);
388 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
389 rport->ns_retries = 0;
390 bfa_fcs_rport_send_gidpn(rport, NULL);
391 break;
392
393 case RPSM_EVENT_LOGO_IMP:
394 rport->pid = 0;
395 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
396 bfa_timer_stop(&rport->timer);
397 bfa_timer_start(rport->fcs->bfa, &rport->timer,
398 bfa_fcs_rport_timeout, rport,
399 bfa_fcs_rport_del_timeout);
400 break;
401
402 case RPSM_EVENT_PLOGI_COMP:
403 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
404 bfa_timer_stop(&rport->timer);
405 bfa_fcs_rport_hal_online(rport);
406 break;
407
408 default:
409 bfa_assert(0);
410 }
411}
412
413/**
414 * PLOGI is sent.
415 */
416static void
417bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
418{
419 bfa_trc(rport->fcs, rport->pwwn);
420 bfa_trc(rport->fcs, rport->pid);
421 bfa_trc(rport->fcs, event);
422
423 switch (event) {
424 case RPSM_EVENT_ACCEPTED:
425 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
426 rport->plogi_retries = 0;
427 bfa_fcs_rport_hal_online(rport);
428 break;
429
430 case RPSM_EVENT_LOGO_RCVD:
431 bfa_fcs_rport_send_logo_acc(rport);
432 bfa_fcxp_discard(rport->fcxp);
433 /*
434 * !! fall through !!
435 */
436 case RPSM_EVENT_FAILED:
437 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
438 bfa_timer_start(rport->fcs->bfa, &rport->timer,
439 bfa_fcs_rport_timeout, rport,
440 BFA_FCS_RETRY_TIMEOUT);
441 break;
442
443 case RPSM_EVENT_LOGO_IMP:
444 rport->pid = 0;
445 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
446 bfa_fcxp_discard(rport->fcxp);
447 bfa_timer_start(rport->fcs->bfa, &rport->timer,
448 bfa_fcs_rport_timeout, rport,
449 bfa_fcs_rport_del_timeout);
450 break;
451
452 case RPSM_EVENT_ADDRESS_CHANGE:
453 bfa_fcxp_discard(rport->fcxp);
454 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
455 rport->ns_retries = 0;
456 bfa_fcs_rport_send_gidpn(rport, NULL);
457 break;
458
459 case RPSM_EVENT_PLOGI_RCVD:
460 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
461 bfa_fcxp_discard(rport->fcxp);
462 bfa_fcs_rport_send_plogiacc(rport, NULL);
463 break;
464
465 case RPSM_EVENT_SCN:
466 /**
467 * Ignore SCN - wait for PLOGI response.
468 */
469 break;
470
471 case RPSM_EVENT_DELETE:
472 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
473 bfa_fcxp_discard(rport->fcxp);
474 bfa_fcs_rport_free(rport);
475 break;
476
477 case RPSM_EVENT_PLOGI_COMP:
478 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
479 bfa_fcxp_discard(rport->fcxp);
480 bfa_fcs_rport_hal_online(rport);
481 break;
482
483 default:
484 bfa_assert(0);
485 }
486}
487
488/**
489 * PLOGI is complete. Awaiting BFA rport online callback. FC-4s
490 * are offline.
491 */
492static void
493bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
494 enum rport_event event)
495{
496 bfa_trc(rport->fcs, rport->pwwn);
497 bfa_trc(rport->fcs, rport->pid);
498 bfa_trc(rport->fcs, event);
499
500 switch (event) {
501 case RPSM_EVENT_HCB_ONLINE:
502 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
503 bfa_fcs_rport_online_action(rport);
504 break;
505
506 case RPSM_EVENT_LOGO_RCVD:
507 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
508 bfa_rport_offline(rport->bfa_rport);
509 break;
510
511 case RPSM_EVENT_LOGO_IMP:
512 case RPSM_EVENT_ADDRESS_CHANGE:
513 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
514 bfa_rport_offline(rport->bfa_rport);
515 break;
516
517 case RPSM_EVENT_PLOGI_RCVD:
518 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
519 bfa_rport_offline(rport->bfa_rport);
520 bfa_fcs_rport_send_plogiacc(rport, NULL);
521 break;
522
523 case RPSM_EVENT_DELETE:
524 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
525 bfa_rport_offline(rport->bfa_rport);
526 break;
527
528 case RPSM_EVENT_SCN:
529 /**
530 * @todo
531 * Ignore SCN - PLOGI just completed, FC-4 login should detect
532 * device failures.
533 */
534 break;
535
536 default:
537 bfa_assert(0);
538 }
539}
540
541/**
542 * Rport is ONLINE. FC-4s active.
543 */
544static void
545bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
546{
547 bfa_trc(rport->fcs, rport->pwwn);
548 bfa_trc(rport->fcs, rport->pid);
549 bfa_trc(rport->fcs, event);
550
551 switch (event) {
552 case RPSM_EVENT_SCN:
553 /**
554 * Pause FC-4 activity till rport is authenticated.
555 * In switched fabrics, check presence of device in nameserver
556 * first.
557 */
558 bfa_fcs_rport_fc4_pause(rport);
559
560 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
561 bfa_sm_set_state(rport,
562 bfa_fcs_rport_sm_nsquery_sending);
563 rport->ns_retries = 0;
564 bfa_fcs_rport_send_gidpn(rport, NULL);
565 } else {
566 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
567 bfa_fcs_rport_send_adisc(rport, NULL);
568 }
569 break;
570
571 case RPSM_EVENT_PLOGI_RCVD:
572 case RPSM_EVENT_LOGO_IMP:
573 case RPSM_EVENT_ADDRESS_CHANGE:
574 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
575 bfa_fcs_rport_offline_action(rport);
576 break;
577
578 case RPSM_EVENT_DELETE:
579 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
580 bfa_fcs_rport_offline_action(rport);
581 break;
582
583 case RPSM_EVENT_LOGO_RCVD:
584 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
585 bfa_fcs_rport_offline_action(rport);
586 break;
587
588 case RPSM_EVENT_PLOGI_COMP:
589 break;
590
591 default:
592 bfa_assert(0);
593 }
594}
595
596/**
597 * An SCN event is received in ONLINE state. NS query is being sent
598 * prior to ADISC authentication with rport. FC-4s are paused.
599 */
600static void
601bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
602 enum rport_event event)
603{
604 bfa_trc(rport->fcs, rport->pwwn);
605 bfa_trc(rport->fcs, rport->pid);
606 bfa_trc(rport->fcs, event);
607
608 switch (event) {
609 case RPSM_EVENT_FCXP_SENT:
610 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery);
611 break;
612
613 case RPSM_EVENT_DELETE:
614 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
615 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
616 bfa_fcs_rport_offline_action(rport);
617 break;
618
619 case RPSM_EVENT_SCN:
620 /**
621 * ignore SCN, wait for response to query itself
622 */
623 break;
624
625 case RPSM_EVENT_LOGO_RCVD:
626 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
627 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
628 bfa_fcs_rport_offline_action(rport);
629 break;
630
631 case RPSM_EVENT_LOGO_IMP:
632 rport->pid = 0;
633 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
634 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
635 bfa_timer_start(rport->fcs->bfa, &rport->timer,
636 bfa_fcs_rport_timeout, rport,
637 bfa_fcs_rport_del_timeout);
638 break;
639
640 case RPSM_EVENT_PLOGI_RCVD:
641 case RPSM_EVENT_ADDRESS_CHANGE:
642 case RPSM_EVENT_PLOGI_COMP:
643 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
644 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
645 bfa_fcs_rport_offline_action(rport);
646 break;
647
648 default:
649 bfa_assert(0);
650 }
651}
652
653/**
654 * An SCN event is received in ONLINE state. NS query is sent to rport.
655 * FC-4s are paused.
656 */
657static void
658bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
659{
660 bfa_trc(rport->fcs, rport->pwwn);
661 bfa_trc(rport->fcs, rport->pid);
662 bfa_trc(rport->fcs, event);
663
664 switch (event) {
665 case RPSM_EVENT_ACCEPTED:
666 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
667 bfa_fcs_rport_send_adisc(rport, NULL);
668 break;
669
670 case RPSM_EVENT_FAILED:
671 rport->ns_retries++;
672 if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
673 bfa_sm_set_state(rport,
674 bfa_fcs_rport_sm_nsquery_sending);
675 bfa_fcs_rport_send_gidpn(rport, NULL);
676 } else {
677 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
678 bfa_fcs_rport_offline_action(rport);
679 }
680 break;
681
682 case RPSM_EVENT_DELETE:
683 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
684 bfa_fcxp_discard(rport->fcxp);
685 bfa_fcs_rport_offline_action(rport);
686 break;
687
688 case RPSM_EVENT_SCN:
689 break;
690
691 case RPSM_EVENT_LOGO_RCVD:
692 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
693 bfa_fcxp_discard(rport->fcxp);
694 bfa_fcs_rport_offline_action(rport);
695 break;
696
697 case RPSM_EVENT_PLOGI_COMP:
698 case RPSM_EVENT_ADDRESS_CHANGE:
699 case RPSM_EVENT_PLOGI_RCVD:
700 case RPSM_EVENT_LOGO_IMP:
701 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
702 bfa_fcxp_discard(rport->fcxp);
703 bfa_fcs_rport_offline_action(rport);
704 break;
705
706 default:
707 bfa_assert(0);
708 }
709}
710
711/**
712 * An SCN event is received in ONLINE state. ADISC is being sent for
713 * authenticating with rport. FC-4s are paused.
714 */
715static void
716bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
717 enum rport_event event)
718{
719 bfa_trc(rport->fcs, rport->pwwn);
720 bfa_trc(rport->fcs, rport->pid);
721 bfa_trc(rport->fcs, event);
722
723 switch (event) {
724 case RPSM_EVENT_FCXP_SENT:
725 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc);
726 break;
727
728 case RPSM_EVENT_DELETE:
729 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
730 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
731 bfa_fcs_rport_offline_action(rport);
732 break;
733
734 case RPSM_EVENT_LOGO_IMP:
735 case RPSM_EVENT_ADDRESS_CHANGE:
736 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
737 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
738 bfa_fcs_rport_offline_action(rport);
739 break;
740
741 case RPSM_EVENT_LOGO_RCVD:
742 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
743 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
744 bfa_fcs_rport_offline_action(rport);
745 break;
746
747 case RPSM_EVENT_SCN:
748 break;
749
750 case RPSM_EVENT_PLOGI_RCVD:
751 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
752 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
753 bfa_fcs_rport_offline_action(rport);
754 break;
755
756 default:
757 bfa_assert(0);
758 }
759}
760
761/**
762 * An SCN event is received in ONLINE state. ADISC is to rport.
763 * FC-4s are paused.
764 */
765static void
766bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
767{
768 bfa_trc(rport->fcs, rport->pwwn);
769 bfa_trc(rport->fcs, rport->pid);
770 bfa_trc(rport->fcs, event);
771
772 switch (event) {
773 case RPSM_EVENT_ACCEPTED:
774 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
775 bfa_fcs_rport_fc4_resume(rport);
776 break;
777
778 case RPSM_EVENT_PLOGI_RCVD:
779 /**
780 * Too complex to cleanup FC-4 & rport and then acc to PLOGI.
781 * At least go offline when a PLOGI is received.
782 */
783 bfa_fcxp_discard(rport->fcxp);
784 /*
785 * !!! fall through !!!
786 */
787
788 case RPSM_EVENT_FAILED:
789 case RPSM_EVENT_ADDRESS_CHANGE:
790 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
791 bfa_fcs_rport_offline_action(rport);
792 break;
793
794 case RPSM_EVENT_DELETE:
795 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
796 bfa_fcxp_discard(rport->fcxp);
797 bfa_fcs_rport_offline_action(rport);
798 break;
799
800 case RPSM_EVENT_SCN:
801 /**
802 * already processing RSCN
803 */
804 break;
805
806 case RPSM_EVENT_LOGO_IMP:
807 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
808 bfa_fcxp_discard(rport->fcxp);
809 bfa_fcs_rport_offline_action(rport);
810 break;
811
812 case RPSM_EVENT_LOGO_RCVD:
813 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
814 bfa_fcxp_discard(rport->fcxp);
815 bfa_fcs_rport_offline_action(rport);
816 break;
817
818 default:
819 bfa_assert(0);
820 }
821}
822
823/**
824 * Rport has sent LOGO. Awaiting FC-4 offline completion callback.
825 */
826static void
827bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
828 enum rport_event event)
829{
830 bfa_trc(rport->fcs, rport->pwwn);
831 bfa_trc(rport->fcs, rport->pid);
832 bfa_trc(rport->fcs, event);
833
834 switch (event) {
835 case RPSM_EVENT_FC4_OFFLINE:
836 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
837 bfa_rport_offline(rport->bfa_rport);
838 break;
839
840 case RPSM_EVENT_DELETE:
841 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
842 break;
843
844 case RPSM_EVENT_LOGO_RCVD:
845 case RPSM_EVENT_ADDRESS_CHANGE:
846 break;
847
848 default:
849 bfa_assert(0);
850 }
851}
852
853/**
854 * LOGO needs to be sent to rport. Awaiting FC-4 offline completion
855 * callback.
856 */
857static void
858bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
859 enum rport_event event)
860{
861 bfa_trc(rport->fcs, rport->pwwn);
862 bfa_trc(rport->fcs, rport->pid);
863 bfa_trc(rport->fcs, event);
864
865 switch (event) {
866 case RPSM_EVENT_FC4_OFFLINE:
867 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
868 bfa_rport_offline(rport->bfa_rport);
869 break;
870
871 default:
872 bfa_assert(0);
873 }
874}
875
876/**
877 * Rport is going offline. Awaiting FC-4 offline completion callback.
878 */
879static void
880bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
881 enum rport_event event)
882{
883 bfa_trc(rport->fcs, rport->pwwn);
884 bfa_trc(rport->fcs, rport->pid);
885 bfa_trc(rport->fcs, event);
886
887 switch (event) {
888 case RPSM_EVENT_FC4_OFFLINE:
889 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
890 bfa_rport_offline(rport->bfa_rport);
891 break;
892
893 case RPSM_EVENT_SCN:
894 case RPSM_EVENT_LOGO_IMP:
895 case RPSM_EVENT_LOGO_RCVD:
896 case RPSM_EVENT_ADDRESS_CHANGE:
897 /**
898 * rport is already going offline.
899 * SCN - ignore and wait till transitioning to offline state
900 */
901 break;
902
903 case RPSM_EVENT_DELETE:
904 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
905 break;
906
907 default:
908 bfa_assert(0);
909 }
910}
911
912/**
913 * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
914 * callback.
915 */
916static void
917bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
918 enum rport_event event)
919{
920 bfa_trc(rport->fcs, rport->pwwn);
921 bfa_trc(rport->fcs, rport->pid);
922 bfa_trc(rport->fcs, event);
923
924 switch (event) {
925 case RPSM_EVENT_HCB_OFFLINE:
926 case RPSM_EVENT_ADDRESS_CHANGE:
927 if (bfa_fcs_port_is_online(rport->port)) {
928 bfa_sm_set_state(rport,
929 bfa_fcs_rport_sm_nsdisc_sending);
930 rport->ns_retries = 0;
931 bfa_fcs_rport_send_gidpn(rport, NULL);
932 } else {
933 rport->pid = 0;
934 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
935 bfa_timer_start(rport->fcs->bfa, &rport->timer,
936 bfa_fcs_rport_timeout, rport,
937 bfa_fcs_rport_del_timeout);
938 }
939 break;
940
941 case RPSM_EVENT_DELETE:
942 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
943 bfa_fcs_rport_free(rport);
944 break;
945
946 case RPSM_EVENT_SCN:
947 case RPSM_EVENT_LOGO_RCVD:
948 /**
949 * Ignore, already offline.
950 */
951 break;
952
953 default:
954 bfa_assert(0);
955 }
956}
957
958/**
959 * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
960 * callback to send LOGO accept.
961 */
962static void
963bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
964 enum rport_event event)
965{
966 bfa_trc(rport->fcs, rport->pwwn);
967 bfa_trc(rport->fcs, rport->pid);
968 bfa_trc(rport->fcs, event);
969
970 switch (event) {
971 case RPSM_EVENT_HCB_OFFLINE:
972 case RPSM_EVENT_ADDRESS_CHANGE:
973 if (rport->pid)
974 bfa_fcs_rport_send_logo_acc(rport);
975 /*
976 * If the lport is online and if the rport is not a well known
977 * address port, we try to re-discover the r-port.
978 */
979 if (bfa_fcs_port_is_online(rport->port)
980 && (!BFA_FCS_PID_IS_WKA(rport->pid))) {
981 bfa_sm_set_state(rport,
982 bfa_fcs_rport_sm_nsdisc_sending);
983 rport->ns_retries = 0;
984 bfa_fcs_rport_send_gidpn(rport, NULL);
985 } else {
986 /*
987 * if it is not a well known address, reset the pid to
988 *
989 */
990 if (!BFA_FCS_PID_IS_WKA(rport->pid))
991 rport->pid = 0;
992 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
993 bfa_timer_start(rport->fcs->bfa, &rport->timer,
994 bfa_fcs_rport_timeout, rport,
995 bfa_fcs_rport_del_timeout);
996 }
997 break;
998
999 case RPSM_EVENT_DELETE:
1000 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
1001 break;
1002
1003 case RPSM_EVENT_LOGO_IMP:
1004 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
1005 break;
1006
1007 case RPSM_EVENT_LOGO_RCVD:
1008 /**
1009 * Ignore - already processing a LOGO.
1010 */
1011 break;
1012
1013 default:
1014 bfa_assert(0);
1015 }
1016}
1017
1018/**
1019 * Rport is being deleted. FC-4s are offline. Awaiting BFA rport offline
1020 * callback to send LOGO.
1021 */
1022static void
1023bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
1024 enum rport_event event)
1025{
1026 bfa_trc(rport->fcs, rport->pwwn);
1027 bfa_trc(rport->fcs, rport->pid);
1028 bfa_trc(rport->fcs, event);
1029
1030 switch (event) {
1031 case RPSM_EVENT_HCB_OFFLINE:
1032 bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending);
1033 bfa_fcs_rport_send_logo(rport, NULL);
1034 break;
1035
1036 case RPSM_EVENT_LOGO_RCVD:
1037 case RPSM_EVENT_ADDRESS_CHANGE:
1038 break;
1039
1040 default:
1041 bfa_assert(0);
1042 }
1043}
1044
1045/**
1046 * Rport is being deleted. FC-4s are offline. LOGO is being sent.
1047 */
1048static void
1049bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
1050 enum rport_event event)
1051{
1052 bfa_trc(rport->fcs, rport->pwwn);
1053 bfa_trc(rport->fcs, rport->pid);
1054 bfa_trc(rport->fcs, event);
1055
1056 switch (event) {
1057 case RPSM_EVENT_FCXP_SENT:
1058 /*
1059 * Once LOGO is sent, we donot wait for the response
1060 */
1061 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1062 bfa_fcs_rport_free(rport);
1063 break;
1064
1065 case RPSM_EVENT_SCN:
1066 case RPSM_EVENT_ADDRESS_CHANGE:
1067 break;
1068
1069 case RPSM_EVENT_LOGO_RCVD:
1070 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1071 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1072 bfa_fcs_rport_free(rport);
1073 break;
1074
1075 default:
1076 bfa_assert(0);
1077 }
1078}
1079
1080/**
1081 * Rport is offline. FC-4s are offline. BFA rport is offline.
1082 * Timer active to delete stale rport.
1083 */
1084static void
1085bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
1086{
1087 bfa_trc(rport->fcs, rport->pwwn);
1088 bfa_trc(rport->fcs, rport->pid);
1089 bfa_trc(rport->fcs, event);
1090
1091 switch (event) {
1092 case RPSM_EVENT_TIMEOUT:
1093 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1094 bfa_fcs_rport_free(rport);
1095 break;
1096
1097 case RPSM_EVENT_SCN:
1098 case RPSM_EVENT_ADDRESS_CHANGE:
1099 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1100 bfa_timer_stop(&rport->timer);
1101 rport->ns_retries = 0;
1102 bfa_fcs_rport_send_gidpn(rport, NULL);
1103 break;
1104
1105 case RPSM_EVENT_DELETE:
1106 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1107 bfa_timer_stop(&rport->timer);
1108 bfa_fcs_rport_free(rport);
1109 break;
1110
1111 case RPSM_EVENT_PLOGI_RCVD:
1112 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1113 bfa_timer_stop(&rport->timer);
1114 bfa_fcs_rport_send_plogiacc(rport, NULL);
1115 break;
1116
1117 case RPSM_EVENT_LOGO_RCVD:
1118 case RPSM_EVENT_LOGO_IMP:
1119 break;
1120
1121 case RPSM_EVENT_PLOGI_COMP:
1122 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1123 bfa_timer_stop(&rport->timer);
1124 bfa_fcs_rport_hal_online(rport);
1125 break;
1126
1127 case RPSM_EVENT_PLOGI_SEND:
1128 bfa_timer_stop(&rport->timer);
1129 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1130 rport->plogi_retries = 0;
1131 bfa_fcs_rport_send_plogi(rport, NULL);
1132 break;
1133
1134 default:
1135 bfa_assert(0);
1136 }
1137}
1138
1139/**
1140 * Rport address has changed. Nameserver discovery request is being sent.
1141 */
1142static void
1143bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
1144 enum rport_event event)
1145{
1146 bfa_trc(rport->fcs, rport->pwwn);
1147 bfa_trc(rport->fcs, rport->pid);
1148 bfa_trc(rport->fcs, event);
1149
1150 switch (event) {
1151 case RPSM_EVENT_FCXP_SENT:
1152 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sent);
1153 break;
1154
1155 case RPSM_EVENT_DELETE:
1156 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1157 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1158 bfa_fcs_rport_free(rport);
1159 break;
1160
1161 case RPSM_EVENT_PLOGI_RCVD:
1162 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1163 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1164 bfa_fcs_rport_send_plogiacc(rport, NULL);
1165 break;
1166
1167 case RPSM_EVENT_SCN:
1168 case RPSM_EVENT_LOGO_RCVD:
1169 case RPSM_EVENT_PLOGI_SEND:
1170 break;
1171
1172 case RPSM_EVENT_ADDRESS_CHANGE:
1173 rport->ns_retries = 0; /* reset the retry count */
1174 break;
1175
1176 case RPSM_EVENT_LOGO_IMP:
1177 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1178 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1179 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1180 bfa_fcs_rport_timeout, rport,
1181 bfa_fcs_rport_del_timeout);
1182 break;
1183
1184 case RPSM_EVENT_PLOGI_COMP:
1185 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1186 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1187 bfa_fcs_rport_hal_online(rport);
1188 break;
1189
1190 default:
1191 bfa_assert(0);
1192 }
1193}
1194
1195/**
1196 * Nameserver discovery failed. Waiting for timeout to retry.
1197 */
1198static void
1199bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
1200 enum rport_event event)
1201{
1202 bfa_trc(rport->fcs, rport->pwwn);
1203 bfa_trc(rport->fcs, rport->pid);
1204 bfa_trc(rport->fcs, event);
1205
1206 switch (event) {
1207 case RPSM_EVENT_TIMEOUT:
1208 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1209 bfa_fcs_rport_send_gidpn(rport, NULL);
1210 break;
1211
1212 case RPSM_EVENT_SCN:
1213 case RPSM_EVENT_ADDRESS_CHANGE:
1214 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1215 bfa_timer_stop(&rport->timer);
1216 rport->ns_retries = 0;
1217 bfa_fcs_rport_send_gidpn(rport, NULL);
1218 break;
1219
1220 case RPSM_EVENT_DELETE:
1221 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1222 bfa_timer_stop(&rport->timer);
1223 bfa_fcs_rport_free(rport);
1224 break;
1225
1226 case RPSM_EVENT_PLOGI_RCVD:
1227 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1228 bfa_timer_stop(&rport->timer);
1229 bfa_fcs_rport_send_plogiacc(rport, NULL);
1230 break;
1231
1232 case RPSM_EVENT_LOGO_IMP:
1233 rport->pid = 0;
1234 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1235 bfa_timer_stop(&rport->timer);
1236 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1237 bfa_fcs_rport_timeout, rport,
1238 bfa_fcs_rport_del_timeout);
1239 break;
1240
1241 case RPSM_EVENT_LOGO_RCVD:
1242 bfa_fcs_rport_send_logo_acc(rport);
1243 break;
1244
1245 case RPSM_EVENT_PLOGI_COMP:
1246 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1247 bfa_timer_stop(&rport->timer);
1248 bfa_fcs_rport_hal_online(rport);
1249 break;
1250
1251 default:
1252 bfa_assert(0);
1253 }
1254}
1255
1256/**
1257 * Rport address has changed. Nameserver discovery request is sent.
1258 */
1259static void
1260bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
1261 enum rport_event event)
1262{
1263 bfa_trc(rport->fcs, rport->pwwn);
1264 bfa_trc(rport->fcs, rport->pid);
1265 bfa_trc(rport->fcs, event);
1266
1267 switch (event) {
1268 case RPSM_EVENT_ACCEPTED:
1269 case RPSM_EVENT_ADDRESS_CHANGE:
1270 if (rport->pid) {
1271 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1272 bfa_fcs_rport_send_plogi(rport, NULL);
1273 } else {
1274 bfa_sm_set_state(rport,
1275 bfa_fcs_rport_sm_nsdisc_sending);
1276 rport->ns_retries = 0;
1277 bfa_fcs_rport_send_gidpn(rport, NULL);
1278 }
1279 break;
1280
1281 case RPSM_EVENT_FAILED:
1282 rport->ns_retries++;
1283 if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
1284 bfa_sm_set_state(rport,
1285 bfa_fcs_rport_sm_nsdisc_sending);
1286 bfa_fcs_rport_send_gidpn(rport, NULL);
1287 } else {
1288 rport->pid = 0;
1289 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1290 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1291 bfa_fcs_rport_timeout, rport,
1292 bfa_fcs_rport_del_timeout);
1293 };
1294 break;
1295
1296 case RPSM_EVENT_DELETE:
1297 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1298 bfa_fcxp_discard(rport->fcxp);
1299 bfa_fcs_rport_free(rport);
1300 break;
1301
1302 case RPSM_EVENT_PLOGI_RCVD:
1303 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1304 bfa_fcxp_discard(rport->fcxp);
1305 bfa_fcs_rport_send_plogiacc(rport, NULL);
1306 break;
1307
1308 case RPSM_EVENT_LOGO_IMP:
1309 rport->pid = 0;
1310 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1311 bfa_fcxp_discard(rport->fcxp);
1312 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1313 bfa_fcs_rport_timeout, rport,
1314 bfa_fcs_rport_del_timeout);
1315 break;
1316
1317 case RPSM_EVENT_SCN:
1318 /**
1319 * ignore, wait for NS query response
1320 */
1321 break;
1322
1323 case RPSM_EVENT_LOGO_RCVD:
1324 /**
1325 * Not logged-in yet. Accept LOGO.
1326 */
1327 bfa_fcs_rport_send_logo_acc(rport);
1328 break;
1329
1330 case RPSM_EVENT_PLOGI_COMP:
1331 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1332 bfa_fcxp_discard(rport->fcxp);
1333 bfa_fcs_rport_hal_online(rport);
1334 break;
1335
1336 default:
1337 bfa_assert(0);
1338 }
1339}
1340
1341
1342
1343/**
1344 * fcs_rport_private FCS RPORT provate functions
1345 */
1346
1347static void
1348bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1349{
1350 struct bfa_fcs_rport_s *rport = rport_cbarg;
1351 struct bfa_fcs_port_s *port = rport->port;
1352 struct fchs_s fchs;
1353 int len;
1354 struct bfa_fcxp_s *fcxp;
1355
1356 bfa_trc(rport->fcs, rport->pwwn);
1357
1358 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1359 if (!fcxp) {
1360 bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1361 bfa_fcs_rport_send_plogi, rport);
1362 return;
1363 }
1364 rport->fcxp = fcxp;
1365
1366 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1367 bfa_fcs_port_get_fcid(port), 0,
1368 port->port_cfg.pwwn, port->port_cfg.nwwn,
1369 bfa_pport_get_maxfrsize(port->fcs->bfa));
1370
1371 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1372 FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
1373 (void *)rport, FC_MAX_PDUSZ, FC_RA_TOV);
1374
1375 rport->stats.plogis++;
1376 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1377}
1378
1379static void
1380bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1381 bfa_status_t req_status, u32 rsp_len,
1382 u32 resid_len, struct fchs_s *rsp_fchs)
1383{
1384 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
1385 struct fc_logi_s *plogi_rsp;
1386 struct fc_ls_rjt_s *ls_rjt;
1387 struct bfa_fcs_rport_s *twin;
1388 struct list_head *qe;
1389
1390 bfa_trc(rport->fcs, rport->pwwn);
1391
1392 /*
1393 * Sanity Checks
1394 */
1395 if (req_status != BFA_STATUS_OK) {
1396 bfa_trc(rport->fcs, req_status);
1397 rport->stats.plogi_failed++;
1398 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1399 return;
1400 }
1401
1402 plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp);
1403
1404 /**
1405 * Check for failure first.
1406 */
1407 if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) {
1408 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
1409
1410 bfa_trc(rport->fcs, ls_rjt->reason_code);
1411 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1412
1413 rport->stats.plogi_rejects++;
1414 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1415 return;
1416 }
1417
1418 /**
1419 * PLOGI is complete. Make sure this device is not one of the known
1420 * device with a new FC port address.
1421 */
1422 list_for_each(qe, &rport->port->rport_q) {
1423 twin = (struct bfa_fcs_rport_s *)qe;
1424 if (twin == rport)
1425 continue;
1426 if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) {
1427 bfa_trc(rport->fcs, twin->pid);
1428 bfa_trc(rport->fcs, rport->pid);
1429
1430 /*
1431 * Update plogi stats in twin
1432 */
1433 twin->stats.plogis += rport->stats.plogis;
1434 twin->stats.plogi_rejects += rport->stats.plogi_rejects;
1435 twin->stats.plogi_timeouts +=
1436 rport->stats.plogi_timeouts;
1437 twin->stats.plogi_failed += rport->stats.plogi_failed;
1438 twin->stats.plogi_rcvd += rport->stats.plogi_rcvd;
1439 twin->stats.plogi_accs++;
1440
1441 bfa_fcs_rport_delete(rport);
1442
1443 bfa_fcs_rport_update(twin, plogi_rsp);
1444 twin->pid = rsp_fchs->s_id;
1445 bfa_sm_send_event(twin, RPSM_EVENT_PLOGI_COMP);
1446 return;
1447 }
1448 }
1449
1450 /**
1451 * Normal login path -- no evil twins.
1452 */
1453 rport->stats.plogi_accs++;
1454 bfa_fcs_rport_update(rport, plogi_rsp);
1455 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1456}
1457
1458static void
1459bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1460{
1461 struct bfa_fcs_rport_s *rport = rport_cbarg;
1462 struct bfa_fcs_port_s *port = rport->port;
1463 struct fchs_s fchs;
1464 int len;
1465 struct bfa_fcxp_s *fcxp;
1466
1467 bfa_trc(rport->fcs, rport->pwwn);
1468 bfa_trc(rport->fcs, rport->reply_oxid);
1469
1470 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1471 if (!fcxp) {
1472 bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1473 bfa_fcs_rport_send_plogiacc, rport);
1474 return;
1475 }
1476 rport->fcxp = fcxp;
1477
1478 len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1479 bfa_fcs_port_get_fcid(port), rport->reply_oxid,
1480 port->port_cfg.pwwn, port->port_cfg.nwwn,
1481 bfa_pport_get_maxfrsize(port->fcs->bfa));
1482
1483 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1484 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1485
1486 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1487}
1488
1489static void
1490bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1491{
1492 struct bfa_fcs_rport_s *rport = rport_cbarg;
1493 struct bfa_fcs_port_s *port = rport->port;
1494 struct fchs_s fchs;
1495 int len;
1496 struct bfa_fcxp_s *fcxp;
1497
1498 bfa_trc(rport->fcs, rport->pwwn);
1499
1500 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1501 if (!fcxp) {
1502 bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1503 bfa_fcs_rport_send_adisc, rport);
1504 return;
1505 }
1506 rport->fcxp = fcxp;
1507
1508 len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1509 bfa_fcs_port_get_fcid(port), 0,
1510 port->port_cfg.pwwn, port->port_cfg.nwwn);
1511
1512 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1513 FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response,
1514 rport, FC_MAX_PDUSZ, FC_RA_TOV);
1515
1516 rport->stats.adisc_sent++;
1517 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1518}
1519
1520static void
1521bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1522 bfa_status_t req_status, u32 rsp_len,
1523 u32 resid_len, struct fchs_s *rsp_fchs)
1524{
1525 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
1526 void *pld = bfa_fcxp_get_rspbuf(fcxp);
1527 struct fc_ls_rjt_s *ls_rjt;
1528
1529 if (req_status != BFA_STATUS_OK) {
1530 bfa_trc(rport->fcs, req_status);
1531 rport->stats.adisc_failed++;
1532 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1533 return;
1534 }
1535
1536 if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn,
1537 rport->nwwn) == FC_PARSE_OK) {
1538 rport->stats.adisc_accs++;
1539 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1540 return;
1541 }
1542
1543 rport->stats.adisc_rejects++;
1544 ls_rjt = pld;
1545 bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code);
1546 bfa_trc(rport->fcs, ls_rjt->reason_code);
1547 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1548 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1549}
1550
1551static void
1552bfa_fcs_rport_send_gidpn(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1553{
1554 struct bfa_fcs_rport_s *rport = rport_cbarg;
1555 struct bfa_fcs_port_s *port = rport->port;
1556 struct fchs_s fchs;
1557 struct bfa_fcxp_s *fcxp;
1558 int len;
1559
1560 bfa_trc(rport->fcs, rport->pid);
1561
1562 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1563 if (!fcxp) {
1564 bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1565 bfa_fcs_rport_send_gidpn, rport);
1566 return;
1567 }
1568 rport->fcxp = fcxp;
1569
1570 len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1571 bfa_fcs_port_get_fcid(port), 0, rport->pwwn);
1572
1573 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1574 FC_CLASS_3, len, &fchs, bfa_fcs_rport_gidpn_response,
1575 (void *)rport, FC_MAX_PDUSZ, FC_RA_TOV);
1576
1577 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1578}
1579
1580static void
1581bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1582 bfa_status_t req_status, u32 rsp_len,
1583 u32 resid_len, struct fchs_s *rsp_fchs)
1584{
1585 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
1586 struct bfa_fcs_rport_s *twin;
1587 struct list_head *qe;
1588 struct ct_hdr_s *cthdr;
1589 struct fcgs_gidpn_resp_s *gidpn_rsp;
1590
1591 bfa_trc(rport->fcs, rport->pwwn);
1592
1593 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1594 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
1595
1596 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1597 /*
1598 * Check if the pid is the same as before.
1599 */
1600 gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1);
1601
1602 if (gidpn_rsp->dap == rport->pid) {
1603 /*
1604 * Device is online
1605 */
1606 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1607 } else {
1608 /*
1609 * Device's PID has changed. We need to cleanup and
1610 * re-login. If there is another device with the the
1611 * newly discovered pid, send an scn notice so that its
1612 * new pid can be discovered.
1613 */
1614 list_for_each(qe, &rport->port->rport_q) {
1615 twin = (struct bfa_fcs_rport_s *)qe;
1616 if (twin == rport)
1617 continue;
1618 if (gidpn_rsp->dap == twin->pid) {
1619 bfa_trc(rport->fcs, twin->pid);
1620 bfa_trc(rport->fcs, rport->pid);
1621
1622 twin->pid = 0;
1623 bfa_sm_send_event(twin,
1624 RPSM_EVENT_ADDRESS_CHANGE);
1625 }
1626 }
1627 rport->pid = gidpn_rsp->dap;
1628 bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_CHANGE);
1629 }
1630 return;
1631 }
1632
1633 /*
1634 * Reject Response
1635 */
1636 switch (cthdr->reason_code) {
1637 case CT_RSN_LOGICAL_BUSY:
1638 /*
1639 * Need to retry
1640 */
1641 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1642 break;
1643
1644 case CT_RSN_UNABLE_TO_PERF:
1645 /*
1646 * device doesn't exist : Start timer to cleanup this later.
1647 */
1648 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1649 break;
1650
1651 default:
1652 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1653 break;
1654 }
1655}
1656
1657/**
1658 * Called to send a logout to the rport.
1659 */
1660static void
1661bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1662{
1663 struct bfa_fcs_rport_s *rport = rport_cbarg;
1664 struct bfa_fcs_port_s *port;
1665 struct fchs_s fchs;
1666 struct bfa_fcxp_s *fcxp;
1667 u16 len;
1668
1669 bfa_trc(rport->fcs, rport->pid);
1670
1671 port = rport->port;
1672
1673 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1674 if (!fcxp) {
1675 bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1676 bfa_fcs_rport_send_logo, rport);
1677 return;
1678 }
1679 rport->fcxp = fcxp;
1680
1681 len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1682 bfa_fcs_port_get_fcid(port), 0,
1683 bfa_fcs_port_get_pwwn(port));
1684
1685 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1686 FC_CLASS_3, len, &fchs, NULL, rport, FC_MAX_PDUSZ,
1687 FC_ED_TOV);
1688
1689 rport->stats.logos++;
1690 bfa_fcxp_discard(rport->fcxp);
1691 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1692}
1693
1694/**
1695 * Send ACC for a LOGO received.
1696 */
1697static void
1698bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
1699{
1700 struct bfa_fcs_rport_s *rport = rport_cbarg;
1701 struct bfa_fcs_port_s *port;
1702 struct fchs_s fchs;
1703 struct bfa_fcxp_s *fcxp;
1704 u16 len;
1705
1706 bfa_trc(rport->fcs, rport->pid);
1707
1708 port = rport->port;
1709
1710 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1711 if (!fcxp)
1712 return;
1713
1714 rport->stats.logo_rcvd++;
1715 len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1716 bfa_fcs_port_get_fcid(port), rport->reply_oxid);
1717
1718 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1719 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1720}
1721
1722/**
1723 * This routine will be called by bfa_timer on timer timeouts.
1724 *
1725 * param[in] rport - pointer to bfa_fcs_port_ns_t.
1726 * param[out] rport_status - pointer to return vport status in
1727 *
1728 * return
1729 * void
1730 *
1731* Special Considerations:
1732 *
1733 * note
1734 */
1735static void
1736bfa_fcs_rport_timeout(void *arg)
1737{
1738 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)arg;
1739
1740 rport->stats.plogi_timeouts++;
1741 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1742}
1743
1744static void
1745bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
1746 struct fchs_s *rx_fchs, u16 len)
1747{
1748 struct bfa_fcxp_s *fcxp;
1749 struct fchs_s fchs;
1750 struct bfa_fcs_port_s *port = rport->port;
1751 struct fc_prli_s *prli;
1752
1753 bfa_trc(port->fcs, rx_fchs->s_id);
1754 bfa_trc(port->fcs, rx_fchs->d_id);
1755
1756 rport->stats.prli_rcvd++;
1757
1758 if (BFA_FCS_VPORT_IS_TARGET_MODE(port)) {
1759 /*
1760 * Target Mode : Let the fcptm handle it
1761 */
1762 bfa_fcs_tin_rx_prli(rport->tin, rx_fchs, len);
1763 return;
1764 }
1765
1766 /*
1767 * We are either in Initiator or ipfc Mode
1768 */
1769 prli = (struct fc_prli_s *) (rx_fchs + 1);
1770
1771 if (prli->parampage.servparams.initiator) {
1772 bfa_trc(rport->fcs, prli->parampage.type);
1773 rport->scsi_function = BFA_RPORT_INITIATOR;
1774 bfa_fcs_itnim_is_initiator(rport->itnim);
1775 } else {
1776 /*
1777 * @todo: PRLI from a target ?
1778 */
1779 bfa_trc(port->fcs, rx_fchs->s_id);
1780 rport->scsi_function = BFA_RPORT_TARGET;
1781 }
1782
1783 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1784 if (!fcxp)
1785 return;
1786
1787 len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
1788 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
1789 port->port_cfg.roles);
1790
1791 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1792 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1793}
1794
1795static void
1796bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
1797 struct fchs_s *rx_fchs, u16 len)
1798{
1799 struct bfa_fcxp_s *fcxp;
1800 struct fchs_s fchs;
1801 struct bfa_fcs_port_s *port = rport->port;
1802 struct fc_rpsc_speed_info_s speeds;
1803 struct bfa_pport_attr_s pport_attr;
1804
1805 bfa_trc(port->fcs, rx_fchs->s_id);
1806 bfa_trc(port->fcs, rx_fchs->d_id);
1807
1808 rport->stats.rpsc_rcvd++;
1809 speeds.port_speed_cap =
1810 RPSC_SPEED_CAP_1G | RPSC_SPEED_CAP_2G | RPSC_SPEED_CAP_4G |
1811 RPSC_SPEED_CAP_8G;
1812
1813 /*
1814 * get curent speed from pport attributes from BFA
1815 */
1816 bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
1817
1818 speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
1819
1820 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1821 if (!fcxp)
1822 return;
1823
1824 len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
1825 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
1826 &speeds);
1827
1828 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1829 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1830}
1831
1832static void
1833bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
1834 struct fchs_s *rx_fchs, u16 len)
1835{
1836 struct bfa_fcxp_s *fcxp;
1837 struct fchs_s fchs;
1838 struct bfa_fcs_port_s *port = rport->port;
1839 struct fc_adisc_s *adisc;
1840
1841 bfa_trc(port->fcs, rx_fchs->s_id);
1842 bfa_trc(port->fcs, rx_fchs->d_id);
1843
1844 rport->stats.adisc_rcvd++;
1845
1846 if (BFA_FCS_VPORT_IS_TARGET_MODE(port)) {
1847 /*
1848 * @todo : Target Mode handling
1849 */
1850 bfa_trc(port->fcs, rx_fchs->d_id);
1851 bfa_assert(0);
1852 return;
1853 }
1854
1855 adisc = (struct fc_adisc_s *) (rx_fchs + 1);
1856
1857 /*
1858 * Accept if the itnim for this rport is online. Else reject the ADISC
1859 */
1860 if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) {
1861
1862 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1863 if (!fcxp)
1864 return;
1865
1866 len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1867 rx_fchs->s_id,
1868 bfa_fcs_port_get_fcid(port),
1869 rx_fchs->ox_id, port->port_cfg.pwwn,
1870 port->port_cfg.nwwn);
1871
1872 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
1873 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
1874 FC_MAX_PDUSZ, 0);
1875 } else {
1876 rport->stats.adisc_rejected++;
1877 bfa_fcs_rport_send_ls_rjt(rport, rx_fchs,
1878 FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD,
1879 FC_LS_RJT_EXP_LOGIN_REQUIRED);
1880 }
1881
1882}
1883
1884static void
1885bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport)
1886{
1887 struct bfa_fcs_port_s *port = rport->port;
1888 struct bfa_rport_info_s rport_info;
1889
1890 rport_info.pid = rport->pid;
1891 rport_info.local_pid = port->pid;
1892 rport_info.lp_tag = port->lp_tag;
1893 rport_info.vf_id = port->fabric->vf_id;
1894 rport_info.vf_en = port->fabric->is_vf;
1895 rport_info.fc_class = rport->fc_cos;
1896 rport_info.cisc = rport->cisc;
1897 rport_info.max_frmsz = rport->maxfrsize;
1898 bfa_rport_online(rport->bfa_rport, &rport_info);
1899}
1900
1901static void
1902bfa_fcs_rport_fc4_pause(struct bfa_fcs_rport_s *rport)
1903{
1904 if (bfa_fcs_port_is_initiator(rport->port))
1905 bfa_fcs_itnim_pause(rport->itnim);
1906
1907 if (bfa_fcs_port_is_target(rport->port))
1908 bfa_fcs_tin_pause(rport->tin);
1909}
1910
1911static void
1912bfa_fcs_rport_fc4_resume(struct bfa_fcs_rport_s *rport)
1913{
1914 if (bfa_fcs_port_is_initiator(rport->port))
1915 bfa_fcs_itnim_resume(rport->itnim);
1916
1917 if (bfa_fcs_port_is_target(rport->port))
1918 bfa_fcs_tin_resume(rport->tin);
1919}
1920
1921static struct bfa_fcs_rport_s *
1922bfa_fcs_rport_alloc(struct bfa_fcs_port_s *port, wwn_t pwwn, u32 rpid)
1923{
1924 struct bfa_fcs_s *fcs = port->fcs;
1925 struct bfa_fcs_rport_s *rport;
1926 struct bfad_rport_s *rport_drv;
1927
1928 /**
1929 * allocate rport
1930 */
1931 if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv)
1932 != BFA_STATUS_OK) {
1933 bfa_trc(fcs, rpid);
1934 return NULL;
1935 }
1936
1937 /*
1938 * Initialize r-port
1939 */
1940 rport->port = port;
1941 rport->fcs = fcs;
1942 rport->rp_drv = rport_drv;
1943 rport->pid = rpid;
1944 rport->pwwn = pwwn;
1945
1946 /**
1947 * allocate BFA rport
1948 */
1949 rport->bfa_rport = bfa_rport_create(port->fcs->bfa, rport);
1950 if (!rport->bfa_rport) {
1951 bfa_trc(fcs, rpid);
1952 kfree(rport_drv);
1953 return NULL;
1954 }
1955
1956 /**
1957 * allocate FC-4s
1958 */
1959 bfa_assert(bfa_fcs_port_is_initiator(port) ^
1960 bfa_fcs_port_is_target(port));
1961
1962 if (bfa_fcs_port_is_initiator(port)) {
1963 rport->itnim = bfa_fcs_itnim_create(rport);
1964 if (!rport->itnim) {
1965 bfa_trc(fcs, rpid);
1966 bfa_rport_delete(rport->bfa_rport);
1967 kfree(rport_drv);
1968 return NULL;
1969 }
1970 }
1971
1972 if (bfa_fcs_port_is_target(port)) {
1973 rport->tin = bfa_fcs_tin_create(rport);
1974 if (!rport->tin) {
1975 bfa_trc(fcs, rpid);
1976 bfa_rport_delete(rport->bfa_rport);
1977 kfree(rport_drv);
1978 return NULL;
1979 }
1980 }
1981
1982 bfa_fcs_port_add_rport(port, rport);
1983
1984 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1985
1986 /*
1987 * Initialize the Rport Features(RPF) Sub Module
1988 */
1989 if (!BFA_FCS_PID_IS_WKA(rport->pid))
1990 bfa_fcs_rpf_init(rport);
1991
1992 return rport;
1993}
1994
1995
1996static void
1997bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
1998{
1999 struct bfa_fcs_port_s *port = rport->port;
2000
2001 /**
2002 * - delete FC-4s
2003 * - delete BFA rport
2004 * - remove from queue of rports
2005 */
2006 if (bfa_fcs_port_is_initiator(port))
2007 bfa_fcs_itnim_delete(rport->itnim);
2008
2009 if (bfa_fcs_port_is_target(port))
2010 bfa_fcs_tin_delete(rport->tin);
2011
2012 bfa_rport_delete(rport->bfa_rport);
2013 bfa_fcs_port_del_rport(port, rport);
2014 kfree(rport->rp_drv);
2015}
2016
2017static void
2018bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
2019 enum bfa_rport_aen_event event,
2020 struct bfa_rport_aen_data_s *data)
2021{
2022 union bfa_aen_data_u aen_data;
2023 struct bfa_log_mod_s *logmod = rport->fcs->logm;
2024 wwn_t lpwwn = bfa_fcs_port_get_pwwn(rport->port);
2025 wwn_t rpwwn = rport->pwwn;
2026 char lpwwn_ptr[BFA_STRING_32];
2027 char rpwwn_ptr[BFA_STRING_32];
2028 char *prio_str[] = { "unknown", "high", "medium", "low" };
2029
2030 wwn2str(lpwwn_ptr, lpwwn);
2031 wwn2str(rpwwn_ptr, rpwwn);
2032
2033 switch (event) {
2034 case BFA_RPORT_AEN_ONLINE:
2035 bfa_log(logmod, BFA_AEN_RPORT_ONLINE, rpwwn_ptr, lpwwn_ptr);
2036 break;
2037 case BFA_RPORT_AEN_OFFLINE:
2038 bfa_log(logmod, BFA_AEN_RPORT_OFFLINE, rpwwn_ptr, lpwwn_ptr);
2039 break;
2040 case BFA_RPORT_AEN_DISCONNECT:
2041 bfa_log(logmod, BFA_AEN_RPORT_DISCONNECT, rpwwn_ptr, lpwwn_ptr);
2042 break;
2043 case BFA_RPORT_AEN_QOS_PRIO:
2044 aen_data.rport.priv.qos = data->priv.qos;
2045 bfa_log(logmod, BFA_AEN_RPORT_QOS_PRIO,
2046 prio_str[aen_data.rport.priv.qos.qos_priority],
2047 rpwwn_ptr, lpwwn_ptr);
2048 break;
2049 case BFA_RPORT_AEN_QOS_FLOWID:
2050 aen_data.rport.priv.qos = data->priv.qos;
2051 bfa_log(logmod, BFA_AEN_RPORT_QOS_FLOWID,
2052 aen_data.rport.priv.qos.qos_flow_id, rpwwn_ptr,
2053 lpwwn_ptr);
2054 break;
2055 default:
2056 break;
2057 }
2058
2059 aen_data.rport.vf_id = rport->port->fabric->vf_id;
2060 aen_data.rport.ppwwn =
2061 bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(rport->fcs));
2062 aen_data.rport.lpwwn = lpwwn;
2063 aen_data.rport.rpwwn = rpwwn;
2064}
2065
2066static void
2067bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
2068{
2069 struct bfa_fcs_port_s *port = rport->port;
2070
2071 rport->stats.onlines++;
2072
2073 if (bfa_fcs_port_is_initiator(port)) {
2074 bfa_fcs_itnim_rport_online(rport->itnim);
2075 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2076 bfa_fcs_rpf_rport_online(rport);
2077 };
2078
2079 if (bfa_fcs_port_is_target(port))
2080 bfa_fcs_tin_rport_online(rport->tin);
2081
2082 /*
2083 * Don't post events for well known addresses
2084 */
2085 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2086 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL);
2087}
2088
2089static void
2090bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
2091{
2092 struct bfa_fcs_port_s *port = rport->port;
2093
2094 rport->stats.offlines++;
2095
2096 /*
2097 * Don't post events for well known addresses
2098 */
2099 if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
2100 if (bfa_fcs_port_is_online(rport->port) == BFA_TRUE) {
2101 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_DISCONNECT,
2102 NULL);
2103 } else {
2104 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_OFFLINE,
2105 NULL);
2106 }
2107 }
2108
2109 if (bfa_fcs_port_is_initiator(port)) {
2110 bfa_fcs_itnim_rport_offline(rport->itnim);
2111 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2112 bfa_fcs_rpf_rport_offline(rport);
2113 }
2114
2115 if (bfa_fcs_port_is_target(port))
2116 bfa_fcs_tin_rport_offline(rport->tin);
2117}
2118
2119/**
2120 * Update rport parameters from PLOGI or PLOGI accept.
2121 */
2122static void
2123bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
2124{
2125 struct bfa_fcs_port_s *port = rport->port;
2126
2127 /**
2128 * - port name
2129 * - node name
2130 */
2131 rport->pwwn = plogi->port_name;
2132 rport->nwwn = plogi->node_name;
2133
2134 /**
2135 * - class of service
2136 */
2137 rport->fc_cos = 0;
2138 if (plogi->class3.class_valid)
2139 rport->fc_cos = FC_CLASS_3;
2140
2141 if (plogi->class2.class_valid)
2142 rport->fc_cos |= FC_CLASS_2;
2143
2144 /**
2145 * - CISC
2146 * - MAX receive frame size
2147 */
2148 rport->cisc = plogi->csp.cisc;
2149 rport->maxfrsize = bfa_os_ntohs(plogi->class3.rxsz);
2150
2151 bfa_trc(port->fcs, bfa_os_ntohs(plogi->csp.bbcred));
2152 bfa_trc(port->fcs, port->fabric->bb_credit);
2153 /**
2154 * Direct Attach P2P mode :
2155 * This is to handle a bug (233476) in IBM targets in Direct Attach
2156 * Mode. Basically, in FLOGI Accept the target would have erroneously
2157 * set the BB Credit to the value used in the FLOGI sent by the HBA.
2158 * It uses the correct value (its own BB credit) in PLOGI.
2159 */
2160 if ((!bfa_fcs_fabric_is_switched(port->fabric))
2161 && (bfa_os_ntohs(plogi->csp.bbcred) < port->fabric->bb_credit)) {
2162
2163 bfa_trc(port->fcs, bfa_os_ntohs(plogi->csp.bbcred));
2164 bfa_trc(port->fcs, port->fabric->bb_credit);
2165
2166 port->fabric->bb_credit = bfa_os_ntohs(plogi->csp.bbcred);
2167 bfa_pport_set_tx_bbcredit(port->fcs->bfa,
2168 port->fabric->bb_credit);
2169 }
2170
2171}
2172
2173/**
2174 * Called to handle LOGO received from an existing remote port.
2175 */
2176static void
2177bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
2178{
2179 rport->reply_oxid = fchs->ox_id;
2180 bfa_trc(rport->fcs, rport->reply_oxid);
2181
2182 rport->stats.logo_rcvd++;
2183 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD);
2184}
2185
2186
2187
2188/**
2189 * fcs_rport_public FCS rport public interfaces
2190 */
2191
2192/**
2193 * Called by bport/vport to create a remote port instance for a discovered
2194 * remote device.
2195 *
2196 * @param[in] port - base port or vport
2197 * @param[in] rpid - remote port ID
2198 *
2199 * @return None
2200 */
2201struct bfa_fcs_rport_s *
2202bfa_fcs_rport_create(struct bfa_fcs_port_s *port, u32 rpid)
2203{
2204 struct bfa_fcs_rport_s *rport;
2205
2206 bfa_trc(port->fcs, rpid);
2207 rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid);
2208 if (!rport)
2209 return NULL;
2210
2211 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
2212 return rport;
2213}
2214
2215/**
2216 * Called to create a rport for which only the wwn is known.
2217 *
2218 * @param[in] port - base port
2219 * @param[in] rpwwn - remote port wwn
2220 *
2221 * @return None
2222 */
2223struct bfa_fcs_rport_s *
2224bfa_fcs_rport_create_by_wwn(struct bfa_fcs_port_s *port, wwn_t rpwwn)
2225{
2226 struct bfa_fcs_rport_s *rport;
2227
2228 bfa_trc(port->fcs, rpwwn);
2229 rport = bfa_fcs_rport_alloc(port, rpwwn, 0);
2230 if (!rport)
2231 return NULL;
2232
2233 bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC);
2234 return rport;
2235}
2236
2237/**
2238 * Called by bport in private loop topology to indicate that a
2239 * rport has been discovered and plogi has been completed.
2240 *
2241 * @param[in] port - base port or vport
2242 * @param[in] rpid - remote port ID
2243 */
2244void
2245bfa_fcs_rport_start(struct bfa_fcs_port_s *port, struct fchs_s *fchs,
2246 struct fc_logi_s *plogi)
2247{
2248 struct bfa_fcs_rport_s *rport;
2249
2250 rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id);
2251 if (!rport)
2252 return;
2253
2254 bfa_fcs_rport_update(rport, plogi);
2255
2256 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP);
2257}
2258
2259/**
2260 * Called by bport/vport to handle PLOGI received from a new remote port.
2261 * If an existing rport does a plogi, it will be handled separately.
2262 */
2263void
2264bfa_fcs_rport_plogi_create(struct bfa_fcs_port_s *port, struct fchs_s *fchs,
2265 struct fc_logi_s *plogi)
2266{
2267 struct bfa_fcs_rport_s *rport;
2268
2269 rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id);
2270 if (!rport)
2271 return;
2272
2273 bfa_fcs_rport_update(rport, plogi);
2274
2275 rport->reply_oxid = fchs->ox_id;
2276 bfa_trc(rport->fcs, rport->reply_oxid);
2277
2278 rport->stats.plogi_rcvd++;
2279 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2280}
2281
2282static int
2283wwn_compare(wwn_t wwn1, wwn_t wwn2)
2284{
2285 u8 *b1 = (u8 *) &wwn1;
2286 u8 *b2 = (u8 *) &wwn2;
2287 int i;
2288
2289 for (i = 0; i < sizeof(wwn_t); i++) {
2290 if (b1[i] < b2[i])
2291 return -1;
2292 if (b1[i] > b2[i])
2293 return 1;
2294 }
2295 return 0;
2296}
2297
2298/**
2299 * Called by bport/vport to handle PLOGI received from an existing
2300 * remote port.
2301 */
2302void
2303bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2304 struct fc_logi_s *plogi)
2305{
2306 /**
2307 * @todo Handle P2P and initiator-initiator.
2308 */
2309
2310 bfa_fcs_rport_update(rport, plogi);
2311
2312 rport->reply_oxid = rx_fchs->ox_id;
2313 bfa_trc(rport->fcs, rport->reply_oxid);
2314
2315 /**
2316 * In Switched fabric topology,
2317 * PLOGI to each other. If our pwwn is smaller, ignore it,
2318 * if it is not a well known address.
2319 * If the link topology is N2N,
2320 * this Plogi should be accepted.
2321 */
2322 if ((wwn_compare(rport->port->port_cfg.pwwn, rport->pwwn) == -1)
2323 && (bfa_fcs_fabric_is_switched(rport->port->fabric))
2324 && (!BFA_FCS_PID_IS_WKA(rport->pid))) {
2325 bfa_trc(rport->fcs, rport->pid);
2326 return;
2327 }
2328
2329 rport->stats.plogi_rcvd++;
2330 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2331}
2332
2333/**
2334 * Called by bport/vport to delete a remote port instance.
2335 *
2336* Rport delete is called under the following conditions:
2337 * - vport is deleted
2338 * - vf is deleted
2339 * - explicit request from OS to delete rport (vmware)
2340 */
2341void
2342bfa_fcs_rport_delete(struct bfa_fcs_rport_s *rport)
2343{
2344 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
2345}
2346
2347/**
2348 * Called by bport/vport to when a target goes offline.
2349 *
2350 */
2351void
2352bfa_fcs_rport_offline(struct bfa_fcs_rport_s *rport)
2353{
2354 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
2355}
2356
2357/**
2358 * Called by bport in n2n when a target (attached port) becomes online.
2359 *
2360 */
2361void
2362bfa_fcs_rport_online(struct bfa_fcs_rport_s *rport)
2363{
2364 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
2365}
2366
2367/**
2368 * Called by bport/vport to notify SCN for the remote port
2369 */
2370void
2371bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
2372{
2373
2374 rport->stats.rscns++;
2375 bfa_sm_send_event(rport, RPSM_EVENT_SCN);
2376}
2377
2378/**
2379 * Called by fcpim to notify that the ITN cleanup is done.
2380 */
2381void
2382bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport)
2383{
2384 bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
2385}
2386
2387/**
2388 * Called by fcptm to notify that the ITN cleanup is done.
2389 */
2390void
2391bfa_fcs_rport_tin_ack(struct bfa_fcs_rport_s *rport)
2392{
2393 bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
2394}
2395
2396/**
2397 * This routine BFA callback for bfa_rport_online() call.
2398 *
2399 * param[in] cb_arg - rport struct.
2400 *
2401 * return
2402 * void
2403 *
2404* Special Considerations:
2405 *
2406 * note
2407 */
2408void
2409bfa_cb_rport_online(void *cbarg)
2410{
2411
2412 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
2413
2414 bfa_trc(rport->fcs, rport->pwwn);
2415 bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE);
2416}
2417
2418/**
2419 * This routine BFA callback for bfa_rport_offline() call.
2420 *
2421 * param[in] rport -
2422 *
2423 * return
2424 * void
2425 *
2426 * Special Considerations:
2427 *
2428 * note
2429 */
2430void
2431bfa_cb_rport_offline(void *cbarg)
2432{
2433 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
2434
2435 bfa_trc(rport->fcs, rport->pwwn);
2436 bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE);
2437}
2438
2439/**
2440 * This routine is a static BFA callback when there is a QoS flow_id
2441 * change notification
2442 *
2443 * @param[in] rport -
2444 *
2445 * @return void
2446 *
2447 * Special Considerations:
2448 *
2449 * @note
2450 */
2451void
2452bfa_cb_rport_qos_scn_flowid(void *cbarg,
2453 struct bfa_rport_qos_attr_s old_qos_attr,
2454 struct bfa_rport_qos_attr_s new_qos_attr)
2455{
2456 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
2457 struct bfa_rport_aen_data_s aen_data;
2458
2459 bfa_trc(rport->fcs, rport->pwwn);
2460 aen_data.priv.qos = new_qos_attr;
2461 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data);
2462}
2463
2464/**
2465 * This routine is a static BFA callback when there is a QoS priority
2466 * change notification
2467 *
2468 * @param[in] rport -
2469 *
2470 * @return void
2471 *
2472 * Special Considerations:
2473 *
2474 * @note
2475 */
2476void
2477bfa_cb_rport_qos_scn_prio(void *cbarg, struct bfa_rport_qos_attr_s old_qos_attr,
2478 struct bfa_rport_qos_attr_s new_qos_attr)
2479{
2480 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
2481 struct bfa_rport_aen_data_s aen_data;
2482
2483 bfa_trc(rport->fcs, rport->pwwn);
2484 aen_data.priv.qos = new_qos_attr;
2485 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data);
2486}
2487
2488/**
2489 * Called to process any unsolicted frames from this remote port
2490 */
2491void
2492bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport)
2493{
2494 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
2495}
2496
2497/**
2498 * Called to process any unsolicted frames from this remote port
2499 */
2500void
2501bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
2502 u16 len)
2503{
2504 struct bfa_fcs_port_s *port = rport->port;
2505 struct fc_els_cmd_s *els_cmd;
2506
2507 bfa_trc(rport->fcs, fchs->s_id);
2508 bfa_trc(rport->fcs, fchs->d_id);
2509 bfa_trc(rport->fcs, fchs->type);
2510
2511 if (fchs->type != FC_TYPE_ELS)
2512 return;
2513
2514 els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
2515
2516 bfa_trc(rport->fcs, els_cmd->els_code);
2517
2518 switch (els_cmd->els_code) {
2519 case FC_ELS_LOGO:
2520 bfa_fcs_rport_process_logo(rport, fchs);
2521 break;
2522
2523 case FC_ELS_ADISC:
2524 bfa_fcs_rport_process_adisc(rport, fchs, len);
2525 break;
2526
2527 case FC_ELS_PRLO:
2528 if (bfa_fcs_port_is_initiator(port))
2529 bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len);
2530
2531 if (bfa_fcs_port_is_target(port))
2532 bfa_fcs_fcptm_uf_recv(rport->tin, fchs, len);
2533 break;
2534
2535 case FC_ELS_PRLI:
2536 bfa_fcs_rport_process_prli(rport, fchs, len);
2537 break;
2538
2539 case FC_ELS_RPSC:
2540 bfa_fcs_rport_process_rpsc(rport, fchs, len);
2541 break;
2542
2543 default:
2544 bfa_fcs_rport_send_ls_rjt(rport, fchs,
2545 FC_LS_RJT_RSN_CMD_NOT_SUPP,
2546 FC_LS_RJT_EXP_NO_ADDL_INFO);
2547 break;
2548 }
2549}
2550
2551/*
2552 * Send a LS reject
2553 */
2554static void
2555bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2556 u8 reason_code, u8 reason_code_expl)
2557{
2558 struct bfa_fcs_port_s *port = rport->port;
2559 struct fchs_s fchs;
2560 struct bfa_fcxp_s *fcxp;
2561 int len;
2562
2563 bfa_trc(rport->fcs, rx_fchs->s_id);
2564
2565 fcxp = bfa_fcs_fcxp_alloc(rport->fcs);
2566 if (!fcxp)
2567 return;
2568
2569 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
2570 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
2571 reason_code, reason_code_expl);
2572
2573 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2574 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2575}
2576
2577/**
2578 * Module initialization
2579 */
2580void
2581bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs)
2582{
2583}
2584
2585/**
2586 * Module cleanup
2587 */
2588void
2589bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs)
2590{
2591 bfa_fcs_modexit_comp(fcs);
2592}
2593
2594/**
2595 * Return state of rport.
2596 */
2597int
2598bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport)
2599{
2600 return bfa_sm_to_state(rport_sm_table, rport->sm);
2601}
2602
2603/**
2604 * Called by the Driver to set rport delete/ageout timeout
2605 *
2606 * param[in] rport timeout value in seconds.
2607 *
2608 * return None
2609 */
2610void
2611bfa_fcs_rport_set_del_timeout(u8 rport_tmo)
2612{
2613 /*
2614 * convert to Millisecs
2615 */
2616 if (rport_tmo > 0)
2617 bfa_fcs_rport_del_timeout = rport_tmo * 1000;
2618}
diff --git a/drivers/scsi/bfa/rport_api.c b/drivers/scsi/bfa/rport_api.c
new file mode 100644
index 000000000000..3dae1774181e
--- /dev/null
+++ b/drivers/scsi/bfa/rport_api.c
@@ -0,0 +1,180 @@
1/*
2 * Copyright (c) 2005-2009 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#include <bfa.h>
18#include <bfa_svc.h>
19#include "fcs_vport.h"
20#include "fcs_lport.h"
21#include "fcs_rport.h"
22#include "fcs_trcmod.h"
23
24BFA_TRC_FILE(FCS, RPORT_API);
25
26/**
27 * rport_api.c Remote port implementation.
28 */
29
30/**
31 * fcs_rport_api FCS rport API.
32 */
33
34/**
35 * Direct API to add a target by port wwn. This interface is used, for
36 * example, by bios when target pwwn is known from boot lun configuration.
37 */
38bfa_status_t
39bfa_fcs_rport_add(struct bfa_fcs_port_s *port, wwn_t *pwwn,
40 struct bfa_fcs_rport_s *rport,
41 struct bfad_rport_s *rport_drv)
42{
43 bfa_trc(port->fcs, *pwwn);
44
45 return BFA_STATUS_OK;
46}
47
48/**
49 * Direct API to remove a target and its associated resources. This
50 * interface is used, for example, by vmware driver to remove target
51 * ports from the target list for a VM.
52 */
53bfa_status_t
54bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport_in)
55{
56
57 struct bfa_fcs_rport_s *rport;
58
59 bfa_trc(rport_in->fcs, rport_in->pwwn);
60
61 rport = bfa_fcs_port_get_rport_by_pwwn(rport_in->port, rport_in->pwwn);
62 if (rport == NULL) {
63 /*
64 * TBD Error handling
65 */
66 bfa_trc(rport_in->fcs, rport_in->pid);
67 return BFA_STATUS_UNKNOWN_RWWN;
68 }
69
70 /*
71 * TBD if this remote port is online, send a logo
72 */
73 return BFA_STATUS_OK;
74
75}
76
77/**
78 * Remote device status for display/debug.
79 */
80void
81bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
82 struct bfa_rport_attr_s *rport_attr)
83{
84 struct bfa_rport_qos_attr_s qos_attr;
85 struct bfa_fcs_port_s *port = rport->port;
86
87 bfa_os_memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
88
89 rport_attr->pid = rport->pid;
90 rport_attr->pwwn = rport->pwwn;
91 rport_attr->nwwn = rport->nwwn;
92 rport_attr->cos_supported = rport->fc_cos;
93 rport_attr->df_sz = rport->maxfrsize;
94 rport_attr->state = bfa_fcs_rport_get_state(rport);
95 rport_attr->fc_cos = rport->fc_cos;
96 rport_attr->cisc = rport->cisc;
97 rport_attr->scsi_function = rport->scsi_function;
98 rport_attr->curr_speed = rport->rpf.rpsc_speed;
99 rport_attr->assigned_speed = rport->rpf.assigned_speed;
100
101 bfa_rport_get_qos_attr(rport->bfa_rport, &qos_attr);
102 rport_attr->qos_attr = qos_attr;
103
104 rport_attr->trl_enforced = BFA_FALSE;
105 if (bfa_pport_is_ratelim(port->fcs->bfa)) {
106 if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) ||
107 (rport->rpf.rpsc_speed <
108 bfa_fcs_port_get_rport_max_speed(port)))
109 rport_attr->trl_enforced = BFA_TRUE;
110 }
111
112 /*
113 * TODO
114 * rport->symname
115 */
116}
117
118/**
119 * Per remote device statistics.
120 */
121void
122bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport,
123 struct bfa_rport_stats_s *stats)
124{
125 *stats = rport->stats;
126}
127
128void
129bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport)
130{
131 bfa_os_memset((char *)&rport->stats, 0,
132 sizeof(struct bfa_rport_stats_s));
133}
134
135struct bfa_fcs_rport_s *
136bfa_fcs_rport_lookup(struct bfa_fcs_port_s *port, wwn_t rpwwn)
137{
138 struct bfa_fcs_rport_s *rport;
139
140 rport = bfa_fcs_port_get_rport_by_pwwn(port, rpwwn);
141 if (rport == NULL) {
142 /*
143 * TBD Error handling
144 */
145 }
146
147 return rport;
148}
149
150struct bfa_fcs_rport_s *
151bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_port_s *port, wwn_t rnwwn)
152{
153 struct bfa_fcs_rport_s *rport;
154
155 rport = bfa_fcs_port_get_rport_by_nwwn(port, rnwwn);
156 if (rport == NULL) {
157 /*
158 * TBD Error handling
159 */
160 }
161
162 return rport;
163}
164
165/*
166 * This API is to set the Rport's speed. Should be used when RPSC is not
167 * supported by the rport.
168 */
169void
170bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport,
171 enum bfa_pport_speed speed)
172{
173 rport->rpf.assigned_speed = speed;
174
175 /* Set this speed in f/w only if the RPSC speed is not available */
176 if (rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN)
177 bfa_rport_speed(rport->bfa_rport, speed);
178}
179
180
diff --git a/drivers/scsi/bfa/rport_ftrs.c b/drivers/scsi/bfa/rport_ftrs.c
new file mode 100644
index 000000000000..8a1f59d596c1
--- /dev/null
+++ b/drivers/scsi/bfa/rport_ftrs.c
@@ -0,0 +1,375 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * rport_ftrs.c Remote port features (RPF) implementation.
20 */
21
22#include <bfa.h>
23#include <bfa_svc.h>
24#include "fcbuild.h"
25#include "fcs_rport.h"
26#include "fcs_lport.h"
27#include "fcs_trcmod.h"
28#include "fcs_fcxp.h"
29#include "fcs.h"
30
31BFA_TRC_FILE(FCS, RPORT_FTRS);
32
33#define BFA_FCS_RPF_RETRIES (3)
34#define BFA_FCS_RPF_RETRY_TIMEOUT (1000) /* 1 sec (In millisecs) */
35
36static void bfa_fcs_rpf_send_rpsc2(void *rport_cbarg,
37 struct bfa_fcxp_s *fcxp_alloced);
38static void bfa_fcs_rpf_rpsc2_response(void *fcsarg,
39 struct bfa_fcxp_s *fcxp, void *cbarg,
40 bfa_status_t req_status, u32 rsp_len,
41 u32 resid_len,
42 struct fchs_s *rsp_fchs);
43static void bfa_fcs_rpf_timeout(void *arg);
44
45/**
46 * fcs_rport_ftrs_sm FCS rport state machine events
47 */
48
49enum rpf_event {
50 RPFSM_EVENT_RPORT_OFFLINE = 1, /* Rport offline */
51 RPFSM_EVENT_RPORT_ONLINE = 2, /* Rport online */
52 RPFSM_EVENT_FCXP_SENT = 3, /* Frame from has been sent */
53 RPFSM_EVENT_TIMEOUT = 4, /* Rport SM timeout event */
54 RPFSM_EVENT_RPSC_COMP = 5,
55 RPFSM_EVENT_RPSC_FAIL = 6,
56 RPFSM_EVENT_RPSC_ERROR = 7,
57};
58
59static void bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf,
60 enum rpf_event event);
61static void bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf,
62 enum rpf_event event);
63static void bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf,
64 enum rpf_event event);
65static void bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf,
66 enum rpf_event event);
67static void bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf,
68 enum rpf_event event);
69static void bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf,
70 enum rpf_event event);
71
72static void
73bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
74{
75 struct bfa_fcs_rport_s *rport = rpf->rport;
76
77 bfa_trc(rport->fcs, rport->pwwn);
78 bfa_trc(rport->fcs, rport->pid);
79 bfa_trc(rport->fcs, event);
80
81 switch (event) {
82 case RPFSM_EVENT_RPORT_ONLINE :
83 if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
84 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
85 rpf->rpsc_retries = 0;
86 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
87 break;
88 };
89
90 case RPFSM_EVENT_RPORT_OFFLINE :
91 break;
92
93 default:
94 bfa_assert(0);
95 }
96}
97
98static void
99bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
100{
101 struct bfa_fcs_rport_s *rport = rpf->rport;
102
103 bfa_trc(rport->fcs, event);
104
105 switch (event) {
106 case RPFSM_EVENT_FCXP_SENT:
107 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc);
108 break;
109
110 case RPFSM_EVENT_RPORT_OFFLINE :
111 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
112 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe);
113 rpf->rpsc_retries = 0;
114 break;
115
116 default:
117 bfa_assert(0);
118 }
119}
120
121static void
122bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
123{
124 struct bfa_fcs_rport_s *rport = rpf->rport;
125
126 bfa_trc(rport->fcs, rport->pid);
127 bfa_trc(rport->fcs, event);
128
129 switch (event) {
130 case RPFSM_EVENT_RPSC_COMP:
131 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
132 /* Update speed info in f/w via BFA */
133 if (rpf->rpsc_speed != BFA_PPORT_SPEED_UNKNOWN) {
134 bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed);
135 } else if (rpf->assigned_speed != BFA_PPORT_SPEED_UNKNOWN) {
136 bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed);
137 }
138 break;
139
140 case RPFSM_EVENT_RPSC_FAIL:
141 /* RPSC not supported by rport */
142 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
143 break;
144
145 case RPFSM_EVENT_RPSC_ERROR:
146 /* need to retry...delayed a bit. */
147 if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) {
148 bfa_timer_start(rport->fcs->bfa, &rpf->timer,
149 bfa_fcs_rpf_timeout, rpf,
150 BFA_FCS_RPF_RETRY_TIMEOUT);
151 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry);
152 } else {
153 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
154 }
155 break;
156
157 case RPFSM_EVENT_RPORT_OFFLINE :
158 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
159 bfa_fcxp_discard(rpf->fcxp);
160 rpf->rpsc_retries = 0;
161 break;
162
163 default:
164 bfa_assert(0);
165 }
166}
167
168static void
169bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
170{
171 struct bfa_fcs_rport_s *rport = rpf->rport;
172
173 bfa_trc(rport->fcs, rport->pid);
174 bfa_trc(rport->fcs, event);
175
176 switch (event) {
177 case RPFSM_EVENT_TIMEOUT :
178 /* re-send the RPSC */
179 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
180 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
181 break;
182
183 case RPFSM_EVENT_RPORT_OFFLINE :
184 bfa_timer_stop(&rpf->timer);
185 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
186 rpf->rpsc_retries = 0;
187 break;
188
189 default:
190 bfa_assert(0);
191 }
192}
193
194static void
195bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
196{
197 struct bfa_fcs_rport_s *rport = rpf->rport;
198
199 bfa_trc(rport->fcs, rport->pwwn);
200 bfa_trc(rport->fcs, rport->pid);
201 bfa_trc(rport->fcs, event);
202
203 switch (event) {
204 case RPFSM_EVENT_RPORT_OFFLINE :
205 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
206 rpf->rpsc_retries = 0;
207 break;
208
209 default:
210 bfa_assert(0);
211 }
212}
213
214static void
215bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
216{
217 struct bfa_fcs_rport_s *rport = rpf->rport;
218
219 bfa_trc(rport->fcs, rport->pwwn);
220 bfa_trc(rport->fcs, rport->pid);
221 bfa_trc(rport->fcs, event);
222
223 switch (event) {
224 case RPFSM_EVENT_RPORT_ONLINE :
225 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
226 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
227 break;
228
229 case RPFSM_EVENT_RPORT_OFFLINE :
230 break;
231
232 default:
233 bfa_assert(0);
234 }
235}
236/**
237 * Called when Rport is created.
238 */
239void bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport)
240{
241 struct bfa_fcs_rpf_s *rpf = &rport->rpf;
242
243 bfa_trc(rport->fcs, rport->pid);
244 rpf->rport = rport;
245
246 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit);
247}
248
249/**
250 * Called when Rport becomes online
251 */
252void bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport)
253{
254 bfa_trc(rport->fcs, rport->pid);
255
256 if (__fcs_min_cfg(rport->port->fcs))
257 return;
258
259 if (bfa_fcs_fabric_is_switched(rport->port->fabric))
260 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE);
261}
262
263/**
264 * Called when Rport becomes offline
265 */
266void bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport)
267{
268 bfa_trc(rport->fcs, rport->pid);
269
270 if (__fcs_min_cfg(rport->port->fcs))
271 return;
272
273 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE);
274}
275
276static void
277bfa_fcs_rpf_timeout(void *arg)
278{
279 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg;
280 struct bfa_fcs_rport_s *rport = rpf->rport;
281
282 bfa_trc(rport->fcs, rport->pid);
283 bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT);
284}
285
286static void
287bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
288{
289 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg;
290 struct bfa_fcs_rport_s *rport = rpf->rport;
291 struct bfa_fcs_port_s *port = rport->port;
292 struct fchs_s fchs;
293 int len;
294 struct bfa_fcxp_s *fcxp;
295
296 bfa_trc(rport->fcs, rport->pwwn);
297
298 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
299 if (!fcxp) {
300 bfa_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe,
301 bfa_fcs_rpf_send_rpsc2, rpf);
302 return;
303 }
304 rpf->fcxp = fcxp;
305
306 len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
307 bfa_fcs_port_get_fcid(port), &rport->pid, 1);
308
309 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
310 FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response,
311 rpf, FC_MAX_PDUSZ, FC_RA_TOV);
312 rport->stats.rpsc_sent++;
313 bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT);
314
315}
316
317static void
318bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
319 bfa_status_t req_status, u32 rsp_len,
320 u32 resid_len, struct fchs_s *rsp_fchs)
321{
322 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg;
323 struct bfa_fcs_rport_s *rport = rpf->rport;
324 struct fc_ls_rjt_s *ls_rjt;
325 struct fc_rpsc2_acc_s *rpsc2_acc;
326 u16 num_ents;
327
328 bfa_trc(rport->fcs, req_status);
329
330 if (req_status != BFA_STATUS_OK) {
331 bfa_trc(rport->fcs, req_status);
332 if (req_status == BFA_STATUS_ETIMER)
333 rport->stats.rpsc_failed++;
334 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
335 return;
336 }
337
338 rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp);
339 if (rpsc2_acc->els_cmd == FC_ELS_ACC) {
340 rport->stats.rpsc_accs++;
341 num_ents = bfa_os_ntohs(rpsc2_acc->num_pids);
342 bfa_trc(rport->fcs, num_ents);
343 if (num_ents > 0) {
344 bfa_assert(rpsc2_acc->port_info[0].pid != rport->pid);
345 bfa_trc(rport->fcs,
346 bfa_os_ntohs(rpsc2_acc->port_info[0].pid));
347 bfa_trc(rport->fcs,
348 bfa_os_ntohs(rpsc2_acc->port_info[0].speed));
349 bfa_trc(rport->fcs,
350 bfa_os_ntohs(rpsc2_acc->port_info[0].index));
351 bfa_trc(rport->fcs,
352 rpsc2_acc->port_info[0].type);
353
354 if (rpsc2_acc->port_info[0].speed == 0) {
355 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
356 return;
357 }
358
359 rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed(
360 bfa_os_ntohs(rpsc2_acc->port_info[0].speed));
361
362 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP);
363 }
364 } else {
365 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
366 bfa_trc(rport->fcs, ls_rjt->reason_code);
367 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
368 rport->stats.rpsc_rejects++;
369 if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) {
370 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL);
371 } else {
372 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
373 }
374 }
375}
diff --git a/drivers/scsi/bfa/scn.c b/drivers/scsi/bfa/scn.c
new file mode 100644
index 000000000000..bd4771ff62c8
--- /dev/null
+++ b/drivers/scsi/bfa/scn.c
@@ -0,0 +1,482 @@
1/*
2 * Copyright (c) 2005-2009 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 <bfa.h>
19#include <bfa_svc.h>
20#include "fcs_lport.h"
21#include "fcs_rport.h"
22#include "fcs_ms.h"
23#include "fcs_trcmod.h"
24#include "fcs_fcxp.h"
25#include "fcs.h"
26#include "lport_priv.h"
27
28BFA_TRC_FILE(FCS, SCN);
29
30#define FC_QOS_RSCN_EVENT 0x0c
31#define FC_FABRIC_NAME_RSCN_EVENT 0x0d
32
33/*
34 * forward declarations
35 */
36static void bfa_fcs_port_scn_send_scr(void *scn_cbarg,
37 struct bfa_fcxp_s *fcxp_alloced);
38static void bfa_fcs_port_scn_scr_response(void *fcsarg,
39 struct bfa_fcxp_s *fcxp,
40 void *cbarg,
41 bfa_status_t req_status,
42 u32 rsp_len,
43 u32 resid_len,
44 struct fchs_s *rsp_fchs);
45static void bfa_fcs_port_scn_send_ls_acc(struct bfa_fcs_port_s *port,
46 struct fchs_s *rx_fchs);
47static void bfa_fcs_port_scn_timeout(void *arg);
48
49/**
50 * fcs_scm_sm FCS SCN state machine
51 */
52
53/**
54 * VPort SCN State Machine events
55 */
56enum port_scn_event {
57 SCNSM_EVENT_PORT_ONLINE = 1,
58 SCNSM_EVENT_PORT_OFFLINE = 2,
59 SCNSM_EVENT_RSP_OK = 3,
60 SCNSM_EVENT_RSP_ERROR = 4,
61 SCNSM_EVENT_TIMEOUT = 5,
62 SCNSM_EVENT_SCR_SENT = 6,
63};
64
65static void bfa_fcs_port_scn_sm_offline(struct bfa_fcs_port_scn_s *scn,
66 enum port_scn_event event);
67static void bfa_fcs_port_scn_sm_sending_scr(struct bfa_fcs_port_scn_s *scn,
68 enum port_scn_event event);
69static void bfa_fcs_port_scn_sm_scr(struct bfa_fcs_port_scn_s *scn,
70 enum port_scn_event event);
71static void bfa_fcs_port_scn_sm_scr_retry(struct bfa_fcs_port_scn_s *scn,
72 enum port_scn_event event);
73static void bfa_fcs_port_scn_sm_online(struct bfa_fcs_port_scn_s *scn,
74 enum port_scn_event event);
75
76/**
77 * Starting state - awaiting link up.
78 */
79static void
80bfa_fcs_port_scn_sm_offline(struct bfa_fcs_port_scn_s *scn,
81 enum port_scn_event event)
82{
83 switch (event) {
84 case SCNSM_EVENT_PORT_ONLINE:
85 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_sending_scr);
86 bfa_fcs_port_scn_send_scr(scn, NULL);
87 break;
88
89 case SCNSM_EVENT_PORT_OFFLINE:
90 break;
91
92 default:
93 bfa_assert(0);
94 }
95}
96
97static void
98bfa_fcs_port_scn_sm_sending_scr(struct bfa_fcs_port_scn_s *scn,
99 enum port_scn_event event)
100{
101 switch (event) {
102 case SCNSM_EVENT_SCR_SENT:
103 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_scr);
104 break;
105
106 case SCNSM_EVENT_PORT_OFFLINE:
107 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline);
108 bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe);
109 break;
110
111 default:
112 bfa_assert(0);
113 }
114}
115
116static void
117bfa_fcs_port_scn_sm_scr(struct bfa_fcs_port_scn_s *scn,
118 enum port_scn_event event)
119{
120 struct bfa_fcs_port_s *port = scn->port;
121
122 switch (event) {
123 case SCNSM_EVENT_RSP_OK:
124 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_online);
125 break;
126
127 case SCNSM_EVENT_RSP_ERROR:
128 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_scr_retry);
129 bfa_timer_start(port->fcs->bfa, &scn->timer,
130 bfa_fcs_port_scn_timeout, scn,
131 BFA_FCS_RETRY_TIMEOUT);
132 break;
133
134 case SCNSM_EVENT_PORT_OFFLINE:
135 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline);
136 bfa_fcxp_discard(scn->fcxp);
137 break;
138
139 default:
140 bfa_assert(0);
141 }
142}
143
144static void
145bfa_fcs_port_scn_sm_scr_retry(struct bfa_fcs_port_scn_s *scn,
146 enum port_scn_event event)
147{
148 switch (event) {
149 case SCNSM_EVENT_TIMEOUT:
150 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_sending_scr);
151 bfa_fcs_port_scn_send_scr(scn, NULL);
152 break;
153
154 case SCNSM_EVENT_PORT_OFFLINE:
155 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline);
156 bfa_timer_stop(&scn->timer);
157 break;
158
159 default:
160 bfa_assert(0);
161 }
162}
163
164static void
165bfa_fcs_port_scn_sm_online(struct bfa_fcs_port_scn_s *scn,
166 enum port_scn_event event)
167{
168 switch (event) {
169 case SCNSM_EVENT_PORT_OFFLINE:
170 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline);
171 break;
172
173 default:
174 bfa_assert(0);
175 }
176}
177
178
179
180/**
181 * fcs_scn_private FCS SCN private functions
182 */
183
184/**
185 * This routine will be called to send a SCR command.
186 */
187static void
188bfa_fcs_port_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
189{
190 struct bfa_fcs_port_scn_s *scn = scn_cbarg;
191 struct bfa_fcs_port_s *port = scn->port;
192 struct fchs_s fchs;
193 int len;
194 struct bfa_fcxp_s *fcxp;
195
196 bfa_trc(port->fcs, port->pid);
197 bfa_trc(port->fcs, port->port_cfg.pwwn);
198
199 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
200 if (!fcxp) {
201 bfa_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe,
202 bfa_fcs_port_scn_send_scr, scn);
203 return;
204 }
205 scn->fcxp = fcxp;
206
207 /*
208 * Handle VU registrations for Base port only
209 */
210 if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) {
211 len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
212 bfa_lps_is_brcd_fabric(port->fabric->lps),
213 port->pid, 0);
214 } else {
215 len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), BFA_FALSE,
216 port->pid, 0);
217 }
218
219 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
220 FC_CLASS_3, len, &fchs, bfa_fcs_port_scn_scr_response,
221 (void *)scn, FC_MAX_PDUSZ, FC_RA_TOV);
222
223 bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT);
224}
225
226static void
227bfa_fcs_port_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
228 void *cbarg, bfa_status_t req_status,
229 u32 rsp_len, u32 resid_len,
230 struct fchs_s *rsp_fchs)
231{
232 struct bfa_fcs_port_scn_s *scn = (struct bfa_fcs_port_scn_s *)cbarg;
233 struct bfa_fcs_port_s *port = scn->port;
234 struct fc_els_cmd_s *els_cmd;
235 struct fc_ls_rjt_s *ls_rjt;
236
237 bfa_trc(port->fcs, port->port_cfg.pwwn);
238
239 /*
240 * Sanity Checks
241 */
242 if (req_status != BFA_STATUS_OK) {
243 bfa_trc(port->fcs, req_status);
244 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
245 return;
246 }
247
248 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
249
250 switch (els_cmd->els_code) {
251
252 case FC_ELS_ACC:
253 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK);
254 break;
255
256 case FC_ELS_LS_RJT:
257
258 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
259
260 bfa_trc(port->fcs, ls_rjt->reason_code);
261 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
262
263 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
264 break;
265
266 default:
267 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
268 }
269}
270
271/*
272 * Send a LS Accept
273 */
274static void
275bfa_fcs_port_scn_send_ls_acc(struct bfa_fcs_port_s *port,
276 struct fchs_s *rx_fchs)
277{
278 struct fchs_s fchs;
279 struct bfa_fcxp_s *fcxp;
280 struct bfa_rport_s *bfa_rport = NULL;
281 int len;
282
283 bfa_trc(port->fcs, rx_fchs->s_id);
284
285 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
286 if (!fcxp)
287 return;
288
289 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
290 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id);
291
292 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
293 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
294 FC_MAX_PDUSZ, 0);
295}
296
297/**
298 * This routine will be called by bfa_timer on timer timeouts.
299 *
300 * param[in] vport - pointer to bfa_fcs_port_t.
301 * param[out] vport_status - pointer to return vport status in
302 *
303 * return
304 * void
305 *
306* Special Considerations:
307 *
308 * note
309 */
310static void
311bfa_fcs_port_scn_timeout(void *arg)
312{
313 struct bfa_fcs_port_scn_s *scn = (struct bfa_fcs_port_scn_s *)arg;
314
315 bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT);
316}
317
318
319
320/**
321 * fcs_scn_public FCS state change notification public interfaces
322 */
323
324/*
325 * Functions called by port/fab
326 */
327void
328bfa_fcs_port_scn_init(struct bfa_fcs_port_s *port)
329{
330 struct bfa_fcs_port_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
331
332 scn->port = port;
333 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline);
334}
335
336void
337bfa_fcs_port_scn_offline(struct bfa_fcs_port_s *port)
338{
339 struct bfa_fcs_port_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
340
341 scn->port = port;
342 bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE);
343}
344
345void
346bfa_fcs_port_scn_online(struct bfa_fcs_port_s *port)
347{
348 struct bfa_fcs_port_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
349
350 scn->port = port;
351 bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE);
352}
353
354static void
355bfa_fcs_port_scn_portid_rscn(struct bfa_fcs_port_s *port, u32 rpid)
356{
357 struct bfa_fcs_rport_s *rport;
358
359 bfa_trc(port->fcs, rpid);
360
361 /**
362 * If this is an unknown device, then it just came online.
363 * Otherwise let rport handle the RSCN event.
364 */
365 rport = bfa_fcs_port_get_rport_by_pid(port, rpid);
366 if (rport == NULL) {
367 /*
368 * If min cfg mode is enabled, we donot need to
369 * discover any new rports.
370 */
371 if (!__fcs_min_cfg(port->fcs))
372 rport = bfa_fcs_rport_create(port, rpid);
373 } else {
374 bfa_fcs_rport_scn(rport);
375 }
376}
377
378/**
379 * rscn format based PID comparison
380 */
381#define __fc_pid_match(__c0, __c1, __fmt) \
382 (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \
383 (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \
384 ((__c0)[0] == (__c1)[0])) || \
385 (((__fmt) == FC_RSCN_FORMAT_AREA) && \
386 ((__c0)[0] == (__c1)[0]) && \
387 ((__c0)[1] == (__c1)[1])))
388
389static void
390bfa_fcs_port_scn_multiport_rscn(struct bfa_fcs_port_s *port,
391 enum fc_rscn_format format, u32 rscn_pid)
392{
393 struct bfa_fcs_rport_s *rport;
394 struct list_head *qe, *qe_next;
395 u8 *c0, *c1;
396
397 bfa_trc(port->fcs, format);
398 bfa_trc(port->fcs, rscn_pid);
399
400 c0 = (u8 *) &rscn_pid;
401
402 list_for_each_safe(qe, qe_next, &port->rport_q) {
403 rport = (struct bfa_fcs_rport_s *)qe;
404 c1 = (u8 *) &rport->pid;
405 if (__fc_pid_match(c0, c1, format))
406 bfa_fcs_rport_scn(rport);
407 }
408}
409
410void
411bfa_fcs_port_scn_process_rscn(struct bfa_fcs_port_s *port, struct fchs_s *fchs,
412 u32 len)
413{
414 struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1);
415 int num_entries;
416 u32 rscn_pid;
417 bfa_boolean_t nsquery = BFA_FALSE;
418 int i = 0;
419
420 num_entries =
421 (bfa_os_ntohs(rscn->payldlen) -
422 sizeof(u32)) / sizeof(rscn->event[0]);
423
424 bfa_trc(port->fcs, num_entries);
425
426 port->stats.num_rscn++;
427
428 bfa_fcs_port_scn_send_ls_acc(port, fchs);
429
430 for (i = 0; i < num_entries; i++) {
431 rscn_pid = rscn->event[i].portid;
432
433 bfa_trc(port->fcs, rscn->event[i].format);
434 bfa_trc(port->fcs, rscn_pid);
435
436 switch (rscn->event[i].format) {
437 case FC_RSCN_FORMAT_PORTID:
438 if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) {
439 /*
440 * Ignore this event. f/w would have processed
441 * it
442 */
443 bfa_trc(port->fcs, rscn_pid);
444 } else {
445 port->stats.num_portid_rscn++;
446 bfa_fcs_port_scn_portid_rscn(port, rscn_pid);
447 }
448 break;
449
450 case FC_RSCN_FORMAT_FABRIC:
451 if (rscn->event[i].qualifier ==
452 FC_FABRIC_NAME_RSCN_EVENT) {
453 bfa_fcs_port_ms_fabric_rscn(port);
454 break;
455 }
456 /*
457 * !!!!!!!!! Fall Through !!!!!!!!!!!!!
458 */
459
460 case FC_RSCN_FORMAT_AREA:
461 case FC_RSCN_FORMAT_DOMAIN:
462 nsquery = BFA_TRUE;
463 bfa_fcs_port_scn_multiport_rscn(port,
464 rscn->event[i].format,
465 rscn_pid);
466 break;
467
468 default:
469 bfa_assert(0);
470 nsquery = BFA_TRUE;
471 }
472 }
473
474 /**
475 * If any of area, domain or fabric RSCN is received, do a fresh discovery
476 * to find new devices.
477 */
478 if (nsquery)
479 bfa_fcs_port_ns_query(port);
480}
481
482
diff --git a/drivers/scsi/bfa/vfapi.c b/drivers/scsi/bfa/vfapi.c
new file mode 100644
index 000000000000..31d81fe2fc48
--- /dev/null
+++ b/drivers/scsi/bfa/vfapi.c
@@ -0,0 +1,292 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * vfapi.c Fabric module implementation.
20 */
21
22#include "fcs_fabric.h"
23#include "fcs_trcmod.h"
24
25BFA_TRC_FILE(FCS, VFAPI);
26
27/**
28 * fcs_vf_api virtual fabrics API
29 */
30
31/**
32 * Enable VF mode.
33 *
34 * @param[in] fcs fcs module instance
35 * @param[in] vf_id default vf_id of port, FC_VF_ID_NULL
36 * to use standard default vf_id of 1.
37 *
38 * @retval BFA_STATUS_OK vf mode is enabled
39 * @retval BFA_STATUS_BUSY Port is active. Port must be disabled
40 * before VF mode can be enabled.
41 */
42bfa_status_t
43bfa_fcs_vf_mode_enable(struct bfa_fcs_s *fcs, u16 vf_id)
44{
45 return BFA_STATUS_OK;
46}
47
48/**
49 * Disable VF mode.
50 *
51 * @param[in] fcs fcs module instance
52 *
53 * @retval BFA_STATUS_OK vf mode is disabled
54 * @retval BFA_STATUS_BUSY VFs are present and being used. All
55 * VFs must be deleted before disabling
56 * VF mode.
57 */
58bfa_status_t
59bfa_fcs_vf_mode_disable(struct bfa_fcs_s *fcs)
60{
61 return BFA_STATUS_OK;
62}
63
64/**
65 * Create a new VF instance.
66 *
67 * A new VF is created using the given VF configuration. A VF is identified
68 * by VF id. No duplicate VF creation is allowed with the same VF id. Once
69 * a VF is created, VF is automatically started after link initialization
70 * and EVFP exchange is completed.
71 *
72 * param[in] vf - FCS vf data structure. Memory is
73 * allocated by caller (driver)
74 * param[in] fcs - FCS module
75 * param[in] vf_cfg - VF configuration
76 * param[in] vf_drv - Opaque handle back to the driver's
77 * virtual vf structure
78 *
79 * retval BFA_STATUS_OK VF creation is successful
80 * retval BFA_STATUS_FAILED VF creation failed
81 * retval BFA_STATUS_EEXIST A VF exists with the given vf_id
82 */
83bfa_status_t
84bfa_fcs_vf_create(bfa_fcs_vf_t *vf, struct bfa_fcs_s *fcs, u16 vf_id,
85 struct bfa_port_cfg_s *port_cfg, struct bfad_vf_s *vf_drv)
86{
87 bfa_trc(fcs, vf_id);
88 return BFA_STATUS_OK;
89}
90
91/**
92 * Use this function to delete a BFA VF object. VF object should
93 * be stopped before this function call.
94 *
95 * param[in] vf - pointer to bfa_vf_t.
96 *
97 * retval BFA_STATUS_OK On vf deletion success
98 * retval BFA_STATUS_BUSY VF is not in a stopped state
99 * retval BFA_STATUS_INPROGRESS VF deletion in in progress
100 */
101bfa_status_t
102bfa_fcs_vf_delete(bfa_fcs_vf_t *vf)
103{
104 bfa_trc(vf->fcs, vf->vf_id);
105 return BFA_STATUS_OK;
106}
107
108/**
109 * Start participation in VF. This triggers login to the virtual fabric.
110 *
111 * param[in] vf - pointer to bfa_vf_t.
112 *
113 * return None
114 */
115void
116bfa_fcs_vf_start(bfa_fcs_vf_t *vf)
117{
118 bfa_trc(vf->fcs, vf->vf_id);
119}
120
121/**
122 * Logout with the virtual fabric.
123 *
124 * param[in] vf - pointer to bfa_vf_t.
125 *
126 * retval BFA_STATUS_OK On success.
127 * retval BFA_STATUS_INPROGRESS VF is being stopped.
128 */
129bfa_status_t
130bfa_fcs_vf_stop(bfa_fcs_vf_t *vf)
131{
132 bfa_trc(vf->fcs, vf->vf_id);
133 return BFA_STATUS_OK;
134}
135
136/**
137 * Returns attributes of the given VF.
138 *
139 * param[in] vf pointer to bfa_vf_t.
140 * param[out] vf_attr vf attributes returned
141 *
142 * return None
143 */
144void
145bfa_fcs_vf_get_attr(bfa_fcs_vf_t *vf, struct bfa_vf_attr_s *vf_attr)
146{
147 bfa_trc(vf->fcs, vf->vf_id);
148}
149
150/**
151 * Return statistics associated with the given vf.
152 *
153 * param[in] vf pointer to bfa_vf_t.
154 * param[out] vf_stats vf statistics returned
155 *
156 * @return None
157 */
158void
159bfa_fcs_vf_get_stats(bfa_fcs_vf_t *vf, struct bfa_vf_stats_s *vf_stats)
160{
161 bfa_os_memcpy(vf_stats, &vf->stats, sizeof(struct bfa_vf_stats_s));
162 return;
163}
164
165void
166/**
167 * clear statistics associated with the given vf.
168 *
169 * param[in] vf pointer to bfa_vf_t.
170 *
171 * @return None
172 */
173bfa_fcs_vf_clear_stats(bfa_fcs_vf_t *vf)
174{
175 bfa_os_memset(&vf->stats, 0, sizeof(struct bfa_vf_stats_s));
176 return;
177}
178
179/**
180 * Returns FCS vf structure for a given vf_id.
181 *
182 * param[in] vf_id - VF_ID
183 *
184 * return
185 * If lookup succeeds, retuns fcs vf object, otherwise returns NULL
186 */
187bfa_fcs_vf_t *
188bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id)
189{
190 bfa_trc(fcs, vf_id);
191 if (vf_id == FC_VF_ID_NULL)
192 return (&fcs->fabric);
193
194 /**
195 * @todo vf support
196 */
197
198 return NULL;
199}
200
201/**
202 * Returns driver VF structure for a given FCS vf.
203 *
204 * param[in] vf - pointer to bfa_vf_t
205 *
206 * return Driver VF structure
207 */
208struct bfad_vf_s *
209bfa_fcs_vf_get_drv_vf(bfa_fcs_vf_t *vf)
210{
211 bfa_assert(vf);
212 bfa_trc(vf->fcs, vf->vf_id);
213 return vf->vf_drv;
214}
215
216/**
217 * Return the list of VFs configured.
218 *
219 * param[in] fcs fcs module instance
220 * param[out] vf_ids returned list of vf_ids
221 * param[in,out] nvfs in:size of vf_ids array,
222 * out:total elements present,
223 * actual elements returned is limited by the size
224 *
225 * return Driver VF structure
226 */
227void
228bfa_fcs_vf_list(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs)
229{
230 bfa_trc(fcs, *nvfs);
231}
232
233/**
234 * Return the list of all VFs visible from fabric.
235 *
236 * param[in] fcs fcs module instance
237 * param[out] vf_ids returned list of vf_ids
238 * param[in,out] nvfs in:size of vf_ids array,
239 * out:total elements present,
240 * actual elements returned is limited by the size
241 *
242 * return Driver VF structure
243 */
244void
245bfa_fcs_vf_list_all(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs)
246{
247 bfa_trc(fcs, *nvfs);
248}
249
250/**
251 * Return the list of local logical ports present in the given VF.
252 *
253 * param[in] vf vf for which logical ports are returned
254 * param[out] lpwwn returned logical port wwn list
255 * param[in,out] nlports in:size of lpwwn list;
256 * out:total elements present,
257 * actual elements returned is limited by the size
258 *
259 */
260void
261bfa_fcs_vf_get_ports(bfa_fcs_vf_t *vf, wwn_t lpwwn[], int *nlports)
262{
263 struct list_head *qe;
264 struct bfa_fcs_vport_s *vport;
265 int i;
266 struct bfa_fcs_s *fcs;
267
268 if (vf == NULL || lpwwn == NULL || *nlports == 0)
269 return;
270
271 fcs = vf->fcs;
272
273 bfa_trc(fcs, vf->vf_id);
274 bfa_trc(fcs, (u32) *nlports);
275
276 i = 0;
277 lpwwn[i++] = vf->bport.port_cfg.pwwn;
278
279 list_for_each(qe, &vf->vport_q) {
280 if (i >= *nlports)
281 break;
282
283 vport = (struct bfa_fcs_vport_s *) qe;
284 lpwwn[i++] = vport->lport.port_cfg.pwwn;
285 }
286
287 bfa_trc(fcs, i);
288 *nlports = i;
289 return;
290}
291
292
diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c
new file mode 100644
index 000000000000..c10af06c5714
--- /dev/null
+++ b/drivers/scsi/bfa/vport.c
@@ -0,0 +1,891 @@
1/*
2 * Copyright (c) 2005-2009 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/**
19 * bfa_fcs_vport.c FCS virtual port state machine
20 */
21
22#include <bfa.h>
23#include <bfa_svc.h>
24#include <fcbuild.h>
25#include "fcs_fabric.h"
26#include "fcs_lport.h"
27#include "fcs_vport.h"
28#include "fcs_trcmod.h"
29#include "fcs.h"
30#include <aen/bfa_aen_lport.h>
31
32BFA_TRC_FILE(FCS, VPORT);
33
34#define __vport_fcs(__vp) (__vp)->lport.fcs
35#define __vport_pwwn(__vp) (__vp)->lport.port_cfg.pwwn
36#define __vport_nwwn(__vp) (__vp)->lport.port_cfg.nwwn
37#define __vport_bfa(__vp) (__vp)->lport.fcs->bfa
38#define __vport_fcid(__vp) (__vp)->lport.pid
39#define __vport_fabric(__vp) (__vp)->lport.fabric
40#define __vport_vfid(__vp) (__vp)->lport.fabric->vf_id
41
42#define BFA_FCS_VPORT_MAX_RETRIES 5
43/*
44 * Forward declarations
45 */
46static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport);
47static void bfa_fcs_vport_timeout(void *vport_arg);
48static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport);
49static void bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport);
50
51/**
52 * fcs_vport_sm FCS virtual port state machine
53 */
54
55/**
56 * VPort State Machine events
57 */
58enum bfa_fcs_vport_event {
59 BFA_FCS_VPORT_SM_CREATE = 1, /* vport create event */
60 BFA_FCS_VPORT_SM_DELETE = 2, /* vport delete event */
61 BFA_FCS_VPORT_SM_START = 3, /* vport start request */
62 BFA_FCS_VPORT_SM_STOP = 4, /* stop: unsupported */
63 BFA_FCS_VPORT_SM_ONLINE = 5, /* fabric online */
64 BFA_FCS_VPORT_SM_OFFLINE = 6, /* fabric offline event */
65 BFA_FCS_VPORT_SM_FRMSENT = 7, /* fdisc/logo sent events */
66 BFA_FCS_VPORT_SM_RSP_OK = 8, /* good response */
67 BFA_FCS_VPORT_SM_RSP_ERROR = 9, /* error/bad response */
68 BFA_FCS_VPORT_SM_TIMEOUT = 10, /* delay timer event */
69 BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */
70 BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error */
71 BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */
72};
73
74static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
75 enum bfa_fcs_vport_event event);
76static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
77 enum bfa_fcs_vport_event event);
78static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
79 enum bfa_fcs_vport_event event);
80static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
81 enum bfa_fcs_vport_event event);
82static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
83 enum bfa_fcs_vport_event event);
84static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
85 enum bfa_fcs_vport_event event);
86static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
87 enum bfa_fcs_vport_event event);
88static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
89 enum bfa_fcs_vport_event event);
90static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
91 enum bfa_fcs_vport_event event);
92static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
93 enum bfa_fcs_vport_event event);
94
95static struct bfa_sm_table_s vport_sm_table[] = {
96 {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT},
97 {BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED},
98 {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE},
99 {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC},
100 {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY},
101 {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE},
102 {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING},
103 {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP},
104 {BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO},
105 {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR}
106};
107
108/**
109 * Beginning state.
110 */
111static void
112bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
113 enum bfa_fcs_vport_event event)
114{
115 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
116 bfa_trc(__vport_fcs(vport), event);
117
118 switch (event) {
119 case BFA_FCS_VPORT_SM_CREATE:
120 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
121 bfa_fcs_fabric_addvport(__vport_fabric(vport), vport);
122 break;
123
124 default:
125 bfa_assert(0);
126 }
127}
128
129/**
130 * Created state - a start event is required to start up the state machine.
131 */
132static void
133bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
134 enum bfa_fcs_vport_event event)
135{
136 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
137 bfa_trc(__vport_fcs(vport), event);
138
139 switch (event) {
140 case BFA_FCS_VPORT_SM_START:
141 if (bfa_fcs_fabric_is_online(__vport_fabric(vport))
142 && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) {
143 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
144 bfa_fcs_vport_do_fdisc(vport);
145 } else {
146 /**
147 * Fabric is offline or not NPIV capable, stay in
148 * offline state.
149 */
150 vport->vport_stats.fab_no_npiv++;
151 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
152 }
153 break;
154
155 case BFA_FCS_VPORT_SM_DELETE:
156 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
157 bfa_fcs_port_delete(&vport->lport);
158 break;
159
160 case BFA_FCS_VPORT_SM_ONLINE:
161 case BFA_FCS_VPORT_SM_OFFLINE:
162 /**
163 * Ignore ONLINE/OFFLINE events from fabric till vport is started.
164 */
165 break;
166
167 default:
168 bfa_assert(0);
169 }
170}
171
172/**
173 * Offline state - awaiting ONLINE event from fabric SM.
174 */
175static void
176bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
177 enum bfa_fcs_vport_event event)
178{
179 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
180 bfa_trc(__vport_fcs(vport), event);
181
182 switch (event) {
183 case BFA_FCS_VPORT_SM_DELETE:
184 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
185 bfa_fcs_port_delete(&vport->lport);
186 break;
187
188 case BFA_FCS_VPORT_SM_ONLINE:
189 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
190 vport->fdisc_retries = 0;
191 bfa_fcs_vport_do_fdisc(vport);
192 break;
193
194 case BFA_FCS_VPORT_SM_OFFLINE:
195 /*
196 * This can happen if the vport couldn't be initialzied due
197 * the fact that the npiv was not enabled on the switch. In
198 * that case we will put the vport in offline state. However,
199 * the link can go down and cause the this event to be sent when
200 * we are already offline. Ignore it.
201 */
202 break;
203
204 default:
205 bfa_assert(0);
206 }
207}
208
209/**
210 * FDISC is sent and awaiting reply from fabric.
211 */
212static void
213bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
214 enum bfa_fcs_vport_event event)
215{
216 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
217 bfa_trc(__vport_fcs(vport), event);
218
219 switch (event) {
220 case BFA_FCS_VPORT_SM_DELETE:
221 bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo);
222 bfa_lps_discard(vport->lps);
223 bfa_fcs_vport_do_logo(vport);
224 break;
225
226 case BFA_FCS_VPORT_SM_OFFLINE:
227 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
228 bfa_lps_discard(vport->lps);
229 break;
230
231 case BFA_FCS_VPORT_SM_RSP_OK:
232 bfa_sm_set_state(vport, bfa_fcs_vport_sm_online);
233 bfa_fcs_port_online(&vport->lport);
234 break;
235
236 case BFA_FCS_VPORT_SM_RSP_ERROR:
237 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry);
238 bfa_timer_start(__vport_bfa(vport), &vport->timer,
239 bfa_fcs_vport_timeout, vport,
240 BFA_FCS_RETRY_TIMEOUT);
241 break;
242
243 case BFA_FCS_VPORT_SM_RSP_FAILED:
244 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
245 break;
246
247 case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
248 bfa_sm_set_state(vport, bfa_fcs_vport_sm_error);
249 break;
250
251 default:
252 bfa_assert(0);
253 }
254}
255
256/**
257 * FDISC attempt failed - a timer is active to retry FDISC.
258 */
259static void
260bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
261 enum bfa_fcs_vport_event event)
262{
263 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
264 bfa_trc(__vport_fcs(vport), event);
265
266 switch (event) {
267 case BFA_FCS_VPORT_SM_DELETE:
268 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
269 bfa_timer_stop(&vport->timer);
270 bfa_fcs_port_delete(&vport->lport);
271 break;
272
273 case BFA_FCS_VPORT_SM_OFFLINE:
274 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
275 bfa_timer_stop(&vport->timer);
276 break;
277
278 case BFA_FCS_VPORT_SM_TIMEOUT:
279 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
280 vport->vport_stats.fdisc_retries++;
281 vport->fdisc_retries++;
282 bfa_fcs_vport_do_fdisc(vport);
283 break;
284
285 default:
286 bfa_assert(0);
287 }
288}
289
290/**
291 * Vport is online (FDISC is complete).
292 */
293static void
294bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
295 enum bfa_fcs_vport_event event)
296{
297 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
298 bfa_trc(__vport_fcs(vport), event);
299
300 switch (event) {
301 case BFA_FCS_VPORT_SM_DELETE:
302 bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
303 bfa_fcs_port_delete(&vport->lport);
304 break;
305
306 case BFA_FCS_VPORT_SM_OFFLINE:
307 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
308 bfa_lps_discard(vport->lps);
309 bfa_fcs_port_offline(&vport->lport);
310 break;
311
312 default:
313 bfa_assert(0);
314 }
315}
316
317/**
318 * Vport is being deleted - awaiting lport delete completion to send
319 * LOGO to fabric.
320 */
321static void
322bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
323 enum bfa_fcs_vport_event event)
324{
325 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
326 bfa_trc(__vport_fcs(vport), event);
327
328 switch (event) {
329 case BFA_FCS_VPORT_SM_DELETE:
330 break;
331
332 case BFA_FCS_VPORT_SM_DELCOMP:
333 bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo);
334 bfa_fcs_vport_do_logo(vport);
335 break;
336
337 case BFA_FCS_VPORT_SM_OFFLINE:
338 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
339 break;
340
341 default:
342 bfa_assert(0);
343 }
344}
345
346/**
347 * Error State.
348 * This state will be set when the Vport Creation fails due to errors like
349 * Dup WWN. In this state only operation allowed is a Vport Delete.
350 */
351static void
352bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
353 enum bfa_fcs_vport_event event)
354{
355 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
356 bfa_trc(__vport_fcs(vport), event);
357
358 switch (event) {
359 case BFA_FCS_VPORT_SM_DELETE:
360 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
361 bfa_fcs_vport_free(vport);
362 break;
363
364 default:
365 bfa_trc(__vport_fcs(vport), event);
366 }
367}
368
369/**
370 * Lport cleanup is in progress since vport is being deleted. Fabric is
371 * offline, so no LOGO is needed to complete vport deletion.
372 */
373static void
374bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
375 enum bfa_fcs_vport_event event)
376{
377 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
378 bfa_trc(__vport_fcs(vport), event);
379
380 switch (event) {
381 case BFA_FCS_VPORT_SM_DELCOMP:
382 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
383 bfa_fcs_vport_free(vport);
384 break;
385
386 case BFA_FCS_VPORT_SM_DELETE:
387 break;
388
389 default:
390 bfa_assert(0);
391 }
392}
393
394/**
395 * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup
396 * is done.
397 */
398static void
399bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
400 enum bfa_fcs_vport_event event)
401{
402 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
403 bfa_trc(__vport_fcs(vport), event);
404
405 switch (event) {
406 case BFA_FCS_VPORT_SM_OFFLINE:
407 bfa_lps_discard(vport->lps);
408 /*
409 * !!! fall through !!!
410 */
411
412 case BFA_FCS_VPORT_SM_RSP_OK:
413 case BFA_FCS_VPORT_SM_RSP_ERROR:
414 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
415 bfa_fcs_vport_free(vport);
416 break;
417
418 case BFA_FCS_VPORT_SM_DELETE:
419 break;
420
421 default:
422 bfa_assert(0);
423 }
424}
425
426
427
428/**
429 * fcs_vport_private FCS virtual port private functions
430 */
431
432/**
433 * Send AEN notification
434 */
435static void
436bfa_fcs_vport_aen_post(bfa_fcs_lport_t *port, enum bfa_lport_aen_event event)
437{
438 union bfa_aen_data_u aen_data;
439 struct bfa_log_mod_s *logmod = port->fcs->logm;
440 enum bfa_port_role role = port->port_cfg.roles;
441 wwn_t lpwwn = bfa_fcs_port_get_pwwn(port);
442 char lpwwn_ptr[BFA_STRING_32];
443 char *role_str[BFA_PORT_ROLE_FCP_MAX / 2 + 1] =
444 { "Initiator", "Target", "IPFC" };
445
446 wwn2str(lpwwn_ptr, lpwwn);
447
448 bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
449
450 switch (event) {
451 case BFA_LPORT_AEN_NPIV_DUP_WWN:
452 bfa_log(logmod, BFA_AEN_LPORT_NPIV_DUP_WWN, lpwwn_ptr,
453 role_str[role / 2]);
454 break;
455 case BFA_LPORT_AEN_NPIV_FABRIC_MAX:
456 bfa_log(logmod, BFA_AEN_LPORT_NPIV_FABRIC_MAX, lpwwn_ptr,
457 role_str[role / 2]);
458 break;
459 case BFA_LPORT_AEN_NPIV_UNKNOWN:
460 bfa_log(logmod, BFA_AEN_LPORT_NPIV_UNKNOWN, lpwwn_ptr,
461 role_str[role / 2]);
462 break;
463 default:
464 break;
465 }
466
467 aen_data.lport.vf_id = port->fabric->vf_id;
468 aen_data.lport.roles = role;
469 aen_data.lport.ppwwn =
470 bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port->fcs));
471 aen_data.lport.lpwwn = lpwwn;
472}
473
474/**
475 * This routine will be called to send a FDISC command.
476 */
477static void
478bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
479{
480 bfa_lps_fdisc(vport->lps, vport,
481 bfa_pport_get_maxfrsize(__vport_bfa(vport)),
482 __vport_pwwn(vport), __vport_nwwn(vport));
483 vport->vport_stats.fdisc_sent++;
484}
485
486static void
487bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
488{
489 u8 lsrjt_rsn = bfa_lps_get_lsrjt_rsn(vport->lps);
490 u8 lsrjt_expl = bfa_lps_get_lsrjt_expl(vport->lps);
491
492 bfa_trc(__vport_fcs(vport), lsrjt_rsn);
493 bfa_trc(__vport_fcs(vport), lsrjt_expl);
494
495 /*
496 * For certain reason codes, we don't want to retry.
497 */
498 switch (bfa_lps_get_lsrjt_expl(vport->lps)) {
499 case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */
500 case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */
501 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
502 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
503 else {
504 bfa_fcs_vport_aen_post(&vport->lport,
505 BFA_LPORT_AEN_NPIV_DUP_WWN);
506 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN);
507 }
508 break;
509
510 case FC_LS_RJT_EXP_INSUFF_RES:
511 /*
512 * This means max logins per port/switch setting on the
513 * switch was exceeded.
514 */
515 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
516 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
517 else {
518 bfa_fcs_vport_aen_post(&vport->lport,
519 BFA_LPORT_AEN_NPIV_FABRIC_MAX);
520 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
521 }
522 break;
523
524 default:
525 if (vport->fdisc_retries == 0) /* Print only once */
526 bfa_fcs_vport_aen_post(&vport->lport,
527 BFA_LPORT_AEN_NPIV_UNKNOWN);
528 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
529 }
530}
531
532/**
533 * Called to send a logout to the fabric. Used when a V-Port is
534 * deleted/stopped.
535 */
536static void
537bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport)
538{
539 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
540
541 vport->vport_stats.logo_sent++;
542 bfa_lps_fdisclogo(vport->lps);
543}
544
545/**
546 * This routine will be called by bfa_timer on timer timeouts.
547 *
548 * param[in] vport - pointer to bfa_fcs_vport_t.
549 * param[out] vport_status - pointer to return vport status in
550 *
551 * return
552 * void
553 *
554* Special Considerations:
555 *
556 * note
557 */
558static void
559bfa_fcs_vport_timeout(void *vport_arg)
560{
561 struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *)vport_arg;
562
563 vport->vport_stats.fdisc_timeouts++;
564 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT);
565}
566
567static void
568bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport)
569{
570 bfa_fcs_fabric_delvport(__vport_fabric(vport), vport);
571 bfa_fcb_vport_delete(vport->vport_drv);
572 bfa_lps_delete(vport->lps);
573}
574
575
576
577/**
578 * fcs_vport_public FCS virtual port public interfaces
579 */
580
581/**
582 * Online notification from fabric SM.
583 */
584void
585bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport)
586{
587 vport->vport_stats.fab_online++;
588 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
589}
590
591/**
592 * Offline notification from fabric SM.
593 */
594void
595bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport)
596{
597 vport->vport_stats.fab_offline++;
598 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
599}
600
601/**
602 * Cleanup notification from fabric SM on link timer expiry.
603 */
604void
605bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport)
606{
607 vport->vport_stats.fab_cleanup++;
608}
609
610/**
611 * Delete completion callback from associated lport
612 */
613void
614bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport)
615{
616 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP);
617}
618
619/**
620 * Module initialization
621 */
622void
623bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs)
624{
625}
626
627/**
628 * Module cleanup
629 */
630void
631bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs)
632{
633 bfa_fcs_modexit_comp(fcs);
634}
635
636u32
637bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs)
638{
639 struct bfa_ioc_attr_s ioc_attr;
640
641 bfa_get_attr(fcs->bfa, &ioc_attr);
642
643 if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT)
644 return (BFA_FCS_MAX_VPORTS_SUPP_CT);
645 else
646 return (BFA_FCS_MAX_VPORTS_SUPP_CB);
647}
648
649
650
651/**
652 * fcs_vport_api Virtual port API
653 */
654
655/**
656 * Use this function to instantiate a new FCS vport object. This
657 * function will not trigger any HW initialization process (which will be
658 * done in vport_start() call)
659 *
660 * param[in] vport - pointer to bfa_fcs_vport_t. This space
661 * needs to be allocated by the driver.
662 * param[in] fcs - FCS instance
663 * param[in] vport_cfg - vport configuration
664 * param[in] vf_id - VF_ID if vport is created within a VF.
665 * FC_VF_ID_NULL to specify base fabric.
666 * param[in] vport_drv - Opaque handle back to the driver's vport
667 * structure
668 *
669 * retval BFA_STATUS_OK - on success.
670 * retval BFA_STATUS_FAILED - on failure.
671 */
672bfa_status_t
673bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
674 u16 vf_id, struct bfa_port_cfg_s *vport_cfg,
675 struct bfad_vport_s *vport_drv)
676{
677 if (vport_cfg->pwwn == 0)
678 return (BFA_STATUS_INVALID_WWN);
679
680 if (bfa_fcs_port_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn)
681 return BFA_STATUS_VPORT_WWN_BP;
682
683 if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL)
684 return BFA_STATUS_VPORT_EXISTS;
685
686 if (bfa_fcs_fabric_vport_count(&fcs->fabric) ==
687 bfa_fcs_vport_get_max(fcs))
688 return BFA_STATUS_VPORT_MAX;
689
690 vport->lps = bfa_lps_alloc(fcs->bfa);
691 if (!vport->lps)
692 return BFA_STATUS_VPORT_MAX;
693
694 vport->vport_drv = vport_drv;
695 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
696
697 bfa_fcs_lport_init(&vport->lport, fcs, vf_id, vport_cfg, vport);
698
699 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE);
700
701 return BFA_STATUS_OK;
702}
703
704/**
705 * Use this function initialize the vport.
706 *
707 * @param[in] vport - pointer to bfa_fcs_vport_t.
708 *
709 * @returns None
710 */
711bfa_status_t
712bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport)
713{
714 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START);
715
716 return BFA_STATUS_OK;
717}
718
719/**
720 * Use this function quiese the vport object. This function will return
721 * immediately, when the vport is actually stopped, the
722 * bfa_drv_vport_stop_cb() will be called.
723 *
724 * param[in] vport - pointer to bfa_fcs_vport_t.
725 *
726 * return None
727 */
728bfa_status_t
729bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport)
730{
731 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP);
732
733 return BFA_STATUS_OK;
734}
735
736/**
737 * Use this function to delete a vport object. Fabric object should
738 * be stopped before this function call.
739 *
740 * param[in] vport - pointer to bfa_fcs_vport_t.
741 *
742 * return None
743 */
744bfa_status_t
745bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport)
746{
747 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
748
749 return BFA_STATUS_OK;
750}
751
752/**
753 * Use this function to get vport's current status info.
754 *
755 * param[in] vport pointer to bfa_fcs_vport_t.
756 * param[out] attr pointer to return vport attributes
757 *
758 * return None
759 */
760void
761bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
762 struct bfa_vport_attr_s *attr)
763{
764 if (vport == NULL || attr == NULL)
765 return;
766
767 bfa_os_memset(attr, 0, sizeof(struct bfa_vport_attr_s));
768
769 bfa_fcs_port_get_attr(&vport->lport, &attr->port_attr);
770 attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm);
771}
772
773/**
774 * Use this function to get vport's statistics.
775 *
776 * param[in] vport pointer to bfa_fcs_vport_t.
777 * param[out] stats pointer to return vport statistics in
778 *
779 * return None
780 */
781void
782bfa_fcs_vport_get_stats(struct bfa_fcs_vport_s *vport,
783 struct bfa_vport_stats_s *stats)
784{
785 *stats = vport->vport_stats;
786}
787
788/**
789 * Use this function to clear vport's statistics.
790 *
791 * param[in] vport pointer to bfa_fcs_vport_t.
792 *
793 * return None
794 */
795void
796bfa_fcs_vport_clr_stats(struct bfa_fcs_vport_s *vport)
797{
798 bfa_os_memset(&vport->vport_stats, 0, sizeof(struct bfa_vport_stats_s));
799}
800
801/**
802 * Lookup a virtual port. Excludes base port from lookup.
803 */
804struct bfa_fcs_vport_s *
805bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn)
806{
807 struct bfa_fcs_vport_s *vport;
808 struct bfa_fcs_fabric_s *fabric;
809
810 bfa_trc(fcs, vf_id);
811 bfa_trc(fcs, vpwwn);
812
813 fabric = bfa_fcs_vf_lookup(fcs, vf_id);
814 if (!fabric) {
815 bfa_trc(fcs, vf_id);
816 return NULL;
817 }
818
819 vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn);
820 return vport;
821}
822
823/**
824 * FDISC Response
825 */
826void
827bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
828{
829 struct bfa_fcs_vport_s *vport = uarg;
830
831 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
832 bfa_trc(__vport_fcs(vport), status);
833
834 switch (status) {
835 case BFA_STATUS_OK:
836 /*
837 * Initialiaze the V-Port fields
838 */
839 __vport_fcid(vport) = bfa_lps_get_pid(vport->lps);
840 vport->vport_stats.fdisc_accepts++;
841 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
842 break;
843
844 case BFA_STATUS_INVALID_MAC:
845 /*
846 * Only for CNA
847 */
848 vport->vport_stats.fdisc_acc_bad++;
849 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
850
851 break;
852
853 case BFA_STATUS_EPROTOCOL:
854 switch (bfa_lps_get_extstatus(vport->lps)) {
855 case BFA_EPROTO_BAD_ACCEPT:
856 vport->vport_stats.fdisc_acc_bad++;
857 break;
858
859 case BFA_EPROTO_UNKNOWN_RSP:
860 vport->vport_stats.fdisc_unknown_rsp++;
861 break;
862
863 default:
864 break;
865 }
866
867 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
868 break;
869
870 case BFA_STATUS_FABRIC_RJT:
871 vport->vport_stats.fdisc_rejects++;
872 bfa_fcs_vport_fdisc_rejected(vport);
873 break;
874
875 default:
876 vport->vport_stats.fdisc_rsp_err++;
877 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
878 }
879}
880
881/**
882 * LOGO response
883 */
884void
885bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
886{
887 struct bfa_fcs_vport_s *vport = uarg;
888 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
889}
890
891