18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * This file is part of the Chelsio FCoE driver for Linux.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (c) 2008-2012 Chelsio Communications, Inc. All rights reserved.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * This software is available to you under a choice of one of two
78c2ecf20Sopenharmony_ci * licenses.  You may choose to be licensed under the terms of the GNU
88c2ecf20Sopenharmony_ci * General Public License (GPL) Version 2, available from the file
98c2ecf20Sopenharmony_ci * COPYING in the main directory of this source tree, or the
108c2ecf20Sopenharmony_ci * OpenIB.org BSD license below:
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci *     Redistribution and use in source and binary forms, with or
138c2ecf20Sopenharmony_ci *     without modification, are permitted provided that the following
148c2ecf20Sopenharmony_ci *     conditions are met:
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci *      - Redistributions of source code must retain the above
178c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
188c2ecf20Sopenharmony_ci *        disclaimer.
198c2ecf20Sopenharmony_ci *
208c2ecf20Sopenharmony_ci *      - Redistributions in binary form must reproduce the above
218c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
228c2ecf20Sopenharmony_ci *        disclaimer in the documentation and/or other materials
238c2ecf20Sopenharmony_ci *        provided with the distribution.
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
268c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
278c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
288c2ecf20Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
298c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
308c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
318c2ecf20Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
328c2ecf20Sopenharmony_ci * SOFTWARE.
338c2ecf20Sopenharmony_ci */
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#ifndef __CSIO_LNODE_H__
368c2ecf20Sopenharmony_ci#define __CSIO_LNODE_H__
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#include <linux/kref.h>
398c2ecf20Sopenharmony_ci#include <linux/timer.h>
408c2ecf20Sopenharmony_ci#include <linux/workqueue.h>
418c2ecf20Sopenharmony_ci#include <scsi/fc/fc_els.h>
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci#include "csio_defs.h"
458c2ecf20Sopenharmony_ci#include "csio_hw.h"
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#define CSIO_FCOE_MAX_NPIV	128
488c2ecf20Sopenharmony_ci#define CSIO_FCOE_MAX_RNODES	2048
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci/* FDMI port attribute unknown speed */
518c2ecf20Sopenharmony_ci#define CSIO_HBA_PORTSPEED_UNKNOWN	0x8000
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ciextern int csio_fcoe_rnodes;
548c2ecf20Sopenharmony_ciextern int csio_fdmi_enable;
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci/* State machine evets */
578c2ecf20Sopenharmony_cienum csio_ln_ev {
588c2ecf20Sopenharmony_ci	CSIO_LNE_NONE = (uint32_t)0,
598c2ecf20Sopenharmony_ci	CSIO_LNE_LINKUP,
608c2ecf20Sopenharmony_ci	CSIO_LNE_FAB_INIT_DONE,
618c2ecf20Sopenharmony_ci	CSIO_LNE_LINK_DOWN,
628c2ecf20Sopenharmony_ci	CSIO_LNE_DOWN_LINK,
638c2ecf20Sopenharmony_ci	CSIO_LNE_LOGO,
648c2ecf20Sopenharmony_ci	CSIO_LNE_CLOSE,
658c2ecf20Sopenharmony_ci	CSIO_LNE_MAX_EVENT,
668c2ecf20Sopenharmony_ci};
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistruct csio_fcf_info {
708c2ecf20Sopenharmony_ci	struct list_head	list;
718c2ecf20Sopenharmony_ci	uint8_t			priority;
728c2ecf20Sopenharmony_ci	uint8_t			mac[6];
738c2ecf20Sopenharmony_ci	uint8_t			name_id[8];
748c2ecf20Sopenharmony_ci	uint8_t			fabric[8];
758c2ecf20Sopenharmony_ci	uint16_t		vf_id;
768c2ecf20Sopenharmony_ci	uint8_t			vlan_id;
778c2ecf20Sopenharmony_ci	uint16_t		max_fcoe_size;
788c2ecf20Sopenharmony_ci	uint8_t			fc_map[3];
798c2ecf20Sopenharmony_ci	uint32_t		fka_adv;
808c2ecf20Sopenharmony_ci	uint32_t		fcfi;
818c2ecf20Sopenharmony_ci	uint8_t			get_next:1;
828c2ecf20Sopenharmony_ci	uint8_t			link_aff:1;
838c2ecf20Sopenharmony_ci	uint8_t			fpma:1;
848c2ecf20Sopenharmony_ci	uint8_t			spma:1;
858c2ecf20Sopenharmony_ci	uint8_t			login:1;
868c2ecf20Sopenharmony_ci	uint8_t			portid;
878c2ecf20Sopenharmony_ci	uint8_t			spma_mac[6];
888c2ecf20Sopenharmony_ci	struct kref		kref;
898c2ecf20Sopenharmony_ci};
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci/* Defines for flags */
928c2ecf20Sopenharmony_ci#define	CSIO_LNF_FIPSUPP		0x00000001	/* Fip Supported */
938c2ecf20Sopenharmony_ci#define	CSIO_LNF_NPIVSUPP		0x00000002	/* NPIV supported */
948c2ecf20Sopenharmony_ci#define CSIO_LNF_LINK_ENABLE		0x00000004	/* Link enabled */
958c2ecf20Sopenharmony_ci#define	CSIO_LNF_FDMI_ENABLE		0x00000008	/* FDMI support */
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci/* Transport events */
988c2ecf20Sopenharmony_cienum csio_ln_fc_evt {
998c2ecf20Sopenharmony_ci	CSIO_LN_FC_LINKUP = 1,
1008c2ecf20Sopenharmony_ci	CSIO_LN_FC_LINKDOWN,
1018c2ecf20Sopenharmony_ci	CSIO_LN_FC_RSCN,
1028c2ecf20Sopenharmony_ci	CSIO_LN_FC_ATTRIB_UPDATE,
1038c2ecf20Sopenharmony_ci};
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci/* Lnode stats */
1068c2ecf20Sopenharmony_cistruct csio_lnode_stats {
1078c2ecf20Sopenharmony_ci	uint32_t	n_link_up;	/* Link down */
1088c2ecf20Sopenharmony_ci	uint32_t	n_link_down;	/* Link up */
1098c2ecf20Sopenharmony_ci	uint32_t	n_err;		/* error */
1108c2ecf20Sopenharmony_ci	uint32_t	n_err_nomem;	/* memory not available */
1118c2ecf20Sopenharmony_ci	uint32_t	n_inval_parm;   /* Invalid parameters */
1128c2ecf20Sopenharmony_ci	uint32_t	n_evt_unexp;	/* unexpected event */
1138c2ecf20Sopenharmony_ci	uint32_t	n_evt_drop;	/* dropped event */
1148c2ecf20Sopenharmony_ci	uint32_t	n_rnode_match;  /* matched rnode */
1158c2ecf20Sopenharmony_ci	uint32_t	n_dev_loss_tmo; /* Device loss timeout */
1168c2ecf20Sopenharmony_ci	uint32_t	n_fdmi_err;	/* fdmi err */
1178c2ecf20Sopenharmony_ci	uint32_t	n_evt_fw[PROTO_ERR_IMPL_LOGO + 1];	/* fw events */
1188c2ecf20Sopenharmony_ci	enum csio_ln_ev	n_evt_sm[CSIO_LNE_MAX_EVENT];	/* State m/c events */
1198c2ecf20Sopenharmony_ci	uint32_t	n_rnode_alloc;	/* rnode allocated */
1208c2ecf20Sopenharmony_ci	uint32_t	n_rnode_free;	/* rnode freed */
1218c2ecf20Sopenharmony_ci	uint32_t	n_rnode_nomem;	/* rnode alloc failure */
1228c2ecf20Sopenharmony_ci	uint32_t        n_input_requests; /* Input Requests */
1238c2ecf20Sopenharmony_ci	uint32_t        n_output_requests; /* Output Requests */
1248c2ecf20Sopenharmony_ci	uint32_t        n_control_requests; /* Control Requests */
1258c2ecf20Sopenharmony_ci	uint32_t        n_input_bytes; /* Input Bytes */
1268c2ecf20Sopenharmony_ci	uint32_t        n_output_bytes; /* Output Bytes */
1278c2ecf20Sopenharmony_ci	uint32_t	rsvd1;
1288c2ecf20Sopenharmony_ci};
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci/* Common Lnode params */
1318c2ecf20Sopenharmony_cistruct csio_lnode_params {
1328c2ecf20Sopenharmony_ci	uint32_t	ra_tov;
1338c2ecf20Sopenharmony_ci	uint32_t	fcfi;
1348c2ecf20Sopenharmony_ci	uint32_t	log_level;	/* Module level for debugging */
1358c2ecf20Sopenharmony_ci};
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_cistruct csio_service_parms {
1388c2ecf20Sopenharmony_ci	struct fc_els_csp	csp;		/* Common service parms */
1398c2ecf20Sopenharmony_ci	uint8_t			wwpn[8];	/* WWPN */
1408c2ecf20Sopenharmony_ci	uint8_t			wwnn[8];	/* WWNN */
1418c2ecf20Sopenharmony_ci	struct fc_els_cssp	clsp[4];	/* Class service params */
1428c2ecf20Sopenharmony_ci	uint8_t			vvl[16];	/* Vendor version level */
1438c2ecf20Sopenharmony_ci};
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci/* Lnode */
1468c2ecf20Sopenharmony_cistruct csio_lnode {
1478c2ecf20Sopenharmony_ci	struct csio_sm		sm;		/* State machine + sibling
1488c2ecf20Sopenharmony_ci						 * lnode list.
1498c2ecf20Sopenharmony_ci						 */
1508c2ecf20Sopenharmony_ci	struct csio_hw		*hwp;		/* Pointer to the HW module */
1518c2ecf20Sopenharmony_ci	uint8_t			portid;		/* Port ID */
1528c2ecf20Sopenharmony_ci	uint8_t			rsvd1;
1538c2ecf20Sopenharmony_ci	uint16_t		rsvd2;
1548c2ecf20Sopenharmony_ci	uint32_t		dev_num;	/* Device number */
1558c2ecf20Sopenharmony_ci	uint32_t		flags;		/* Flags */
1568c2ecf20Sopenharmony_ci	struct list_head	fcf_lsthead;	/* FCF entries */
1578c2ecf20Sopenharmony_ci	struct csio_fcf_info	*fcfinfo;	/* FCF in use */
1588c2ecf20Sopenharmony_ci	struct csio_ioreq	*mgmt_req;	/* MGMT request */
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	/* FCoE identifiers */
1618c2ecf20Sopenharmony_ci	uint8_t			mac[6];
1628c2ecf20Sopenharmony_ci	uint32_t		nport_id;
1638c2ecf20Sopenharmony_ci	struct csio_service_parms ln_sparm;	/* Service parms */
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci	/* Firmware identifiers */
1668c2ecf20Sopenharmony_ci	uint32_t		fcf_flowid;	/*fcf flowid */
1678c2ecf20Sopenharmony_ci	uint32_t		vnp_flowid;
1688c2ecf20Sopenharmony_ci	uint16_t		ssn_cnt;	/* Registered Session */
1698c2ecf20Sopenharmony_ci	uint8_t			cur_evt;	/* Current event */
1708c2ecf20Sopenharmony_ci	uint8_t			prev_evt;	/* Previous event */
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	/* Children */
1738c2ecf20Sopenharmony_ci	struct list_head	cln_head;	/* Head of the children lnode
1748c2ecf20Sopenharmony_ci						 * list.
1758c2ecf20Sopenharmony_ci						 */
1768c2ecf20Sopenharmony_ci	uint32_t		num_vports;	/* Total NPIV/children LNodes*/
1778c2ecf20Sopenharmony_ci	struct csio_lnode	*pln;		/* Parent lnode of child
1788c2ecf20Sopenharmony_ci						 * lnodes.
1798c2ecf20Sopenharmony_ci						 */
1808c2ecf20Sopenharmony_ci	struct list_head	cmpl_q;		/* Pending I/Os on this lnode */
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	/* Remote node information */
1838c2ecf20Sopenharmony_ci	struct list_head	rnhead;		/* Head of rnode list */
1848c2ecf20Sopenharmony_ci	uint32_t		num_reg_rnodes;	/* Number of rnodes registered
1858c2ecf20Sopenharmony_ci						 * with the host.
1868c2ecf20Sopenharmony_ci						 */
1878c2ecf20Sopenharmony_ci	uint32_t		n_scsi_tgts;	/* Number of scsi targets
1888c2ecf20Sopenharmony_ci						 * found
1898c2ecf20Sopenharmony_ci						 */
1908c2ecf20Sopenharmony_ci	uint32_t		last_scan_ntgts;/* Number of scsi targets
1918c2ecf20Sopenharmony_ci						 * found per last scan.
1928c2ecf20Sopenharmony_ci						 */
1938c2ecf20Sopenharmony_ci	uint32_t		tgt_scan_tick;	/* timer started after
1948c2ecf20Sopenharmony_ci						 * new tgt found
1958c2ecf20Sopenharmony_ci						 */
1968c2ecf20Sopenharmony_ci	/* FC transport data */
1978c2ecf20Sopenharmony_ci	struct fc_vport		*fc_vport;
1988c2ecf20Sopenharmony_ci	struct fc_host_statistics fch_stats;
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	struct csio_lnode_stats stats;		/* Common lnode stats */
2018c2ecf20Sopenharmony_ci	struct csio_lnode_params params;	/* Common lnode params */
2028c2ecf20Sopenharmony_ci};
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci#define	csio_lnode_to_hw(ln)	((ln)->hwp)
2058c2ecf20Sopenharmony_ci#define csio_root_lnode(ln)	(csio_lnode_to_hw((ln))->rln)
2068c2ecf20Sopenharmony_ci#define csio_parent_lnode(ln)	((ln)->pln)
2078c2ecf20Sopenharmony_ci#define	csio_ln_flowid(ln)	((ln)->vnp_flowid)
2088c2ecf20Sopenharmony_ci#define csio_ln_wwpn(ln)	((ln)->ln_sparm.wwpn)
2098c2ecf20Sopenharmony_ci#define csio_ln_wwnn(ln)	((ln)->ln_sparm.wwnn)
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci#define csio_is_root_ln(ln)	(((ln) == csio_root_lnode((ln))) ? 1 : 0)
2128c2ecf20Sopenharmony_ci#define csio_is_phys_ln(ln)	(((ln)->pln == NULL) ? 1 : 0)
2138c2ecf20Sopenharmony_ci#define csio_is_npiv_ln(ln)	(((ln)->pln != NULL) ? 1 : 0)
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci#define csio_ln_dbg(_ln, _fmt, ...)	\
2178c2ecf20Sopenharmony_ci	csio_dbg(_ln->hwp, "%x:%x "_fmt, CSIO_DEVID_HI(_ln), \
2188c2ecf20Sopenharmony_ci		 CSIO_DEVID_LO(_ln), ##__VA_ARGS__);
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci#define csio_ln_err(_ln, _fmt, ...)	\
2218c2ecf20Sopenharmony_ci	csio_err(_ln->hwp, "%x:%x "_fmt, CSIO_DEVID_HI(_ln), \
2228c2ecf20Sopenharmony_ci		 CSIO_DEVID_LO(_ln), ##__VA_ARGS__);
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci#define csio_ln_warn(_ln, _fmt, ...)	\
2258c2ecf20Sopenharmony_ci	csio_warn(_ln->hwp, "%x:%x "_fmt, CSIO_DEVID_HI(_ln), \
2268c2ecf20Sopenharmony_ci		 CSIO_DEVID_LO(_ln), ##__VA_ARGS__);
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci/* HW->Lnode notifications */
2298c2ecf20Sopenharmony_cienum csio_ln_notify {
2308c2ecf20Sopenharmony_ci	CSIO_LN_NOTIFY_HWREADY = 1,
2318c2ecf20Sopenharmony_ci	CSIO_LN_NOTIFY_HWSTOP,
2328c2ecf20Sopenharmony_ci	CSIO_LN_NOTIFY_HWREMOVE,
2338c2ecf20Sopenharmony_ci	CSIO_LN_NOTIFY_HWRESET,
2348c2ecf20Sopenharmony_ci};
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_civoid csio_fcoe_fwevt_handler(struct csio_hw *,  __u8 cpl_op, __be64 *);
2378c2ecf20Sopenharmony_ciint csio_is_lnode_ready(struct csio_lnode *);
2388c2ecf20Sopenharmony_civoid csio_lnode_state_to_str(struct csio_lnode *ln, int8_t *str);
2398c2ecf20Sopenharmony_cistruct csio_lnode *csio_lnode_lookup_by_wwpn(struct csio_hw *, uint8_t *);
2408c2ecf20Sopenharmony_ciint csio_get_phy_port_stats(struct csio_hw *, uint8_t ,
2418c2ecf20Sopenharmony_ci				      struct fw_fcoe_port_stats *);
2428c2ecf20Sopenharmony_ciint csio_scan_done(struct csio_lnode *, unsigned long, unsigned long,
2438c2ecf20Sopenharmony_ci		   unsigned long, unsigned long);
2448c2ecf20Sopenharmony_civoid csio_notify_lnodes(struct csio_hw *, enum csio_ln_notify);
2458c2ecf20Sopenharmony_civoid csio_disable_lnodes(struct csio_hw *, uint8_t, bool);
2468c2ecf20Sopenharmony_civoid csio_lnode_async_event(struct csio_lnode *, enum csio_ln_fc_evt);
2478c2ecf20Sopenharmony_ciint csio_ln_fdmi_start(struct csio_lnode *, void *);
2488c2ecf20Sopenharmony_ciint csio_lnode_start(struct csio_lnode *);
2498c2ecf20Sopenharmony_civoid csio_lnode_stop(struct csio_lnode *);
2508c2ecf20Sopenharmony_civoid csio_lnode_close(struct csio_lnode *);
2518c2ecf20Sopenharmony_ciint csio_lnode_init(struct csio_lnode *, struct csio_hw *,
2528c2ecf20Sopenharmony_ci			      struct csio_lnode *);
2538c2ecf20Sopenharmony_civoid csio_lnode_exit(struct csio_lnode *);
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci#endif /* ifndef __CSIO_LNODE_H__ */
256