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