xref: /OK3568_Linux_fs/kernel/drivers/scsi/csiostor/csio_lnode.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * This file is part of the Chelsio FCoE driver for Linux.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (c) 2008-2012 Chelsio Communications, Inc. All rights reserved.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * This software is available to you under a choice of one of two
7*4882a593Smuzhiyun  * licenses.  You may choose to be licensed under the terms of the GNU
8*4882a593Smuzhiyun  * General Public License (GPL) Version 2, available from the file
9*4882a593Smuzhiyun  * COPYING in the main directory of this source tree, or the
10*4882a593Smuzhiyun  * OpenIB.org BSD license below:
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  *     Redistribution and use in source and binary forms, with or
13*4882a593Smuzhiyun  *     without modification, are permitted provided that the following
14*4882a593Smuzhiyun  *     conditions are met:
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  *      - Redistributions of source code must retain the above
17*4882a593Smuzhiyun  *        copyright notice, this list of conditions and the following
18*4882a593Smuzhiyun  *        disclaimer.
19*4882a593Smuzhiyun  *
20*4882a593Smuzhiyun  *      - Redistributions in binary form must reproduce the above
21*4882a593Smuzhiyun  *        copyright notice, this list of conditions and the following
22*4882a593Smuzhiyun  *        disclaimer in the documentation and/or other materials
23*4882a593Smuzhiyun  *        provided with the distribution.
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26*4882a593Smuzhiyun  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27*4882a593Smuzhiyun  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28*4882a593Smuzhiyun  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29*4882a593Smuzhiyun  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30*4882a593Smuzhiyun  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31*4882a593Smuzhiyun  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32*4882a593Smuzhiyun  * SOFTWARE.
33*4882a593Smuzhiyun  */
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #ifndef __CSIO_LNODE_H__
36*4882a593Smuzhiyun #define __CSIO_LNODE_H__
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #include <linux/kref.h>
39*4882a593Smuzhiyun #include <linux/timer.h>
40*4882a593Smuzhiyun #include <linux/workqueue.h>
41*4882a593Smuzhiyun #include <scsi/fc/fc_els.h>
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #include "csio_defs.h"
45*4882a593Smuzhiyun #include "csio_hw.h"
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun #define CSIO_FCOE_MAX_NPIV	128
48*4882a593Smuzhiyun #define CSIO_FCOE_MAX_RNODES	2048
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun /* FDMI port attribute unknown speed */
51*4882a593Smuzhiyun #define CSIO_HBA_PORTSPEED_UNKNOWN	0x8000
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun extern int csio_fcoe_rnodes;
54*4882a593Smuzhiyun extern int csio_fdmi_enable;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun /* State machine evets */
57*4882a593Smuzhiyun enum csio_ln_ev {
58*4882a593Smuzhiyun 	CSIO_LNE_NONE = (uint32_t)0,
59*4882a593Smuzhiyun 	CSIO_LNE_LINKUP,
60*4882a593Smuzhiyun 	CSIO_LNE_FAB_INIT_DONE,
61*4882a593Smuzhiyun 	CSIO_LNE_LINK_DOWN,
62*4882a593Smuzhiyun 	CSIO_LNE_DOWN_LINK,
63*4882a593Smuzhiyun 	CSIO_LNE_LOGO,
64*4882a593Smuzhiyun 	CSIO_LNE_CLOSE,
65*4882a593Smuzhiyun 	CSIO_LNE_MAX_EVENT,
66*4882a593Smuzhiyun };
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun struct csio_fcf_info {
70*4882a593Smuzhiyun 	struct list_head	list;
71*4882a593Smuzhiyun 	uint8_t			priority;
72*4882a593Smuzhiyun 	uint8_t			mac[6];
73*4882a593Smuzhiyun 	uint8_t			name_id[8];
74*4882a593Smuzhiyun 	uint8_t			fabric[8];
75*4882a593Smuzhiyun 	uint16_t		vf_id;
76*4882a593Smuzhiyun 	uint8_t			vlan_id;
77*4882a593Smuzhiyun 	uint16_t		max_fcoe_size;
78*4882a593Smuzhiyun 	uint8_t			fc_map[3];
79*4882a593Smuzhiyun 	uint32_t		fka_adv;
80*4882a593Smuzhiyun 	uint32_t		fcfi;
81*4882a593Smuzhiyun 	uint8_t			get_next:1;
82*4882a593Smuzhiyun 	uint8_t			link_aff:1;
83*4882a593Smuzhiyun 	uint8_t			fpma:1;
84*4882a593Smuzhiyun 	uint8_t			spma:1;
85*4882a593Smuzhiyun 	uint8_t			login:1;
86*4882a593Smuzhiyun 	uint8_t			portid;
87*4882a593Smuzhiyun 	uint8_t			spma_mac[6];
88*4882a593Smuzhiyun 	struct kref		kref;
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun /* Defines for flags */
92*4882a593Smuzhiyun #define	CSIO_LNF_FIPSUPP		0x00000001	/* Fip Supported */
93*4882a593Smuzhiyun #define	CSIO_LNF_NPIVSUPP		0x00000002	/* NPIV supported */
94*4882a593Smuzhiyun #define CSIO_LNF_LINK_ENABLE		0x00000004	/* Link enabled */
95*4882a593Smuzhiyun #define	CSIO_LNF_FDMI_ENABLE		0x00000008	/* FDMI support */
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun /* Transport events */
98*4882a593Smuzhiyun enum csio_ln_fc_evt {
99*4882a593Smuzhiyun 	CSIO_LN_FC_LINKUP = 1,
100*4882a593Smuzhiyun 	CSIO_LN_FC_LINKDOWN,
101*4882a593Smuzhiyun 	CSIO_LN_FC_RSCN,
102*4882a593Smuzhiyun 	CSIO_LN_FC_ATTRIB_UPDATE,
103*4882a593Smuzhiyun };
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun /* Lnode stats */
106*4882a593Smuzhiyun struct csio_lnode_stats {
107*4882a593Smuzhiyun 	uint32_t	n_link_up;	/* Link down */
108*4882a593Smuzhiyun 	uint32_t	n_link_down;	/* Link up */
109*4882a593Smuzhiyun 	uint32_t	n_err;		/* error */
110*4882a593Smuzhiyun 	uint32_t	n_err_nomem;	/* memory not available */
111*4882a593Smuzhiyun 	uint32_t	n_inval_parm;   /* Invalid parameters */
112*4882a593Smuzhiyun 	uint32_t	n_evt_unexp;	/* unexpected event */
113*4882a593Smuzhiyun 	uint32_t	n_evt_drop;	/* dropped event */
114*4882a593Smuzhiyun 	uint32_t	n_rnode_match;  /* matched rnode */
115*4882a593Smuzhiyun 	uint32_t	n_dev_loss_tmo; /* Device loss timeout */
116*4882a593Smuzhiyun 	uint32_t	n_fdmi_err;	/* fdmi err */
117*4882a593Smuzhiyun 	uint32_t	n_evt_fw[PROTO_ERR_IMPL_LOGO + 1];	/* fw events */
118*4882a593Smuzhiyun 	enum csio_ln_ev	n_evt_sm[CSIO_LNE_MAX_EVENT];	/* State m/c events */
119*4882a593Smuzhiyun 	uint32_t	n_rnode_alloc;	/* rnode allocated */
120*4882a593Smuzhiyun 	uint32_t	n_rnode_free;	/* rnode freed */
121*4882a593Smuzhiyun 	uint32_t	n_rnode_nomem;	/* rnode alloc failure */
122*4882a593Smuzhiyun 	uint32_t        n_input_requests; /* Input Requests */
123*4882a593Smuzhiyun 	uint32_t        n_output_requests; /* Output Requests */
124*4882a593Smuzhiyun 	uint32_t        n_control_requests; /* Control Requests */
125*4882a593Smuzhiyun 	uint32_t        n_input_bytes; /* Input Bytes */
126*4882a593Smuzhiyun 	uint32_t        n_output_bytes; /* Output Bytes */
127*4882a593Smuzhiyun 	uint32_t	rsvd1;
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun /* Common Lnode params */
131*4882a593Smuzhiyun struct csio_lnode_params {
132*4882a593Smuzhiyun 	uint32_t	ra_tov;
133*4882a593Smuzhiyun 	uint32_t	fcfi;
134*4882a593Smuzhiyun 	uint32_t	log_level;	/* Module level for debugging */
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun struct csio_service_parms {
138*4882a593Smuzhiyun 	struct fc_els_csp	csp;		/* Common service parms */
139*4882a593Smuzhiyun 	uint8_t			wwpn[8];	/* WWPN */
140*4882a593Smuzhiyun 	uint8_t			wwnn[8];	/* WWNN */
141*4882a593Smuzhiyun 	struct fc_els_cssp	clsp[4];	/* Class service params */
142*4882a593Smuzhiyun 	uint8_t			vvl[16];	/* Vendor version level */
143*4882a593Smuzhiyun };
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun /* Lnode */
146*4882a593Smuzhiyun struct csio_lnode {
147*4882a593Smuzhiyun 	struct csio_sm		sm;		/* State machine + sibling
148*4882a593Smuzhiyun 						 * lnode list.
149*4882a593Smuzhiyun 						 */
150*4882a593Smuzhiyun 	struct csio_hw		*hwp;		/* Pointer to the HW module */
151*4882a593Smuzhiyun 	uint8_t			portid;		/* Port ID */
152*4882a593Smuzhiyun 	uint8_t			rsvd1;
153*4882a593Smuzhiyun 	uint16_t		rsvd2;
154*4882a593Smuzhiyun 	uint32_t		dev_num;	/* Device number */
155*4882a593Smuzhiyun 	uint32_t		flags;		/* Flags */
156*4882a593Smuzhiyun 	struct list_head	fcf_lsthead;	/* FCF entries */
157*4882a593Smuzhiyun 	struct csio_fcf_info	*fcfinfo;	/* FCF in use */
158*4882a593Smuzhiyun 	struct csio_ioreq	*mgmt_req;	/* MGMT request */
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	/* FCoE identifiers */
161*4882a593Smuzhiyun 	uint8_t			mac[6];
162*4882a593Smuzhiyun 	uint32_t		nport_id;
163*4882a593Smuzhiyun 	struct csio_service_parms ln_sparm;	/* Service parms */
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	/* Firmware identifiers */
166*4882a593Smuzhiyun 	uint32_t		fcf_flowid;	/*fcf flowid */
167*4882a593Smuzhiyun 	uint32_t		vnp_flowid;
168*4882a593Smuzhiyun 	uint16_t		ssn_cnt;	/* Registered Session */
169*4882a593Smuzhiyun 	uint8_t			cur_evt;	/* Current event */
170*4882a593Smuzhiyun 	uint8_t			prev_evt;	/* Previous event */
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	/* Children */
173*4882a593Smuzhiyun 	struct list_head	cln_head;	/* Head of the children lnode
174*4882a593Smuzhiyun 						 * list.
175*4882a593Smuzhiyun 						 */
176*4882a593Smuzhiyun 	uint32_t		num_vports;	/* Total NPIV/children LNodes*/
177*4882a593Smuzhiyun 	struct csio_lnode	*pln;		/* Parent lnode of child
178*4882a593Smuzhiyun 						 * lnodes.
179*4882a593Smuzhiyun 						 */
180*4882a593Smuzhiyun 	struct list_head	cmpl_q;		/* Pending I/Os on this lnode */
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	/* Remote node information */
183*4882a593Smuzhiyun 	struct list_head	rnhead;		/* Head of rnode list */
184*4882a593Smuzhiyun 	uint32_t		num_reg_rnodes;	/* Number of rnodes registered
185*4882a593Smuzhiyun 						 * with the host.
186*4882a593Smuzhiyun 						 */
187*4882a593Smuzhiyun 	uint32_t		n_scsi_tgts;	/* Number of scsi targets
188*4882a593Smuzhiyun 						 * found
189*4882a593Smuzhiyun 						 */
190*4882a593Smuzhiyun 	uint32_t		last_scan_ntgts;/* Number of scsi targets
191*4882a593Smuzhiyun 						 * found per last scan.
192*4882a593Smuzhiyun 						 */
193*4882a593Smuzhiyun 	uint32_t		tgt_scan_tick;	/* timer started after
194*4882a593Smuzhiyun 						 * new tgt found
195*4882a593Smuzhiyun 						 */
196*4882a593Smuzhiyun 	/* FC transport data */
197*4882a593Smuzhiyun 	struct fc_vport		*fc_vport;
198*4882a593Smuzhiyun 	struct fc_host_statistics fch_stats;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	struct csio_lnode_stats stats;		/* Common lnode stats */
201*4882a593Smuzhiyun 	struct csio_lnode_params params;	/* Common lnode params */
202*4882a593Smuzhiyun };
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun #define	csio_lnode_to_hw(ln)	((ln)->hwp)
205*4882a593Smuzhiyun #define csio_root_lnode(ln)	(csio_lnode_to_hw((ln))->rln)
206*4882a593Smuzhiyun #define csio_parent_lnode(ln)	((ln)->pln)
207*4882a593Smuzhiyun #define	csio_ln_flowid(ln)	((ln)->vnp_flowid)
208*4882a593Smuzhiyun #define csio_ln_wwpn(ln)	((ln)->ln_sparm.wwpn)
209*4882a593Smuzhiyun #define csio_ln_wwnn(ln)	((ln)->ln_sparm.wwnn)
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun #define csio_is_root_ln(ln)	(((ln) == csio_root_lnode((ln))) ? 1 : 0)
212*4882a593Smuzhiyun #define csio_is_phys_ln(ln)	(((ln)->pln == NULL) ? 1 : 0)
213*4882a593Smuzhiyun #define csio_is_npiv_ln(ln)	(((ln)->pln != NULL) ? 1 : 0)
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun #define csio_ln_dbg(_ln, _fmt, ...)	\
217*4882a593Smuzhiyun 	csio_dbg(_ln->hwp, "%x:%x "_fmt, CSIO_DEVID_HI(_ln), \
218*4882a593Smuzhiyun 		 CSIO_DEVID_LO(_ln), ##__VA_ARGS__);
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun #define csio_ln_err(_ln, _fmt, ...)	\
221*4882a593Smuzhiyun 	csio_err(_ln->hwp, "%x:%x "_fmt, CSIO_DEVID_HI(_ln), \
222*4882a593Smuzhiyun 		 CSIO_DEVID_LO(_ln), ##__VA_ARGS__);
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun #define csio_ln_warn(_ln, _fmt, ...)	\
225*4882a593Smuzhiyun 	csio_warn(_ln->hwp, "%x:%x "_fmt, CSIO_DEVID_HI(_ln), \
226*4882a593Smuzhiyun 		 CSIO_DEVID_LO(_ln), ##__VA_ARGS__);
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun /* HW->Lnode notifications */
229*4882a593Smuzhiyun enum csio_ln_notify {
230*4882a593Smuzhiyun 	CSIO_LN_NOTIFY_HWREADY = 1,
231*4882a593Smuzhiyun 	CSIO_LN_NOTIFY_HWSTOP,
232*4882a593Smuzhiyun 	CSIO_LN_NOTIFY_HWREMOVE,
233*4882a593Smuzhiyun 	CSIO_LN_NOTIFY_HWRESET,
234*4882a593Smuzhiyun };
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun void csio_fcoe_fwevt_handler(struct csio_hw *,  __u8 cpl_op, __be64 *);
237*4882a593Smuzhiyun int csio_is_lnode_ready(struct csio_lnode *);
238*4882a593Smuzhiyun void csio_lnode_state_to_str(struct csio_lnode *ln, int8_t *str);
239*4882a593Smuzhiyun struct csio_lnode *csio_lnode_lookup_by_wwpn(struct csio_hw *, uint8_t *);
240*4882a593Smuzhiyun int csio_get_phy_port_stats(struct csio_hw *, uint8_t ,
241*4882a593Smuzhiyun 				      struct fw_fcoe_port_stats *);
242*4882a593Smuzhiyun int csio_scan_done(struct csio_lnode *, unsigned long, unsigned long,
243*4882a593Smuzhiyun 		   unsigned long, unsigned long);
244*4882a593Smuzhiyun void csio_notify_lnodes(struct csio_hw *, enum csio_ln_notify);
245*4882a593Smuzhiyun void csio_disable_lnodes(struct csio_hw *, uint8_t, bool);
246*4882a593Smuzhiyun void csio_lnode_async_event(struct csio_lnode *, enum csio_ln_fc_evt);
247*4882a593Smuzhiyun int csio_ln_fdmi_start(struct csio_lnode *, void *);
248*4882a593Smuzhiyun int csio_lnode_start(struct csio_lnode *);
249*4882a593Smuzhiyun void csio_lnode_stop(struct csio_lnode *);
250*4882a593Smuzhiyun void csio_lnode_close(struct csio_lnode *);
251*4882a593Smuzhiyun int csio_lnode_init(struct csio_lnode *, struct csio_hw *,
252*4882a593Smuzhiyun 			      struct csio_lnode *);
253*4882a593Smuzhiyun void csio_lnode_exit(struct csio_lnode *);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun #endif /* ifndef __CSIO_LNODE_H__ */
256