brintos

brintos / linux-shallow public Read only

0
0
Text · 16.5 KiB · 57e3386 Raw
624 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * Copyright (C) 2021 Broadcom. All Rights Reserved. The term4 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.5 */6 7#ifndef __EFCLIB_H__8#define __EFCLIB_H__9 10#include "scsi/fc/fc_els.h"11#include "scsi/fc/fc_fs.h"12#include "scsi/fc/fc_ns.h"13#include "scsi/fc/fc_gs.h"14#include "scsi/fc_frame.h"15#include "../include/efc_common.h"16#include "../libefc_sli/sli4.h"17 18#define EFC_SERVICE_PARMS_LENGTH	12019#define EFC_NAME_LENGTH			3220#define EFC_SM_NAME_LENGTH		6421#define EFC_DISPLAY_BUS_INFO_LENGTH	1622 23#define EFC_WWN_LENGTH			3224 25#define EFC_FC_ELS_DEFAULT_RETRIES	326 27/* Timeouts */28#define EFC_FC_ELS_SEND_DEFAULT_TIMEOUT	029#define EFC_FC_FLOGI_TIMEOUT_SEC	530#define EFC_SHUTDOWN_TIMEOUT_USEC	3000000031 32/* Return values for calls from base driver to libefc */33#define EFC_SCSI_CALL_COMPLETE		034#define EFC_SCSI_CALL_ASYNC		135 36/* Local port topology */37enum efc_nport_topology {38	EFC_NPORT_TOPO_UNKNOWN = 0,39	EFC_NPORT_TOPO_FABRIC,40	EFC_NPORT_TOPO_P2P,41	EFC_NPORT_TOPO_FC_AL,42};43 44#define enable_target_rscn(efc)		145 46enum efc_node_shutd_rsn {47	EFC_NODE_SHUTDOWN_DEFAULT = 0,48	EFC_NODE_SHUTDOWN_EXPLICIT_LOGO,49	EFC_NODE_SHUTDOWN_IMPLICIT_LOGO,50};51 52enum efc_node_send_ls_acc {53	EFC_NODE_SEND_LS_ACC_NONE = 0,54	EFC_NODE_SEND_LS_ACC_PLOGI,55	EFC_NODE_SEND_LS_ACC_PRLI,56};57 58#define EFC_LINK_STATUS_UP		059#define EFC_LINK_STATUS_DOWN		160 61enum efc_sm_event;62 63/* State machine context header  */64struct efc_sm_ctx {65	void (*current_state)(struct efc_sm_ctx *ctx,66			      enum efc_sm_event evt, void *arg);67 68	const char	*description;69	void		*app;70};71 72/* Description of discovered Fabric Domain */73struct efc_domain_record {74	u32		index;75	u32		priority;76	u8		address[6];77	u8		wwn[8];78	union {79		u8	vlan[512];80		u8	loop[128];81	} map;82	u32		speed;83	u32		fc_id;84	bool		is_loop;85	bool		is_nport;86};87 88/* Domain events */89enum efc_hw_domain_event {90	EFC_HW_DOMAIN_ALLOC_OK,91	EFC_HW_DOMAIN_ALLOC_FAIL,92	EFC_HW_DOMAIN_ATTACH_OK,93	EFC_HW_DOMAIN_ATTACH_FAIL,94	EFC_HW_DOMAIN_FREE_OK,95	EFC_HW_DOMAIN_FREE_FAIL,96	EFC_HW_DOMAIN_LOST,97	EFC_HW_DOMAIN_FOUND,98	EFC_HW_DOMAIN_CHANGED,99};100 101/**102 * Fibre Channel port object103 *104 * @list_entry:		nport list entry105 * @ref:		reference count, each node takes a reference106 * @release:		function to free nport object107 * @efc:		pointer back to efc108 * @instance_index:	unique instance index value109 * @display_name:	port display name110 * @is_vport:		Is NPIV port111 * @free_req_pending:	pending request to free resources112 * @attached:		mark attached if reg VPI succeeds113 * @p2p_winner:		TRUE if we're the point-to-point winner114 * @domain:		pointer back to domain115 * @wwpn:		port wwpn116 * @wwnn:		port wwnn117 * @tgt_data:		target backend private port data118 * @ini_data:		initiator backend private port data119 * @indicator:		VPI120 * @fc_id:		port FC address121 * @dma:		memory for Service Parameters122 * @wwnn_str:		wwpn string123 * @sli_wwpn:		SLI provided wwpn124 * @sli_wwnn:		SLI provided wwnn125 * @sm:			nport state machine context126 * @lookup:		fc_id to node lookup object127 * @enable_ini:		SCSI initiator enabled for this port128 * @enable_tgt:		SCSI target enabled for this port129 * @enable_rscn:	port will be expecting RSCN130 * @shutting_down:	nport in process of shutting down131 * @p2p_port_id:	our port id for point-to-point132 * @topology:		topology: fabric/p2p/unknown133 * @service_params:	login parameters134 * @p2p_remote_port_id:	remote node's port id for point-to-point135 */136 137struct efc_nport {138	struct list_head	list_entry;139	struct kref		ref;140	void			(*release)(struct kref *arg);141	struct efc		*efc;142	u32			instance_index;143	char			display_name[EFC_NAME_LENGTH];144	bool			is_vport;145	bool			free_req_pending;146	bool			attached;147	bool			attaching;148	bool			p2p_winner;149	struct efc_domain	*domain;150	u64			wwpn;151	u64			wwnn;152	void			*tgt_data;153	void			*ini_data;154 155	u32			indicator;156	u32			fc_id;157	struct efc_dma		dma;158 159	u8			wwnn_str[EFC_WWN_LENGTH];160	__be64			sli_wwpn;161	__be64			sli_wwnn;162 163	struct efc_sm_ctx	sm;164	struct xarray		lookup;165	bool			enable_ini;166	bool			enable_tgt;167	bool			enable_rscn;168	bool			shutting_down;169	u32			p2p_port_id;170	enum efc_nport_topology topology;171	u8			service_params[EFC_SERVICE_PARMS_LENGTH];172	u32			p2p_remote_port_id;173};174 175/**176 * Fibre Channel domain object177 *178 * This object is a container for the various SLI components needed179 * to connect to the domain of a FC or FCoE switch180 * @efc:		pointer back to efc181 * @instance_index:	unique instance index value182 * @display_name:	Node display name183 * @nport_list:		linked list of nports associated with this domain184 * @ref:		Reference count, each nport takes a reference185 * @release:		Function to free domain object186 * @ini_domain:		initiator backend private domain data187 * @tgt_domain:		target backend private domain data188 * @sm:			state machine context189 * @fcf:		FC Forwarder table index190 * @fcf_indicator:	FCFI191 * @indicator:		VFI192 * @nport_count:	Number of nports allocated193 * @dma:		memory for Service Parameters194 * @fcf_wwn:		WWN for FCF/switch195 * @drvsm:		driver domain sm context196 * @attached:		set true after attach completes197 * @is_fc:		is FC198 * @is_loop:		is loop topology199 * @is_nlport:		is public loop200 * @domain_found_pending:A domain found is pending, drec is updated201 * @req_domain_free:	True if domain object should be free'd202 * @req_accept_frames:	set in domain state machine to enable frames203 * @domain_notify_pend:	Set in domain SM to avoid duplicate node event post204 * @pending_drec:	Pending drec if a domain found is pending205 * @service_params:	any nports service parameters206 * @flogi_service_params:Fabric/P2p service parameters from FLOGI207 * @lookup:		d_id to node lookup object208 * @nport:		Pointer to first (physical) SLI port209 */210struct efc_domain {211	struct efc		*efc;212	char			display_name[EFC_NAME_LENGTH];213	struct list_head	nport_list;214	struct kref		ref;215	void			(*release)(struct kref *arg);216	void			*ini_domain;217	void			*tgt_domain;218 219	/* Declarations private to HW/SLI */220	u32			fcf;221	u32			fcf_indicator;222	u32			indicator;223	u32			nport_count;224	struct efc_dma		dma;225 226	/* Declarations private to FC trannport */227	u64			fcf_wwn;228	struct efc_sm_ctx	drvsm;229	bool			attached;230	bool			is_fc;231	bool			is_loop;232	bool			is_nlport;233	bool			domain_found_pending;234	bool			req_domain_free;235	bool			req_accept_frames;236	bool			domain_notify_pend;237 238	struct efc_domain_record pending_drec;239	u8			service_params[EFC_SERVICE_PARMS_LENGTH];240	u8			flogi_service_params[EFC_SERVICE_PARMS_LENGTH];241 242	struct xarray		lookup;243 244	struct efc_nport	*nport;245};246 247/**248 * Remote Node object249 *250 * This object represents a connection between the SLI port and another251 * Nx_Port on the fabric. Note this can be either a well known port such252 * as a F_Port (i.e. ff:ff:fe) or another N_Port.253 * @indicator:		RPI254 * @fc_id:		FC address255 * @attached:		true if attached256 * @nport:		associated SLI port257 * @node:		associated node258 */259struct efc_remote_node {260	u32			indicator;261	u32			index;262	u32			fc_id;263 264	bool			attached;265 266	struct efc_nport	*nport;267	void			*node;268};269 270/**271 * FC Node object272 * @efc:		pointer back to efc structure273 * @display_name:	Node display name274 * @nort:		Assosiated nport pointer.275 * @hold_frames:	hold incoming frames if true276 * @els_io_enabled:	Enable allocating els ios for this node277 * @els_ios_lock:	lock to protect the els ios list278 * @els_ios_list:	ELS I/O's for this node279 * @ini_node:		backend initiator private node data280 * @tgt_node:		backend target private node data281 * @rnode:		Remote node282 * @sm:			state machine context283 * @evtdepth:		current event posting nesting depth284 * @req_free:		this node is to be free'd285 * @attached:		node is attached (REGLOGIN complete)286 * @fcp_enabled:	node is enabled to handle FCP287 * @rscn_pending:	for name server node RSCN is pending288 * @send_plogi:		send PLOGI accept, upon completion of node attach289 * @send_plogi_acc:	TRUE if io_alloc() is enabled.290 * @send_ls_acc:	type of LS acc to send291 * @ls_acc_io:		SCSI IO for LS acc292 * @ls_acc_oxid:	OX_ID for pending accept293 * @ls_acc_did:		D_ID for pending accept294 * @shutdown_reason:	reason for node shutdown295 * @sparm_dma_buf:	service parameters buffer296 * @service_params:	plogi/acc frame from remote device297 * @pend_frames_lock:	lock for inbound pending frames list298 * @pend_frames:	inbound pending frames list299 * @pend_frames_processed:count of frames processed in hold frames interval300 * @ox_id_in_use:	used to verify one at a time us of ox_id301 * @els_retries_remaining:for ELS, number of retries remaining302 * @els_req_cnt:	number of outstanding ELS requests303 * @els_cmpl_cnt:	number of outstanding ELS completions304 * @abort_cnt:		Abort counter for debugging purpos305 * @current_state_name:	current node state306 * @prev_state_name:	previous node state307 * @current_evt:	current event308 * @prev_evt:		previous event309 * @targ:		node is target capable310 * @init:		node is init capable311 * @refound:		Handle node refound case when node is being deleted312 * @els_io_pend_list:	list of pending (not yet processed) ELS IOs313 * @els_io_active_list:	list of active (processed) ELS IOs314 * @nodedb_state:	Node debugging, saved state315 * @gidpt_delay_timer:	GIDPT delay timer316 * @time_last_gidpt_msec:Start time of last target RSCN GIDPT317 * @wwnn:		remote port WWNN318 * @wwpn:		remote port WWPN319 */320struct efc_node {321	struct efc		*efc;322	char			display_name[EFC_NAME_LENGTH];323	struct efc_nport	*nport;324	struct kref		ref;325	void			(*release)(struct kref *arg);326	bool			hold_frames;327	bool			els_io_enabled;328	bool			send_plogi_acc;329	bool			send_plogi;330	bool			rscn_pending;331	bool			fcp_enabled;332	bool			attached;333	bool			req_free;334 335	spinlock_t		els_ios_lock;336	struct list_head	els_ios_list;337	void			*ini_node;338	void			*tgt_node;339 340	struct efc_remote_node	rnode;341	/* Declarations private to FC trannport */342	struct efc_sm_ctx	sm;343	u32			evtdepth;344 345	enum efc_node_send_ls_acc send_ls_acc;346	void			*ls_acc_io;347	u32			ls_acc_oxid;348	u32			ls_acc_did;349	enum efc_node_shutd_rsn	shutdown_reason;350	bool			targ;351	bool			init;352	bool			refound;353	struct efc_dma		sparm_dma_buf;354	u8			service_params[EFC_SERVICE_PARMS_LENGTH];355	spinlock_t		pend_frames_lock;356	struct list_head	pend_frames;357	u32			pend_frames_processed;358	u32			ox_id_in_use;359	u32			els_retries_remaining;360	u32			els_req_cnt;361	u32			els_cmpl_cnt;362	u32			abort_cnt;363 364	char			current_state_name[EFC_SM_NAME_LENGTH];365	char			prev_state_name[EFC_SM_NAME_LENGTH];366	int			current_evt;367	int			prev_evt;368 369	void (*nodedb_state)(struct efc_sm_ctx *ctx,370			     enum efc_sm_event evt, void *arg);371	struct timer_list	gidpt_delay_timer;372	u64			time_last_gidpt_msec;373 374	char			wwnn[EFC_WWN_LENGTH];375	char			wwpn[EFC_WWN_LENGTH];376};377 378/**379 * NPIV port380 *381 * Collection of the information required to restore a virtual port across382 * link events383 * @wwnn:		node name384 * @wwpn:		port name385 * @fc_id:		port id386 * @tgt_data:		target backend pointer387 * @ini_data:		initiator backend pointe388 * @nport:		Used to match record after attaching for update389 *390 */391 392struct efc_vport {393	struct list_head	list_entry;394	u64			wwnn;395	u64			wwpn;396	u32			fc_id;397	bool			enable_tgt;398	bool			enable_ini;399	void			*tgt_data;400	void			*ini_data;401	struct efc_nport	*nport;402};403 404#define node_printf(node, fmt, args...) \405	efc_log_info(node->efc, "[%s] " fmt, node->display_name, ##args)406 407/* Node SM IO Context Callback structure */408struct efc_node_cb {409	int			status;410	int			ext_status;411	struct efc_hw_rq_buffer *header;412	struct efc_hw_rq_buffer *payload;413	struct efc_dma		els_rsp;414 415	/* Actual length of data received */416	int			rsp_len;417};418 419struct efc_hw_rq_buffer {420	u16			rqindex;421	struct efc_dma		dma;422};423 424/**425 * FC sequence object426 *427 * Defines a general FC sequence object428 * @hw:			HW that owns this sequence429 * @fcfi:		FCFI associated with sequence430 * @header:		Received frame header431 * @payload:		Received frame header432 * @hw_priv:		HW private context433 */434struct efc_hw_sequence {435	struct list_head	list_entry;436	void			*hw;437	u8			fcfi;438	struct efc_hw_rq_buffer *header;439	struct efc_hw_rq_buffer *payload;440	void			*hw_priv;441};442 443enum efc_disc_io_type {444	EFC_DISC_IO_ELS_REQ,445	EFC_DISC_IO_ELS_RESP,446	EFC_DISC_IO_CT_REQ,447	EFC_DISC_IO_CT_RESP448};449 450struct efc_io_els_params {451	u32             s_id;452	u16             ox_id;453	u8              timeout;454};455 456struct efc_io_ct_params {457	u8              r_ctl;458	u8              type;459	u8              df_ctl;460	u8              timeout;461	u16             ox_id;462};463 464union efc_disc_io_param {465	struct efc_io_els_params els;466	struct efc_io_ct_params ct;467};468 469struct efc_disc_io {470	struct efc_dma		req;         /* send buffer */471	struct efc_dma		rsp;         /* receive buffer */472	enum efc_disc_io_type	io_type;     /* EFC_DISC_IO_TYPE enum*/473	u16			xmit_len;    /* Length of els request*/474	u16			rsp_len;     /* Max length of rsps to be rcvd */475	u32			rpi;         /* Registered RPI */476	u32			vpi;         /* VPI for this nport */477	u32			s_id;478	u32			d_id;479	bool			rpi_registered; /* if false, use tmp RPI */480	union efc_disc_io_param iparam;481};482 483/* Return value indiacating the sequence can not be freed */484#define EFC_HW_SEQ_HOLD		0485/* Return value indiacating the sequence can be freed */486#define EFC_HW_SEQ_FREE		1487 488struct libefc_function_template {489	/*Sport*/490	int (*new_nport)(struct efc *efc, struct efc_nport *sp);491	void (*del_nport)(struct efc *efc, struct efc_nport *sp);492 493	/*Scsi Node*/494	int (*scsi_new_node)(struct efc *efc, struct efc_node *n);495	int (*scsi_del_node)(struct efc *efc, struct efc_node *n, int reason);496 497	int (*issue_mbox_rqst)(void *efct, void *buf, void *cb, void *arg);498	/*Send ELS IO*/499	int (*send_els)(struct efc *efc, struct efc_disc_io *io);500	/*Send BLS IO*/501	int (*send_bls)(struct efc *efc, u32 type, struct sli_bls_params *bls);502	/*Free HW frame*/503	int (*hw_seq_free)(struct efc *efc, struct efc_hw_sequence *seq);504};505 506#define EFC_LOG_LIB		0x01507#define EFC_LOG_NODE		0x02508#define EFC_LOG_PORT		0x04509#define EFC_LOG_DOMAIN		0x08510#define EFC_LOG_ELS		0x10511#define EFC_LOG_DOMAIN_SM	0x20512#define EFC_LOG_SM		0x40513 514/* efc library port structure */515struct efc {516	void			*base;517	struct pci_dev		*pci;518	struct sli4		*sli;519	u32			fcfi;520	u64			req_wwpn;521	u64			req_wwnn;522 523	u64			def_wwpn;524	u64			def_wwnn;525	u64			max_xfer_size;526	mempool_t		*node_pool;527	struct dma_pool		*node_dma_pool;528	u32			nodes_count;529 530	u32			link_status;531 532	struct list_head	vport_list;533	/* lock to protect the vport list */534	spinlock_t		vport_lock;535 536	struct libefc_function_template tt;537	/* lock to protect the discovery library.538	 * Refer to efclib.c for more details.539	 */540	spinlock_t		lock;541 542	bool			enable_ini;543	bool			enable_tgt;544 545	u32			log_level;546 547	struct efc_domain	*domain;548	void (*domain_free_cb)(struct efc *efc, void *arg);549	void			*domain_free_cb_arg;550 551	u64			tgt_rscn_delay_msec;552	u64			tgt_rscn_period_msec;553 554	bool			external_loopback;555	u32			nodedb_mask;556	u32			logmask;557	mempool_t		*els_io_pool;558	atomic_t		els_io_alloc_failed_count;559 560	/* hold pending frames */561	bool			hold_frames;562	/* lock to protect pending frames list access */563	spinlock_t		pend_frames_lock;564	struct list_head	pend_frames;565	/* count of pending frames that were processed */566	u32			pend_frames_processed;567 568};569 570/*571 * EFC library registration572 * **********************************/573int efcport_init(struct efc *efc);574void efcport_destroy(struct efc *efc);575/*576 * EFC Domain577 * **********************************/578int efc_domain_cb(void *arg, int event, void *data);579void580efc_register_domain_free_cb(struct efc *efc,581			    void (*callback)(struct efc *efc, void *arg),582			    void *arg);583 584/*585 * EFC nport586 * **********************************/587void efc_nport_cb(void *arg, int event, void *data);588struct efc_vport *589efc_vport_create_spec(struct efc *efc, u64 wwnn, u64 wwpn, u32 fc_id,590		      bool enable_ini, bool enable_tgt,591		      void *tgt_data, void *ini_data);592int efc_nport_vport_new(struct efc_domain *domain, u64 wwpn,593			u64 wwnn, u32 fc_id, bool ini, bool tgt,594			void *tgt_data, void *ini_data);595int efc_nport_vport_del(struct efc *efc, struct efc_domain *domain,596			u64 wwpn, u64 wwnn);597 598void efc_vport_del_all(struct efc *efc);599 600/*601 * EFC Node602 * **********************************/603int efc_remote_node_cb(void *arg, int event, void *data);604void efc_node_fcid_display(u32 fc_id, char *buffer, u32 buf_len);605void efc_node_post_shutdown(struct efc_node *node, void *arg);606u64 efc_node_get_wwpn(struct efc_node *node);607 608/*609 * EFC FCP/ELS/CT interface610 * **********************************/611void efc_dispatch_frame(struct efc *efc, struct efc_hw_sequence *seq);612void efc_disc_io_complete(struct efc_disc_io *io, u32 len, u32 status,613			  u32 ext_status);614 615/*616 * EFC SCSI INTERACTION LAYER617 * **********************************/618void efc_scsi_sess_reg_complete(struct efc_node *node, u32 status);619void efc_scsi_del_initiator_complete(struct efc *efc, struct efc_node *node);620void efc_scsi_del_target_complete(struct efc *efc, struct efc_node *node);621void efc_scsi_io_list_empty(struct efc *efc, struct efc_node *node);622 623#endif /* __EFCLIB_H__ */624