xref: /openbmc/linux/drivers/scsi/elx/libefc/efc_els.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
18f406ef7SJames Smart // SPDX-License-Identifier: GPL-2.0
28f406ef7SJames Smart /*
38f406ef7SJames Smart  * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
48f406ef7SJames Smart  * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
58f406ef7SJames Smart  */
68f406ef7SJames Smart 
78f406ef7SJames Smart /*
88f406ef7SJames Smart  * Functions to build and send ELS/CT/BLS commands and responses.
98f406ef7SJames Smart  */
108f406ef7SJames Smart 
118f406ef7SJames Smart #include "efc.h"
128f406ef7SJames Smart #include "efc_els.h"
138f406ef7SJames Smart #include "../libefc_sli/sli4.h"
148f406ef7SJames Smart 
158f406ef7SJames Smart #define EFC_LOG_ENABLE_ELS_TRACE(efc)		\
168f406ef7SJames Smart 		(((efc) != NULL) ? (((efc)->logmask & (1U << 1)) != 0) : 0)
178f406ef7SJames Smart 
188f406ef7SJames Smart #define node_els_trace()  \
198f406ef7SJames Smart 	do { \
208f406ef7SJames Smart 		if (EFC_LOG_ENABLE_ELS_TRACE(efc)) \
218f406ef7SJames Smart 			efc_log_info(efc, "[%s] %-20s\n", \
228f406ef7SJames Smart 				node->display_name, __func__); \
238f406ef7SJames Smart 	} while (0)
248f406ef7SJames Smart 
258f406ef7SJames Smart #define els_io_printf(els, fmt, ...) \
268f406ef7SJames Smart 	efc_log_err((struct efc *)els->node->efc,\
278f406ef7SJames Smart 		      "[%s] %-8s " fmt, \
288f406ef7SJames Smart 		      els->node->display_name,\
298f406ef7SJames Smart 		      els->display_name, ##__VA_ARGS__)
308f406ef7SJames Smart 
318f406ef7SJames Smart #define EFC_ELS_RSP_LEN			1024
328f406ef7SJames Smart #define EFC_ELS_GID_PT_RSP_LEN		8096
338f406ef7SJames Smart 
348f406ef7SJames Smart struct efc_els_io_req *
efc_els_io_alloc(struct efc_node * node,u32 reqlen)358f406ef7SJames Smart efc_els_io_alloc(struct efc_node *node, u32 reqlen)
368f406ef7SJames Smart {
378f406ef7SJames Smart 	return efc_els_io_alloc_size(node, reqlen, EFC_ELS_RSP_LEN);
388f406ef7SJames Smart }
398f406ef7SJames Smart 
408f406ef7SJames Smart struct efc_els_io_req *
efc_els_io_alloc_size(struct efc_node * node,u32 reqlen,u32 rsplen)418f406ef7SJames Smart efc_els_io_alloc_size(struct efc_node *node, u32 reqlen, u32 rsplen)
428f406ef7SJames Smart {
438f406ef7SJames Smart 	struct efc *efc;
448f406ef7SJames Smart 	struct efc_els_io_req *els;
458f406ef7SJames Smart 	unsigned long flags = 0;
468f406ef7SJames Smart 
478f406ef7SJames Smart 	efc = node->efc;
488f406ef7SJames Smart 
498f406ef7SJames Smart 	if (!node->els_io_enabled) {
508f406ef7SJames Smart 		efc_log_err(efc, "els io alloc disabled\n");
518f406ef7SJames Smart 		return NULL;
528f406ef7SJames Smart 	}
538f406ef7SJames Smart 
548f406ef7SJames Smart 	els = mempool_alloc(efc->els_io_pool, GFP_ATOMIC);
558f406ef7SJames Smart 	if (!els) {
568f406ef7SJames Smart 		atomic_add_return(1, &efc->els_io_alloc_failed_count);
578f406ef7SJames Smart 		return NULL;
588f406ef7SJames Smart 	}
598f406ef7SJames Smart 
608f406ef7SJames Smart 	/* initialize refcount */
618f406ef7SJames Smart 	kref_init(&els->ref);
628f406ef7SJames Smart 	els->release = _efc_els_io_free;
638f406ef7SJames Smart 
648f406ef7SJames Smart 	/* populate generic io fields */
658f406ef7SJames Smart 	els->node = node;
668f406ef7SJames Smart 
678f406ef7SJames Smart 	/* now allocate DMA for request and response */
688f406ef7SJames Smart 	els->io.req.size = reqlen;
698f406ef7SJames Smart 	els->io.req.virt = dma_alloc_coherent(&efc->pci->dev, els->io.req.size,
70efac162aSChristoph Hellwig 					      &els->io.req.phys, GFP_KERNEL);
718f406ef7SJames Smart 	if (!els->io.req.virt) {
728f406ef7SJames Smart 		mempool_free(els, efc->els_io_pool);
738f406ef7SJames Smart 		return NULL;
748f406ef7SJames Smart 	}
758f406ef7SJames Smart 
768f406ef7SJames Smart 	els->io.rsp.size = rsplen;
778f406ef7SJames Smart 	els->io.rsp.virt = dma_alloc_coherent(&efc->pci->dev, els->io.rsp.size,
78efac162aSChristoph Hellwig 					      &els->io.rsp.phys, GFP_KERNEL);
798f406ef7SJames Smart 	if (!els->io.rsp.virt) {
808f406ef7SJames Smart 		dma_free_coherent(&efc->pci->dev, els->io.req.size,
818f406ef7SJames Smart 				  els->io.req.virt, els->io.req.phys);
828f406ef7SJames Smart 		mempool_free(els, efc->els_io_pool);
838f406ef7SJames Smart 		els = NULL;
848f406ef7SJames Smart 	}
858f406ef7SJames Smart 
868f406ef7SJames Smart 	if (els) {
878f406ef7SJames Smart 		/* initialize fields */
888f406ef7SJames Smart 		els->els_retries_remaining = EFC_FC_ELS_DEFAULT_RETRIES;
898f406ef7SJames Smart 
908f406ef7SJames Smart 		/* add els structure to ELS IO list */
918f406ef7SJames Smart 		INIT_LIST_HEAD(&els->list_entry);
92*61263b3aSYang Yingliang 		spin_lock_irqsave(&node->els_ios_lock, flags);
938f406ef7SJames Smart 		list_add_tail(&els->list_entry, &node->els_ios_list);
94*61263b3aSYang Yingliang 		spin_unlock_irqrestore(&node->els_ios_lock, flags);
958f406ef7SJames Smart 	}
968f406ef7SJames Smart 
978f406ef7SJames Smart 	return els;
988f406ef7SJames Smart }
998f406ef7SJames Smart 
1008f406ef7SJames Smart void
efc_els_io_free(struct efc_els_io_req * els)1018f406ef7SJames Smart efc_els_io_free(struct efc_els_io_req *els)
1028f406ef7SJames Smart {
1038f406ef7SJames Smart 	kref_put(&els->ref, els->release);
1048f406ef7SJames Smart }
1058f406ef7SJames Smart 
1068f406ef7SJames Smart void
_efc_els_io_free(struct kref * arg)1078f406ef7SJames Smart _efc_els_io_free(struct kref *arg)
1088f406ef7SJames Smart {
1098f406ef7SJames Smart 	struct efc_els_io_req *els =
1108f406ef7SJames Smart 				container_of(arg, struct efc_els_io_req, ref);
1118f406ef7SJames Smart 	struct efc *efc;
1128f406ef7SJames Smart 	struct efc_node *node;
1138f406ef7SJames Smart 	int send_empty_event = false;
1148f406ef7SJames Smart 	unsigned long flags = 0;
1158f406ef7SJames Smart 
1168f406ef7SJames Smart 	node = els->node;
1178f406ef7SJames Smart 	efc = node->efc;
1188f406ef7SJames Smart 
1198f406ef7SJames Smart 	spin_lock_irqsave(&node->els_ios_lock, flags);
1208f406ef7SJames Smart 
1218f406ef7SJames Smart 	list_del(&els->list_entry);
1228f406ef7SJames Smart 	/* Send list empty event if the IO allocator
1238f406ef7SJames Smart 	 * is disabled, and the list is empty
1248f406ef7SJames Smart 	 * If node->els_io_enabled was not checked,
1258f406ef7SJames Smart 	 * the event would be posted continually
1268f406ef7SJames Smart 	 */
1278f406ef7SJames Smart 	send_empty_event = (!node->els_io_enabled &&
1288f406ef7SJames Smart 			   list_empty(&node->els_ios_list));
1298f406ef7SJames Smart 
1308f406ef7SJames Smart 	spin_unlock_irqrestore(&node->els_ios_lock, flags);
1318f406ef7SJames Smart 
1328f406ef7SJames Smart 	/* free ELS request and response buffers */
1338f406ef7SJames Smart 	dma_free_coherent(&efc->pci->dev, els->io.rsp.size,
1348f406ef7SJames Smart 			  els->io.rsp.virt, els->io.rsp.phys);
1358f406ef7SJames Smart 	dma_free_coherent(&efc->pci->dev, els->io.req.size,
1368f406ef7SJames Smart 			  els->io.req.virt, els->io.req.phys);
1378f406ef7SJames Smart 
1388f406ef7SJames Smart 	mempool_free(els, efc->els_io_pool);
1398f406ef7SJames Smart 
1408f406ef7SJames Smart 	if (send_empty_event)
1418f406ef7SJames Smart 		efc_scsi_io_list_empty(node->efc, node);
1428f406ef7SJames Smart }
1438f406ef7SJames Smart 
1448f406ef7SJames Smart static void
1458f406ef7SJames Smart efc_els_retry(struct efc_els_io_req *els);
1468f406ef7SJames Smart 
1478f406ef7SJames Smart static void
efc_els_delay_timer_cb(struct timer_list * t)1488f406ef7SJames Smart efc_els_delay_timer_cb(struct timer_list *t)
1498f406ef7SJames Smart {
1508f406ef7SJames Smart 	struct efc_els_io_req *els = from_timer(els, t, delay_timer);
1518f406ef7SJames Smart 
1528f406ef7SJames Smart 	/* Retry delay timer expired, retry the ELS request */
1538f406ef7SJames Smart 	efc_els_retry(els);
1548f406ef7SJames Smart }
1558f406ef7SJames Smart 
1568f406ef7SJames Smart static int
efc_els_req_cb(void * arg,u32 length,int status,u32 ext_status)1578f406ef7SJames Smart efc_els_req_cb(void *arg, u32 length, int status, u32 ext_status)
1588f406ef7SJames Smart {
1598f406ef7SJames Smart 	struct efc_els_io_req *els;
1608f406ef7SJames Smart 	struct efc_node *node;
1618f406ef7SJames Smart 	struct efc *efc;
1628f406ef7SJames Smart 	struct efc_node_cb cbdata;
1638f406ef7SJames Smart 	u32 reason_code;
1648f406ef7SJames Smart 
1658f406ef7SJames Smart 	els = arg;
1668f406ef7SJames Smart 	node = els->node;
1678f406ef7SJames Smart 	efc = node->efc;
1688f406ef7SJames Smart 
1698f406ef7SJames Smart 	if (status)
1708f406ef7SJames Smart 		els_io_printf(els, "status x%x ext x%x\n", status, ext_status);
1718f406ef7SJames Smart 
1728f406ef7SJames Smart 	/* set the response len element of els->rsp */
1738f406ef7SJames Smart 	els->io.rsp.len = length;
1748f406ef7SJames Smart 
1758f406ef7SJames Smart 	cbdata.status = status;
1768f406ef7SJames Smart 	cbdata.ext_status = ext_status;
1778f406ef7SJames Smart 	cbdata.header = NULL;
1788f406ef7SJames Smart 	cbdata.els_rsp = els->io.rsp;
1798f406ef7SJames Smart 
1808f406ef7SJames Smart 	/* set the response len element of els->rsp */
1818f406ef7SJames Smart 	cbdata.rsp_len = length;
1828f406ef7SJames Smart 
1838f406ef7SJames Smart 	/* FW returns the number of bytes received on the link in
1848f406ef7SJames Smart 	 * the WCQE, not the amount placed in the buffer; use this info to
1858f406ef7SJames Smart 	 * check if there was an overrun.
1868f406ef7SJames Smart 	 */
1878f406ef7SJames Smart 	if (length > els->io.rsp.size) {
1888f406ef7SJames Smart 		efc_log_warn(efc,
1898f406ef7SJames Smart 			     "ELS response returned len=%d > buflen=%zu\n",
1908f406ef7SJames Smart 			     length, els->io.rsp.size);
1918f406ef7SJames Smart 		efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_REQ_FAIL, &cbdata);
1928f406ef7SJames Smart 		return 0;
1938f406ef7SJames Smart 	}
1948f406ef7SJames Smart 
1958f406ef7SJames Smart 	/* Post event to ELS IO object */
1968f406ef7SJames Smart 	switch (status) {
1978f406ef7SJames Smart 	case SLI4_FC_WCQE_STATUS_SUCCESS:
1988f406ef7SJames Smart 		efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_REQ_OK, &cbdata);
1998f406ef7SJames Smart 		break;
2008f406ef7SJames Smart 
2018f406ef7SJames Smart 	case SLI4_FC_WCQE_STATUS_LS_RJT:
2028f406ef7SJames Smart 		reason_code = (ext_status >> 16) & 0xff;
2038f406ef7SJames Smart 
2048f406ef7SJames Smart 		/* delay and retry if reason code is Logical Busy */
2058f406ef7SJames Smart 		switch (reason_code) {
2068f406ef7SJames Smart 		case ELS_RJT_BUSY:
2078f406ef7SJames Smart 			els->node->els_req_cnt--;
2088f406ef7SJames Smart 			els_io_printf(els,
2098f406ef7SJames Smart 				      "LS_RJT Logical Busy, delay and retry\n");
2108f406ef7SJames Smart 			timer_setup(&els->delay_timer,
2118f406ef7SJames Smart 				    efc_els_delay_timer_cb, 0);
2128f406ef7SJames Smart 			mod_timer(&els->delay_timer,
2138f406ef7SJames Smart 				  jiffies + msecs_to_jiffies(5000));
2148f406ef7SJames Smart 			break;
2158f406ef7SJames Smart 		default:
2168f406ef7SJames Smart 			efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_REQ_RJT,
2178f406ef7SJames Smart 					   &cbdata);
2188f406ef7SJames Smart 			break;
2198f406ef7SJames Smart 		}
2208f406ef7SJames Smart 		break;
2218f406ef7SJames Smart 
2228f406ef7SJames Smart 	case SLI4_FC_WCQE_STATUS_LOCAL_REJECT:
2238f406ef7SJames Smart 		switch (ext_status) {
2248f406ef7SJames Smart 		case SLI4_FC_LOCAL_REJECT_SEQUENCE_TIMEOUT:
2258f406ef7SJames Smart 			efc_els_retry(els);
2268f406ef7SJames Smart 			break;
2278f406ef7SJames Smart 		default:
2288f406ef7SJames Smart 			efc_log_err(efc, "LOCAL_REJECT with ext status:%x\n",
2298f406ef7SJames Smart 				    ext_status);
2308f406ef7SJames Smart 			efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_REQ_FAIL,
2318f406ef7SJames Smart 					   &cbdata);
2328f406ef7SJames Smart 			break;
2338f406ef7SJames Smart 		}
2348f406ef7SJames Smart 		break;
2358f406ef7SJames Smart 	default:	/* Other error */
2368f406ef7SJames Smart 		efc_log_warn(efc, "els req failed status x%x, ext_status x%x\n",
2378f406ef7SJames Smart 			     status, ext_status);
2388f406ef7SJames Smart 		efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_REQ_FAIL, &cbdata);
2398f406ef7SJames Smart 		break;
2408f406ef7SJames Smart 	}
2418f406ef7SJames Smart 
2428f406ef7SJames Smart 	return 0;
2438f406ef7SJames Smart }
2448f406ef7SJames Smart 
efc_disc_io_complete(struct efc_disc_io * io,u32 len,u32 status,u32 ext_status)2458f406ef7SJames Smart void efc_disc_io_complete(struct efc_disc_io *io, u32 len, u32 status,
2468f406ef7SJames Smart 			  u32 ext_status)
2478f406ef7SJames Smart {
2488f406ef7SJames Smart 	struct efc_els_io_req *els =
2498f406ef7SJames Smart 				container_of(io, struct efc_els_io_req, io);
2508f406ef7SJames Smart 
2518f406ef7SJames Smart 	WARN_ON_ONCE(!els->cb);
2528f406ef7SJames Smart 
2538f406ef7SJames Smart 	((efc_hw_srrs_cb_t)els->cb) (els, len, status, ext_status);
2548f406ef7SJames Smart }
2558f406ef7SJames Smart 
efc_els_send_req(struct efc_node * node,struct efc_els_io_req * els,enum efc_disc_io_type io_type)2568f406ef7SJames Smart static int efc_els_send_req(struct efc_node *node, struct efc_els_io_req *els,
2578f406ef7SJames Smart 			    enum efc_disc_io_type io_type)
2588f406ef7SJames Smart {
2598f406ef7SJames Smart 	int rc = 0;
2608f406ef7SJames Smart 	struct efc *efc = node->efc;
2618f406ef7SJames Smart 	struct efc_node_cb cbdata;
2628f406ef7SJames Smart 
2638f406ef7SJames Smart 	/* update ELS request counter */
2648f406ef7SJames Smart 	els->node->els_req_cnt++;
2658f406ef7SJames Smart 
2668f406ef7SJames Smart 	/* Prepare the IO request details */
2678f406ef7SJames Smart 	els->io.io_type = io_type;
2688f406ef7SJames Smart 	els->io.xmit_len = els->io.req.size;
2698f406ef7SJames Smart 	els->io.rsp_len = els->io.rsp.size;
2708f406ef7SJames Smart 	els->io.rpi = node->rnode.indicator;
2718f406ef7SJames Smart 	els->io.vpi = node->nport->indicator;
2728f406ef7SJames Smart 	els->io.s_id = node->nport->fc_id;
2738f406ef7SJames Smart 	els->io.d_id = node->rnode.fc_id;
2748f406ef7SJames Smart 
2758f406ef7SJames Smart 	if (node->rnode.attached)
2768f406ef7SJames Smart 		els->io.rpi_registered = true;
2778f406ef7SJames Smart 
2788f406ef7SJames Smart 	els->cb = efc_els_req_cb;
2798f406ef7SJames Smart 
2808f406ef7SJames Smart 	rc = efc->tt.send_els(efc, &els->io);
2818f406ef7SJames Smart 	if (!rc)
2828f406ef7SJames Smart 		return rc;
2838f406ef7SJames Smart 
2848f406ef7SJames Smart 	cbdata.status = EFC_STATUS_INVALID;
2858f406ef7SJames Smart 	cbdata.ext_status = EFC_STATUS_INVALID;
2868f406ef7SJames Smart 	cbdata.els_rsp = els->io.rsp;
2878f406ef7SJames Smart 	efc_log_err(efc, "efc_els_send failed: %d\n", rc);
2888f406ef7SJames Smart 	efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_REQ_FAIL, &cbdata);
2898f406ef7SJames Smart 
2908f406ef7SJames Smart 	return rc;
2918f406ef7SJames Smart }
2928f406ef7SJames Smart 
2938f406ef7SJames Smart static void
efc_els_retry(struct efc_els_io_req * els)2948f406ef7SJames Smart efc_els_retry(struct efc_els_io_req *els)
2958f406ef7SJames Smart {
2968f406ef7SJames Smart 	struct efc *efc;
2978f406ef7SJames Smart 	struct efc_node_cb cbdata;
2988f406ef7SJames Smart 	u32 rc;
2998f406ef7SJames Smart 
3008f406ef7SJames Smart 	efc = els->node->efc;
3018f406ef7SJames Smart 	cbdata.status = EFC_STATUS_INVALID;
3028f406ef7SJames Smart 	cbdata.ext_status = EFC_STATUS_INVALID;
3038f406ef7SJames Smart 	cbdata.els_rsp = els->io.rsp;
3048f406ef7SJames Smart 
3058f406ef7SJames Smart 	if (els->els_retries_remaining) {
3068f406ef7SJames Smart 		els->els_retries_remaining--;
3078f406ef7SJames Smart 		rc = efc->tt.send_els(efc, &els->io);
3088f406ef7SJames Smart 	} else {
3098f406ef7SJames Smart 		rc = -EIO;
3108f406ef7SJames Smart 	}
3118f406ef7SJames Smart 
3128f406ef7SJames Smart 	if (rc) {
3138f406ef7SJames Smart 		efc_log_err(efc, "ELS retries exhausted\n");
3148f406ef7SJames Smart 		efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_REQ_FAIL, &cbdata);
3158f406ef7SJames Smart 	}
3168f406ef7SJames Smart }
3178f406ef7SJames Smart 
3188f406ef7SJames Smart static int
efc_els_acc_cb(void * arg,u32 length,int status,u32 ext_status)3198f406ef7SJames Smart efc_els_acc_cb(void *arg, u32 length, int status, u32 ext_status)
3208f406ef7SJames Smart {
3218f406ef7SJames Smart 	struct efc_els_io_req *els;
3228f406ef7SJames Smart 	struct efc_node *node;
3238f406ef7SJames Smart 	struct efc *efc;
3248f406ef7SJames Smart 	struct efc_node_cb cbdata;
3258f406ef7SJames Smart 
3268f406ef7SJames Smart 	els = arg;
3278f406ef7SJames Smart 	node = els->node;
3288f406ef7SJames Smart 	efc = node->efc;
3298f406ef7SJames Smart 
3308f406ef7SJames Smart 	cbdata.status = status;
3318f406ef7SJames Smart 	cbdata.ext_status = ext_status;
3328f406ef7SJames Smart 	cbdata.header = NULL;
3338f406ef7SJames Smart 	cbdata.els_rsp = els->io.rsp;
3348f406ef7SJames Smart 
3358f406ef7SJames Smart 	/* Post node event */
3368f406ef7SJames Smart 	switch (status) {
3378f406ef7SJames Smart 	case SLI4_FC_WCQE_STATUS_SUCCESS:
3388f406ef7SJames Smart 		efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_CMPL_OK, &cbdata);
3398f406ef7SJames Smart 		break;
3408f406ef7SJames Smart 
3418f406ef7SJames Smart 	default:	/* Other error */
3428f406ef7SJames Smart 		efc_log_warn(efc, "[%s] %-8s failed status x%x, ext x%x\n",
3438f406ef7SJames Smart 			     node->display_name, els->display_name,
3448f406ef7SJames Smart 			     status, ext_status);
3458f406ef7SJames Smart 		efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_CMPL_FAIL, &cbdata);
3468f406ef7SJames Smart 		break;
3478f406ef7SJames Smart 	}
3488f406ef7SJames Smart 
3498f406ef7SJames Smart 	return 0;
3508f406ef7SJames Smart }
3518f406ef7SJames Smart 
3528f406ef7SJames Smart static int
efc_els_send_rsp(struct efc_els_io_req * els,u32 rsplen)3538f406ef7SJames Smart efc_els_send_rsp(struct efc_els_io_req *els, u32 rsplen)
3548f406ef7SJames Smart {
3558f406ef7SJames Smart 	int rc = 0;
3568f406ef7SJames Smart 	struct efc_node_cb cbdata;
3578f406ef7SJames Smart 	struct efc_node *node = els->node;
3588f406ef7SJames Smart 	struct efc *efc = node->efc;
3598f406ef7SJames Smart 
3608f406ef7SJames Smart 	/* increment ELS completion counter */
3618f406ef7SJames Smart 	node->els_cmpl_cnt++;
3628f406ef7SJames Smart 
3638f406ef7SJames Smart 	els->io.io_type = EFC_DISC_IO_ELS_RESP;
3648f406ef7SJames Smart 	els->cb = efc_els_acc_cb;
3658f406ef7SJames Smart 
3668f406ef7SJames Smart 	/* Prepare the IO request details */
3678f406ef7SJames Smart 	els->io.xmit_len = rsplen;
3688f406ef7SJames Smart 	els->io.rsp_len = els->io.rsp.size;
3698f406ef7SJames Smart 	els->io.rpi = node->rnode.indicator;
3708f406ef7SJames Smart 	els->io.vpi = node->nport->indicator;
3718f406ef7SJames Smart 	if (node->nport->fc_id != U32_MAX)
3728f406ef7SJames Smart 		els->io.s_id = node->nport->fc_id;
3738f406ef7SJames Smart 	else
3748f406ef7SJames Smart 		els->io.s_id = els->io.iparam.els.s_id;
3758f406ef7SJames Smart 	els->io.d_id = node->rnode.fc_id;
3768f406ef7SJames Smart 
3778f406ef7SJames Smart 	if (node->attached)
3788f406ef7SJames Smart 		els->io.rpi_registered = true;
3798f406ef7SJames Smart 
3808f406ef7SJames Smart 	rc = efc->tt.send_els(efc, &els->io);
3818f406ef7SJames Smart 	if (!rc)
3828f406ef7SJames Smart 		return rc;
3838f406ef7SJames Smart 
3848f406ef7SJames Smart 	cbdata.status = EFC_STATUS_INVALID;
3858f406ef7SJames Smart 	cbdata.ext_status = EFC_STATUS_INVALID;
3868f406ef7SJames Smart 	cbdata.els_rsp = els->io.rsp;
3878f406ef7SJames Smart 	efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_CMPL_FAIL, &cbdata);
3888f406ef7SJames Smart 
3898f406ef7SJames Smart 	return rc;
3908f406ef7SJames Smart }
3918f406ef7SJames Smart 
3928f406ef7SJames Smart int
efc_send_plogi(struct efc_node * node)3938f406ef7SJames Smart efc_send_plogi(struct efc_node *node)
3948f406ef7SJames Smart {
3958f406ef7SJames Smart 	struct efc_els_io_req *els;
3968f406ef7SJames Smart 	struct efc *efc = node->efc;
3978f406ef7SJames Smart 	struct fc_els_flogi  *plogi;
3988f406ef7SJames Smart 
3998f406ef7SJames Smart 	node_els_trace();
4008f406ef7SJames Smart 
4018f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*plogi));
4028f406ef7SJames Smart 	if (!els) {
4038f406ef7SJames Smart 		efc_log_err(efc, "IO alloc failed\n");
4048f406ef7SJames Smart 		return -EIO;
4058f406ef7SJames Smart 	}
4068f406ef7SJames Smart 	els->display_name = "plogi";
4078f406ef7SJames Smart 
4088f406ef7SJames Smart 	/* Build PLOGI request */
4098f406ef7SJames Smart 	plogi = els->io.req.virt;
4108f406ef7SJames Smart 
4118f406ef7SJames Smart 	memcpy(plogi, node->nport->service_params, sizeof(*plogi));
4128f406ef7SJames Smart 
4138f406ef7SJames Smart 	plogi->fl_cmd = ELS_PLOGI;
4148f406ef7SJames Smart 	memset(plogi->_fl_resvd, 0, sizeof(plogi->_fl_resvd));
4158f406ef7SJames Smart 
4168f406ef7SJames Smart 	return efc_els_send_req(node, els, EFC_DISC_IO_ELS_REQ);
4178f406ef7SJames Smart }
4188f406ef7SJames Smart 
4198f406ef7SJames Smart int
efc_send_flogi(struct efc_node * node)4208f406ef7SJames Smart efc_send_flogi(struct efc_node *node)
4218f406ef7SJames Smart {
4228f406ef7SJames Smart 	struct efc_els_io_req *els;
4238f406ef7SJames Smart 	struct efc *efc;
4248f406ef7SJames Smart 	struct fc_els_flogi  *flogi;
4258f406ef7SJames Smart 
4268f406ef7SJames Smart 	efc = node->efc;
4278f406ef7SJames Smart 
4288f406ef7SJames Smart 	node_els_trace();
4298f406ef7SJames Smart 
4308f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*flogi));
4318f406ef7SJames Smart 	if (!els) {
4328f406ef7SJames Smart 		efc_log_err(efc, "IO alloc failed\n");
4338f406ef7SJames Smart 		return -EIO;
4348f406ef7SJames Smart 	}
4358f406ef7SJames Smart 
4368f406ef7SJames Smart 	els->display_name = "flogi";
4378f406ef7SJames Smart 
4388f406ef7SJames Smart 	/* Build FLOGI request */
4398f406ef7SJames Smart 	flogi = els->io.req.virt;
4408f406ef7SJames Smart 
4418f406ef7SJames Smart 	memcpy(flogi, node->nport->service_params, sizeof(*flogi));
4428f406ef7SJames Smart 	flogi->fl_cmd = ELS_FLOGI;
4438f406ef7SJames Smart 	memset(flogi->_fl_resvd, 0, sizeof(flogi->_fl_resvd));
4448f406ef7SJames Smart 
4458f406ef7SJames Smart 	return efc_els_send_req(node, els, EFC_DISC_IO_ELS_REQ);
4468f406ef7SJames Smart }
4478f406ef7SJames Smart 
4488f406ef7SJames Smart int
efc_send_fdisc(struct efc_node * node)4498f406ef7SJames Smart efc_send_fdisc(struct efc_node *node)
4508f406ef7SJames Smart {
4518f406ef7SJames Smart 	struct efc_els_io_req *els;
4528f406ef7SJames Smart 	struct efc *efc;
4538f406ef7SJames Smart 	struct fc_els_flogi *fdisc;
4548f406ef7SJames Smart 
4558f406ef7SJames Smart 	efc = node->efc;
4568f406ef7SJames Smart 
4578f406ef7SJames Smart 	node_els_trace();
4588f406ef7SJames Smart 
4598f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*fdisc));
4608f406ef7SJames Smart 	if (!els) {
4618f406ef7SJames Smart 		efc_log_err(efc, "IO alloc failed\n");
4628f406ef7SJames Smart 		return -EIO;
4638f406ef7SJames Smart 	}
4648f406ef7SJames Smart 
4658f406ef7SJames Smart 	els->display_name = "fdisc";
4668f406ef7SJames Smart 
4678f406ef7SJames Smart 	/* Build FDISC request */
4688f406ef7SJames Smart 	fdisc = els->io.req.virt;
4698f406ef7SJames Smart 
4708f406ef7SJames Smart 	memcpy(fdisc, node->nport->service_params, sizeof(*fdisc));
4718f406ef7SJames Smart 	fdisc->fl_cmd = ELS_FDISC;
4728f406ef7SJames Smart 	memset(fdisc->_fl_resvd, 0, sizeof(fdisc->_fl_resvd));
4738f406ef7SJames Smart 
4748f406ef7SJames Smart 	return efc_els_send_req(node, els, EFC_DISC_IO_ELS_REQ);
4758f406ef7SJames Smart }
4768f406ef7SJames Smart 
4778f406ef7SJames Smart int
efc_send_prli(struct efc_node * node)4788f406ef7SJames Smart efc_send_prli(struct efc_node *node)
4798f406ef7SJames Smart {
4808f406ef7SJames Smart 	struct efc *efc = node->efc;
4818f406ef7SJames Smart 	struct efc_els_io_req *els;
4828f406ef7SJames Smart 	struct {
4838f406ef7SJames Smart 		struct fc_els_prli prli;
4848f406ef7SJames Smart 		struct fc_els_spp spp;
4858f406ef7SJames Smart 	} *pp;
4868f406ef7SJames Smart 
4878f406ef7SJames Smart 	node_els_trace();
4888f406ef7SJames Smart 
4898f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*pp));
4908f406ef7SJames Smart 	if (!els) {
4918f406ef7SJames Smart 		efc_log_err(efc, "IO alloc failed\n");
4928f406ef7SJames Smart 		return -EIO;
4938f406ef7SJames Smart 	}
4948f406ef7SJames Smart 
4958f406ef7SJames Smart 	els->display_name = "prli";
4968f406ef7SJames Smart 
4978f406ef7SJames Smart 	/* Build PRLI request */
4988f406ef7SJames Smart 	pp = els->io.req.virt;
4998f406ef7SJames Smart 
5008f406ef7SJames Smart 	memset(pp, 0, sizeof(*pp));
5018f406ef7SJames Smart 
5028f406ef7SJames Smart 	pp->prli.prli_cmd = ELS_PRLI;
5038f406ef7SJames Smart 	pp->prli.prli_spp_len = 16;
5048f406ef7SJames Smart 	pp->prli.prli_len = cpu_to_be16(sizeof(*pp));
5058f406ef7SJames Smart 	pp->spp.spp_type = FC_TYPE_FCP;
5068f406ef7SJames Smart 	pp->spp.spp_type_ext = 0;
5078f406ef7SJames Smart 	pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR;
5088f406ef7SJames Smart 	pp->spp.spp_params = cpu_to_be32(FCP_SPPF_RD_XRDY_DIS |
5098f406ef7SJames Smart 			       (node->nport->enable_ini ?
5108f406ef7SJames Smart 			       FCP_SPPF_INIT_FCN : 0) |
5118f406ef7SJames Smart 			       (node->nport->enable_tgt ?
5128f406ef7SJames Smart 			       FCP_SPPF_TARG_FCN : 0));
5138f406ef7SJames Smart 
5148f406ef7SJames Smart 	return efc_els_send_req(node, els, EFC_DISC_IO_ELS_REQ);
5158f406ef7SJames Smart }
5168f406ef7SJames Smart 
5178f406ef7SJames Smart int
efc_send_logo(struct efc_node * node)5188f406ef7SJames Smart efc_send_logo(struct efc_node *node)
5198f406ef7SJames Smart {
5208f406ef7SJames Smart 	struct efc *efc = node->efc;
5218f406ef7SJames Smart 	struct efc_els_io_req *els;
5228f406ef7SJames Smart 	struct fc_els_logo *logo;
5238f406ef7SJames Smart 	struct fc_els_flogi  *sparams;
5248f406ef7SJames Smart 
5258f406ef7SJames Smart 	node_els_trace();
5268f406ef7SJames Smart 
5278f406ef7SJames Smart 	sparams = (struct fc_els_flogi *)node->nport->service_params;
5288f406ef7SJames Smart 
5298f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*logo));
5308f406ef7SJames Smart 	if (!els) {
5318f406ef7SJames Smart 		efc_log_err(efc, "IO alloc failed\n");
5328f406ef7SJames Smart 		return -EIO;
5338f406ef7SJames Smart 	}
5348f406ef7SJames Smart 
5358f406ef7SJames Smart 	els->display_name = "logo";
5368f406ef7SJames Smart 
5378f406ef7SJames Smart 	/* Build LOGO request */
5388f406ef7SJames Smart 
5398f406ef7SJames Smart 	logo = els->io.req.virt;
5408f406ef7SJames Smart 
5418f406ef7SJames Smart 	memset(logo, 0, sizeof(*logo));
5428f406ef7SJames Smart 	logo->fl_cmd = ELS_LOGO;
5438f406ef7SJames Smart 	hton24(logo->fl_n_port_id, node->rnode.nport->fc_id);
5448f406ef7SJames Smart 	logo->fl_n_port_wwn = sparams->fl_wwpn;
5458f406ef7SJames Smart 
5468f406ef7SJames Smart 	return efc_els_send_req(node, els, EFC_DISC_IO_ELS_REQ);
5478f406ef7SJames Smart }
5488f406ef7SJames Smart 
5498f406ef7SJames Smart int
efc_send_adisc(struct efc_node * node)5508f406ef7SJames Smart efc_send_adisc(struct efc_node *node)
5518f406ef7SJames Smart {
5528f406ef7SJames Smart 	struct efc *efc = node->efc;
5538f406ef7SJames Smart 	struct efc_els_io_req *els;
5548f406ef7SJames Smart 	struct fc_els_adisc *adisc;
5558f406ef7SJames Smart 	struct fc_els_flogi  *sparams;
5568f406ef7SJames Smart 	struct efc_nport *nport = node->nport;
5578f406ef7SJames Smart 
5588f406ef7SJames Smart 	node_els_trace();
5598f406ef7SJames Smart 
5608f406ef7SJames Smart 	sparams = (struct fc_els_flogi *)node->nport->service_params;
5618f406ef7SJames Smart 
5628f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*adisc));
5638f406ef7SJames Smart 	if (!els) {
5648f406ef7SJames Smart 		efc_log_err(efc, "IO alloc failed\n");
5658f406ef7SJames Smart 		return -EIO;
5668f406ef7SJames Smart 	}
5678f406ef7SJames Smart 
5688f406ef7SJames Smart 	els->display_name = "adisc";
5698f406ef7SJames Smart 
5708f406ef7SJames Smart 	/* Build ADISC request */
5718f406ef7SJames Smart 
5728f406ef7SJames Smart 	adisc = els->io.req.virt;
5738f406ef7SJames Smart 
5748f406ef7SJames Smart 	memset(adisc, 0, sizeof(*adisc));
5758f406ef7SJames Smart 	adisc->adisc_cmd = ELS_ADISC;
5768f406ef7SJames Smart 	hton24(adisc->adisc_hard_addr, nport->fc_id);
5778f406ef7SJames Smart 	adisc->adisc_wwpn = sparams->fl_wwpn;
5788f406ef7SJames Smart 	adisc->adisc_wwnn = sparams->fl_wwnn;
5798f406ef7SJames Smart 	hton24(adisc->adisc_port_id, node->rnode.nport->fc_id);
5808f406ef7SJames Smart 
5818f406ef7SJames Smart 	return efc_els_send_req(node, els, EFC_DISC_IO_ELS_REQ);
5828f406ef7SJames Smart }
5838f406ef7SJames Smart 
5848f406ef7SJames Smart int
efc_send_scr(struct efc_node * node)5858f406ef7SJames Smart efc_send_scr(struct efc_node *node)
5868f406ef7SJames Smart {
5878f406ef7SJames Smart 	struct efc_els_io_req *els;
5888f406ef7SJames Smart 	struct efc *efc = node->efc;
5898f406ef7SJames Smart 	struct fc_els_scr *req;
5908f406ef7SJames Smart 
5918f406ef7SJames Smart 	node_els_trace();
5928f406ef7SJames Smart 
5938f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*req));
5948f406ef7SJames Smart 	if (!els) {
5958f406ef7SJames Smart 		efc_log_err(efc, "IO alloc failed\n");
5968f406ef7SJames Smart 		return -EIO;
5978f406ef7SJames Smart 	}
5988f406ef7SJames Smart 
5998f406ef7SJames Smart 	els->display_name = "scr";
6008f406ef7SJames Smart 
6018f406ef7SJames Smart 	req = els->io.req.virt;
6028f406ef7SJames Smart 
6038f406ef7SJames Smart 	memset(req, 0, sizeof(*req));
6048f406ef7SJames Smart 	req->scr_cmd = ELS_SCR;
6058f406ef7SJames Smart 	req->scr_reg_func = ELS_SCRF_FULL;
6068f406ef7SJames Smart 
6078f406ef7SJames Smart 	return efc_els_send_req(node, els, EFC_DISC_IO_ELS_REQ);
6088f406ef7SJames Smart }
6098f406ef7SJames Smart 
6108f406ef7SJames Smart int
efc_send_ls_rjt(struct efc_node * node,u32 ox_id,u32 reason_code,u32 reason_code_expl,u32 vendor_unique)6118f406ef7SJames Smart efc_send_ls_rjt(struct efc_node *node, u32 ox_id, u32 reason_code,
6128f406ef7SJames Smart 		u32 reason_code_expl, u32 vendor_unique)
6138f406ef7SJames Smart {
6148f406ef7SJames Smart 	struct efc *efc = node->efc;
6158f406ef7SJames Smart 	struct efc_els_io_req *els = NULL;
6168f406ef7SJames Smart 	struct fc_els_ls_rjt *rjt;
6178f406ef7SJames Smart 
6188f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*rjt));
6198f406ef7SJames Smart 	if (!els) {
6208f406ef7SJames Smart 		efc_log_err(efc, "els IO alloc failed\n");
6218f406ef7SJames Smart 		return -EIO;
6228f406ef7SJames Smart 	}
6238f406ef7SJames Smart 
6248f406ef7SJames Smart 	node_els_trace();
6258f406ef7SJames Smart 
6268f406ef7SJames Smart 	els->display_name = "ls_rjt";
6278f406ef7SJames Smart 
6288f406ef7SJames Smart 	memset(&els->io.iparam, 0, sizeof(els->io.iparam));
6298f406ef7SJames Smart 	els->io.iparam.els.ox_id = ox_id;
6308f406ef7SJames Smart 
6318f406ef7SJames Smart 	rjt = els->io.req.virt;
6328f406ef7SJames Smart 	memset(rjt, 0, sizeof(*rjt));
6338f406ef7SJames Smart 
6348f406ef7SJames Smart 	rjt->er_cmd = ELS_LS_RJT;
6358f406ef7SJames Smart 	rjt->er_reason = reason_code;
6368f406ef7SJames Smart 	rjt->er_explan = reason_code_expl;
6378f406ef7SJames Smart 
6388f406ef7SJames Smart 	return efc_els_send_rsp(els, sizeof(*rjt));
6398f406ef7SJames Smart }
6408f406ef7SJames Smart 
6418f406ef7SJames Smart int
efc_send_plogi_acc(struct efc_node * node,u32 ox_id)6428f406ef7SJames Smart efc_send_plogi_acc(struct efc_node *node, u32 ox_id)
6438f406ef7SJames Smart {
6448f406ef7SJames Smart 	struct efc *efc = node->efc;
6458f406ef7SJames Smart 	struct efc_els_io_req *els = NULL;
6468f406ef7SJames Smart 	struct fc_els_flogi  *plogi;
6478f406ef7SJames Smart 	struct fc_els_flogi  *req = (struct fc_els_flogi *)node->service_params;
6488f406ef7SJames Smart 
6498f406ef7SJames Smart 	node_els_trace();
6508f406ef7SJames Smart 
6518f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*plogi));
6528f406ef7SJames Smart 	if (!els) {
6538f406ef7SJames Smart 		efc_log_err(efc, "els IO alloc failed\n");
6548f406ef7SJames Smart 		return -EIO;
6558f406ef7SJames Smart 	}
6568f406ef7SJames Smart 
6578f406ef7SJames Smart 	els->display_name = "plogi_acc";
6588f406ef7SJames Smart 
6598f406ef7SJames Smart 	memset(&els->io.iparam, 0, sizeof(els->io.iparam));
6608f406ef7SJames Smart 	els->io.iparam.els.ox_id = ox_id;
6618f406ef7SJames Smart 
6628f406ef7SJames Smart 	plogi = els->io.req.virt;
6638f406ef7SJames Smart 
6648f406ef7SJames Smart 	/* copy our port's service parameters to payload */
6658f406ef7SJames Smart 	memcpy(plogi, node->nport->service_params, sizeof(*plogi));
6668f406ef7SJames Smart 	plogi->fl_cmd = ELS_LS_ACC;
6678f406ef7SJames Smart 	memset(plogi->_fl_resvd, 0, sizeof(plogi->_fl_resvd));
6688f406ef7SJames Smart 
6698f406ef7SJames Smart 	/* Set Application header support bit if requested */
6708f406ef7SJames Smart 	if (req->fl_csp.sp_features & cpu_to_be16(FC_SP_FT_BCAST))
6718f406ef7SJames Smart 		plogi->fl_csp.sp_features |= cpu_to_be16(FC_SP_FT_BCAST);
6728f406ef7SJames Smart 
6738f406ef7SJames Smart 	return efc_els_send_rsp(els, sizeof(*plogi));
6748f406ef7SJames Smart }
6758f406ef7SJames Smart 
6768f406ef7SJames Smart int
efc_send_flogi_p2p_acc(struct efc_node * node,u32 ox_id,u32 s_id)6778f406ef7SJames Smart efc_send_flogi_p2p_acc(struct efc_node *node, u32 ox_id, u32 s_id)
6788f406ef7SJames Smart {
6798f406ef7SJames Smart 	struct efc *efc = node->efc;
6808f406ef7SJames Smart 	struct efc_els_io_req *els = NULL;
6818f406ef7SJames Smart 	struct fc_els_flogi  *flogi;
6828f406ef7SJames Smart 
6838f406ef7SJames Smart 	node_els_trace();
6848f406ef7SJames Smart 
6858f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*flogi));
6868f406ef7SJames Smart 	if (!els) {
6878f406ef7SJames Smart 		efc_log_err(efc, "els IO alloc failed\n");
6888f406ef7SJames Smart 		return -EIO;
6898f406ef7SJames Smart 	}
6908f406ef7SJames Smart 
6918f406ef7SJames Smart 	els->display_name = "flogi_p2p_acc";
6928f406ef7SJames Smart 
6938f406ef7SJames Smart 	memset(&els->io.iparam, 0, sizeof(els->io.iparam));
6948f406ef7SJames Smart 	els->io.iparam.els.ox_id = ox_id;
6958f406ef7SJames Smart 	els->io.iparam.els.s_id = s_id;
6968f406ef7SJames Smart 
6978f406ef7SJames Smart 	flogi = els->io.req.virt;
6988f406ef7SJames Smart 
6998f406ef7SJames Smart 	/* copy our port's service parameters to payload */
7008f406ef7SJames Smart 	memcpy(flogi, node->nport->service_params, sizeof(*flogi));
7018f406ef7SJames Smart 	flogi->fl_cmd = ELS_LS_ACC;
7028f406ef7SJames Smart 	memset(flogi->_fl_resvd, 0, sizeof(flogi->_fl_resvd));
7038f406ef7SJames Smart 
7048f406ef7SJames Smart 	memset(flogi->fl_cssp, 0, sizeof(flogi->fl_cssp));
7058f406ef7SJames Smart 
7068f406ef7SJames Smart 	return efc_els_send_rsp(els, sizeof(*flogi));
7078f406ef7SJames Smart }
7088f406ef7SJames Smart 
7098f406ef7SJames Smart int
efc_send_prli_acc(struct efc_node * node,u32 ox_id)7108f406ef7SJames Smart efc_send_prli_acc(struct efc_node *node, u32 ox_id)
7118f406ef7SJames Smart {
7128f406ef7SJames Smart 	struct efc *efc = node->efc;
7138f406ef7SJames Smart 	struct efc_els_io_req *els = NULL;
7148f406ef7SJames Smart 	struct {
7158f406ef7SJames Smart 		struct fc_els_prli prli;
7168f406ef7SJames Smart 		struct fc_els_spp spp;
7178f406ef7SJames Smart 	} *pp;
7188f406ef7SJames Smart 
7198f406ef7SJames Smart 	node_els_trace();
7208f406ef7SJames Smart 
7218f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*pp));
7228f406ef7SJames Smart 	if (!els) {
7238f406ef7SJames Smart 		efc_log_err(efc, "els IO alloc failed\n");
7248f406ef7SJames Smart 		return -EIO;
7258f406ef7SJames Smart 	}
7268f406ef7SJames Smart 
7278f406ef7SJames Smart 	els->display_name = "prli_acc";
7288f406ef7SJames Smart 
7298f406ef7SJames Smart 	memset(&els->io.iparam, 0, sizeof(els->io.iparam));
7308f406ef7SJames Smart 	els->io.iparam.els.ox_id = ox_id;
7318f406ef7SJames Smart 
7328f406ef7SJames Smart 	pp = els->io.req.virt;
7338f406ef7SJames Smart 	memset(pp, 0, sizeof(*pp));
7348f406ef7SJames Smart 
7358f406ef7SJames Smart 	pp->prli.prli_cmd = ELS_LS_ACC;
7368f406ef7SJames Smart 	pp->prli.prli_spp_len = 0x10;
7378f406ef7SJames Smart 	pp->prli.prli_len = cpu_to_be16(sizeof(*pp));
7388f406ef7SJames Smart 	pp->spp.spp_type = FC_TYPE_FCP;
7398f406ef7SJames Smart 	pp->spp.spp_type_ext = 0;
7408f406ef7SJames Smart 	pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR | FC_SPP_RESP_ACK;
7418f406ef7SJames Smart 
7428f406ef7SJames Smart 	pp->spp.spp_params = cpu_to_be32(FCP_SPPF_RD_XRDY_DIS |
7438f406ef7SJames Smart 					(node->nport->enable_ini ?
7448f406ef7SJames Smart 					 FCP_SPPF_INIT_FCN : 0) |
7458f406ef7SJames Smart 					(node->nport->enable_tgt ?
7468f406ef7SJames Smart 					 FCP_SPPF_TARG_FCN : 0));
7478f406ef7SJames Smart 
7488f406ef7SJames Smart 	return efc_els_send_rsp(els, sizeof(*pp));
7498f406ef7SJames Smart }
7508f406ef7SJames Smart 
7518f406ef7SJames Smart int
efc_send_prlo_acc(struct efc_node * node,u32 ox_id)7528f406ef7SJames Smart efc_send_prlo_acc(struct efc_node *node, u32 ox_id)
7538f406ef7SJames Smart {
7548f406ef7SJames Smart 	struct efc *efc = node->efc;
7558f406ef7SJames Smart 	struct efc_els_io_req *els = NULL;
7568f406ef7SJames Smart 	struct {
7578f406ef7SJames Smart 		struct fc_els_prlo prlo;
7588f406ef7SJames Smart 		struct fc_els_spp spp;
7598f406ef7SJames Smart 	} *pp;
7608f406ef7SJames Smart 
7618f406ef7SJames Smart 	node_els_trace();
7628f406ef7SJames Smart 
7638f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*pp));
7648f406ef7SJames Smart 	if (!els) {
7658f406ef7SJames Smart 		efc_log_err(efc, "els IO alloc failed\n");
7668f406ef7SJames Smart 		return -EIO;
7678f406ef7SJames Smart 	}
7688f406ef7SJames Smart 
7698f406ef7SJames Smart 	els->display_name = "prlo_acc";
7708f406ef7SJames Smart 
7718f406ef7SJames Smart 	memset(&els->io.iparam, 0, sizeof(els->io.iparam));
7728f406ef7SJames Smart 	els->io.iparam.els.ox_id = ox_id;
7738f406ef7SJames Smart 
7748f406ef7SJames Smart 	pp = els->io.req.virt;
7758f406ef7SJames Smart 	memset(pp, 0, sizeof(*pp));
7768f406ef7SJames Smart 	pp->prlo.prlo_cmd = ELS_LS_ACC;
7778f406ef7SJames Smart 	pp->prlo.prlo_obs = 0x10;
7788f406ef7SJames Smart 	pp->prlo.prlo_len = cpu_to_be16(sizeof(*pp));
7798f406ef7SJames Smart 
7808f406ef7SJames Smart 	pp->spp.spp_type = FC_TYPE_FCP;
7818f406ef7SJames Smart 	pp->spp.spp_type_ext = 0;
7828f406ef7SJames Smart 	pp->spp.spp_flags = FC_SPP_RESP_ACK;
7838f406ef7SJames Smart 
7848f406ef7SJames Smart 	return efc_els_send_rsp(els, sizeof(*pp));
7858f406ef7SJames Smart }
7868f406ef7SJames Smart 
7878f406ef7SJames Smart int
efc_send_ls_acc(struct efc_node * node,u32 ox_id)7888f406ef7SJames Smart efc_send_ls_acc(struct efc_node *node, u32 ox_id)
7898f406ef7SJames Smart {
7908f406ef7SJames Smart 	struct efc *efc = node->efc;
7918f406ef7SJames Smart 	struct efc_els_io_req *els = NULL;
7928f406ef7SJames Smart 	struct fc_els_ls_acc *acc;
7938f406ef7SJames Smart 
7948f406ef7SJames Smart 	node_els_trace();
7958f406ef7SJames Smart 
7968f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*acc));
7978f406ef7SJames Smart 	if (!els) {
7988f406ef7SJames Smart 		efc_log_err(efc, "els IO alloc failed\n");
7998f406ef7SJames Smart 		return -EIO;
8008f406ef7SJames Smart 	}
8018f406ef7SJames Smart 
8028f406ef7SJames Smart 	els->display_name = "ls_acc";
8038f406ef7SJames Smart 
8048f406ef7SJames Smart 	memset(&els->io.iparam, 0, sizeof(els->io.iparam));
8058f406ef7SJames Smart 	els->io.iparam.els.ox_id = ox_id;
8068f406ef7SJames Smart 
8078f406ef7SJames Smart 	acc = els->io.req.virt;
8088f406ef7SJames Smart 	memset(acc, 0, sizeof(*acc));
8098f406ef7SJames Smart 
8108f406ef7SJames Smart 	acc->la_cmd = ELS_LS_ACC;
8118f406ef7SJames Smart 
8128f406ef7SJames Smart 	return efc_els_send_rsp(els, sizeof(*acc));
8138f406ef7SJames Smart }
8148f406ef7SJames Smart 
8158f406ef7SJames Smart int
efc_send_logo_acc(struct efc_node * node,u32 ox_id)8168f406ef7SJames Smart efc_send_logo_acc(struct efc_node *node, u32 ox_id)
8178f406ef7SJames Smart {
8188f406ef7SJames Smart 	struct efc_els_io_req *els = NULL;
8198f406ef7SJames Smart 	struct efc *efc = node->efc;
8208f406ef7SJames Smart 	struct fc_els_ls_acc *logo;
8218f406ef7SJames Smart 
8228f406ef7SJames Smart 	node_els_trace();
8238f406ef7SJames Smart 
8248f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*logo));
8258f406ef7SJames Smart 	if (!els) {
8268f406ef7SJames Smart 		efc_log_err(efc, "els IO alloc failed\n");
8278f406ef7SJames Smart 		return -EIO;
8288f406ef7SJames Smart 	}
8298f406ef7SJames Smart 
8308f406ef7SJames Smart 	els->display_name = "logo_acc";
8318f406ef7SJames Smart 
8328f406ef7SJames Smart 	memset(&els->io.iparam, 0, sizeof(els->io.iparam));
8338f406ef7SJames Smart 	els->io.iparam.els.ox_id = ox_id;
8348f406ef7SJames Smart 
8358f406ef7SJames Smart 	logo = els->io.req.virt;
8368f406ef7SJames Smart 	memset(logo, 0, sizeof(*logo));
8378f406ef7SJames Smart 
8388f406ef7SJames Smart 	logo->la_cmd = ELS_LS_ACC;
8398f406ef7SJames Smart 
8408f406ef7SJames Smart 	return efc_els_send_rsp(els, sizeof(*logo));
8418f406ef7SJames Smart }
8428f406ef7SJames Smart 
8438f406ef7SJames Smart int
efc_send_adisc_acc(struct efc_node * node,u32 ox_id)8448f406ef7SJames Smart efc_send_adisc_acc(struct efc_node *node, u32 ox_id)
8458f406ef7SJames Smart {
8468f406ef7SJames Smart 	struct efc *efc = node->efc;
8478f406ef7SJames Smart 	struct efc_els_io_req *els = NULL;
8488f406ef7SJames Smart 	struct fc_els_adisc *adisc;
8498f406ef7SJames Smart 	struct fc_els_flogi  *sparams;
8508f406ef7SJames Smart 
8518f406ef7SJames Smart 	node_els_trace();
8528f406ef7SJames Smart 
8538f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*adisc));
8548f406ef7SJames Smart 	if (!els) {
8558f406ef7SJames Smart 		efc_log_err(efc, "els IO alloc failed\n");
8568f406ef7SJames Smart 		return -EIO;
8578f406ef7SJames Smart 	}
8588f406ef7SJames Smart 
8598f406ef7SJames Smart 	els->display_name = "adisc_acc";
8608f406ef7SJames Smart 
8618f406ef7SJames Smart 	/* Go ahead and send the ELS_ACC */
8628f406ef7SJames Smart 	memset(&els->io.iparam, 0, sizeof(els->io.iparam));
8638f406ef7SJames Smart 	els->io.iparam.els.ox_id = ox_id;
8648f406ef7SJames Smart 
8658f406ef7SJames Smart 	sparams = (struct fc_els_flogi  *)node->nport->service_params;
8668f406ef7SJames Smart 	adisc = els->io.req.virt;
8678f406ef7SJames Smart 	memset(adisc, 0, sizeof(*adisc));
8688f406ef7SJames Smart 	adisc->adisc_cmd = ELS_LS_ACC;
8698f406ef7SJames Smart 	adisc->adisc_wwpn = sparams->fl_wwpn;
8708f406ef7SJames Smart 	adisc->adisc_wwnn = sparams->fl_wwnn;
8718f406ef7SJames Smart 	hton24(adisc->adisc_port_id, node->rnode.nport->fc_id);
8728f406ef7SJames Smart 
8738f406ef7SJames Smart 	return efc_els_send_rsp(els, sizeof(*adisc));
8748f406ef7SJames Smart }
8758f406ef7SJames Smart 
8768f406ef7SJames Smart static inline void
fcct_build_req_header(struct fc_ct_hdr * hdr,u16 cmd,u16 max_size)8778f406ef7SJames Smart fcct_build_req_header(struct fc_ct_hdr  *hdr, u16 cmd, u16 max_size)
8788f406ef7SJames Smart {
8798f406ef7SJames Smart 	hdr->ct_rev = FC_CT_REV;
8808f406ef7SJames Smart 	hdr->ct_fs_type = FC_FST_DIR;
8818f406ef7SJames Smart 	hdr->ct_fs_subtype = FC_NS_SUBTYPE;
8828f406ef7SJames Smart 	hdr->ct_options = 0;
8838f406ef7SJames Smart 	hdr->ct_cmd = cpu_to_be16(cmd);
8848f406ef7SJames Smart 	/* words */
8858f406ef7SJames Smart 	hdr->ct_mr_size = cpu_to_be16(max_size / (sizeof(u32)));
8868f406ef7SJames Smart 	hdr->ct_reason = 0;
8878f406ef7SJames Smart 	hdr->ct_explan = 0;
8888f406ef7SJames Smart 	hdr->ct_vendor = 0;
8898f406ef7SJames Smart }
8908f406ef7SJames Smart 
8918f406ef7SJames Smart int
efc_ns_send_rftid(struct efc_node * node)8928f406ef7SJames Smart efc_ns_send_rftid(struct efc_node *node)
8938f406ef7SJames Smart {
8948f406ef7SJames Smart 	struct efc *efc = node->efc;
8958f406ef7SJames Smart 	struct efc_els_io_req *els;
8968f406ef7SJames Smart 	struct {
8978f406ef7SJames Smart 		struct fc_ct_hdr hdr;
8988f406ef7SJames Smart 		struct fc_ns_rft_id rftid;
8998f406ef7SJames Smart 	} *ct;
9008f406ef7SJames Smart 
9018f406ef7SJames Smart 	node_els_trace();
9028f406ef7SJames Smart 
9038f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*ct));
9048f406ef7SJames Smart 	if (!els) {
9058f406ef7SJames Smart 		efc_log_err(efc, "IO alloc failed\n");
9068f406ef7SJames Smart 		return -EIO;
9078f406ef7SJames Smart 	}
9088f406ef7SJames Smart 
9098f406ef7SJames Smart 	els->io.iparam.ct.r_ctl = FC_RCTL_ELS_REQ;
9108f406ef7SJames Smart 	els->io.iparam.ct.type = FC_TYPE_CT;
9118f406ef7SJames Smart 	els->io.iparam.ct.df_ctl = 0;
9128f406ef7SJames Smart 	els->io.iparam.ct.timeout = EFC_FC_ELS_SEND_DEFAULT_TIMEOUT;
9138f406ef7SJames Smart 
9148f406ef7SJames Smart 	els->display_name = "rftid";
9158f406ef7SJames Smart 
9168f406ef7SJames Smart 	ct = els->io.req.virt;
9178f406ef7SJames Smart 	memset(ct, 0, sizeof(*ct));
9188f406ef7SJames Smart 	fcct_build_req_header(&ct->hdr, FC_NS_RFT_ID,
9198f406ef7SJames Smart 			      sizeof(struct fc_ns_rft_id));
9208f406ef7SJames Smart 
9218f406ef7SJames Smart 	hton24(ct->rftid.fr_fid.fp_fid, node->rnode.nport->fc_id);
9228f406ef7SJames Smart 	ct->rftid.fr_fts.ff_type_map[FC_TYPE_FCP / FC_NS_BPW] =
9238f406ef7SJames Smart 		cpu_to_be32(1 << (FC_TYPE_FCP % FC_NS_BPW));
9248f406ef7SJames Smart 
9258f406ef7SJames Smart 	return efc_els_send_req(node, els, EFC_DISC_IO_CT_REQ);
9268f406ef7SJames Smart }
9278f406ef7SJames Smart 
9288f406ef7SJames Smart int
efc_ns_send_rffid(struct efc_node * node)9298f406ef7SJames Smart efc_ns_send_rffid(struct efc_node *node)
9308f406ef7SJames Smart {
9318f406ef7SJames Smart 	struct efc *efc = node->efc;
9328f406ef7SJames Smart 	struct efc_els_io_req *els;
9338f406ef7SJames Smart 	struct {
9348f406ef7SJames Smart 		struct fc_ct_hdr hdr;
9358f406ef7SJames Smart 		struct fc_ns_rff_id rffid;
9368f406ef7SJames Smart 	} *ct;
9378f406ef7SJames Smart 
9388f406ef7SJames Smart 	node_els_trace();
9398f406ef7SJames Smart 
9408f406ef7SJames Smart 	els = efc_els_io_alloc(node, sizeof(*ct));
9418f406ef7SJames Smart 	if (!els) {
9428f406ef7SJames Smart 		efc_log_err(efc, "IO alloc failed\n");
9438f406ef7SJames Smart 		return -EIO;
9448f406ef7SJames Smart 	}
9458f406ef7SJames Smart 
9468f406ef7SJames Smart 	els->io.iparam.ct.r_ctl = FC_RCTL_ELS_REQ;
9478f406ef7SJames Smart 	els->io.iparam.ct.type = FC_TYPE_CT;
9488f406ef7SJames Smart 	els->io.iparam.ct.df_ctl = 0;
9498f406ef7SJames Smart 	els->io.iparam.ct.timeout = EFC_FC_ELS_SEND_DEFAULT_TIMEOUT;
9508f406ef7SJames Smart 
9518f406ef7SJames Smart 	els->display_name = "rffid";
9528f406ef7SJames Smart 	ct = els->io.req.virt;
9538f406ef7SJames Smart 
9548f406ef7SJames Smart 	memset(ct, 0, sizeof(*ct));
9558f406ef7SJames Smart 	fcct_build_req_header(&ct->hdr, FC_NS_RFF_ID,
9568f406ef7SJames Smart 			      sizeof(struct fc_ns_rff_id));
9578f406ef7SJames Smart 
9588f406ef7SJames Smart 	hton24(ct->rffid.fr_fid.fp_fid, node->rnode.nport->fc_id);
9598f406ef7SJames Smart 	if (node->nport->enable_ini)
9608f406ef7SJames Smart 		ct->rffid.fr_feat |= FCP_FEAT_INIT;
9618f406ef7SJames Smart 	if (node->nport->enable_tgt)
9628f406ef7SJames Smart 		ct->rffid.fr_feat |= FCP_FEAT_TARG;
9638f406ef7SJames Smart 	ct->rffid.fr_type = FC_TYPE_FCP;
9648f406ef7SJames Smart 
9658f406ef7SJames Smart 	return efc_els_send_req(node, els, EFC_DISC_IO_CT_REQ);
9668f406ef7SJames Smart }
9678f406ef7SJames Smart 
9688f406ef7SJames Smart int
efc_ns_send_gidpt(struct efc_node * node)9698f406ef7SJames Smart efc_ns_send_gidpt(struct efc_node *node)
9708f406ef7SJames Smart {
9718f406ef7SJames Smart 	struct efc_els_io_req *els = NULL;
9728f406ef7SJames Smart 	struct efc *efc = node->efc;
9738f406ef7SJames Smart 	struct {
9748f406ef7SJames Smart 		struct fc_ct_hdr hdr;
9758f406ef7SJames Smart 		struct fc_ns_gid_pt gidpt;
9768f406ef7SJames Smart 	} *ct;
9778f406ef7SJames Smart 
9788f406ef7SJames Smart 	node_els_trace();
9798f406ef7SJames Smart 
9808f406ef7SJames Smart 	els = efc_els_io_alloc_size(node, sizeof(*ct), EFC_ELS_GID_PT_RSP_LEN);
9818f406ef7SJames Smart 	if (!els) {
9828f406ef7SJames Smart 		efc_log_err(efc, "IO alloc failed\n");
9838f406ef7SJames Smart 		return -EIO;
9848f406ef7SJames Smart 	}
9858f406ef7SJames Smart 
9868f406ef7SJames Smart 	els->io.iparam.ct.r_ctl = FC_RCTL_ELS_REQ;
9878f406ef7SJames Smart 	els->io.iparam.ct.type = FC_TYPE_CT;
9888f406ef7SJames Smart 	els->io.iparam.ct.df_ctl = 0;
9898f406ef7SJames Smart 	els->io.iparam.ct.timeout = EFC_FC_ELS_SEND_DEFAULT_TIMEOUT;
9908f406ef7SJames Smart 
9918f406ef7SJames Smart 	els->display_name = "gidpt";
9928f406ef7SJames Smart 
9938f406ef7SJames Smart 	ct = els->io.req.virt;
9948f406ef7SJames Smart 
9958f406ef7SJames Smart 	memset(ct, 0, sizeof(*ct));
9968f406ef7SJames Smart 	fcct_build_req_header(&ct->hdr, FC_NS_GID_PT,
9978f406ef7SJames Smart 			      sizeof(struct fc_ns_gid_pt));
9988f406ef7SJames Smart 
9998f406ef7SJames Smart 	ct->gidpt.fn_pt_type = FC_TYPE_FCP;
10008f406ef7SJames Smart 
10018f406ef7SJames Smart 	return efc_els_send_req(node, els, EFC_DISC_IO_CT_REQ);
10028f406ef7SJames Smart }
10038f406ef7SJames Smart 
10048f406ef7SJames Smart void
efc_els_io_cleanup(struct efc_els_io_req * els,int evt,void * arg)10058f406ef7SJames Smart efc_els_io_cleanup(struct efc_els_io_req *els, int evt, void *arg)
10068f406ef7SJames Smart {
10078f406ef7SJames Smart 	/* don't want further events that could come; e.g. abort requests
10088f406ef7SJames Smart 	 * from the node state machine; thus, disable state machine
10098f406ef7SJames Smart 	 */
10108f406ef7SJames Smart 	els->els_req_free = true;
10118f406ef7SJames Smart 	efc_node_post_els_resp(els->node, evt, arg);
10128f406ef7SJames Smart 
10138f406ef7SJames Smart 	efc_els_io_free(els);
10148f406ef7SJames Smart }
10158f406ef7SJames Smart 
10168f406ef7SJames Smart static int
efc_ct_acc_cb(void * arg,u32 length,int status,u32 ext_status)10178f406ef7SJames Smart efc_ct_acc_cb(void *arg, u32 length, int status, u32 ext_status)
10188f406ef7SJames Smart {
10198f406ef7SJames Smart 	struct efc_els_io_req *els = arg;
10208f406ef7SJames Smart 
10218f406ef7SJames Smart 	efc_els_io_free(els);
10228f406ef7SJames Smart 
10238f406ef7SJames Smart 	return 0;
10248f406ef7SJames Smart }
10258f406ef7SJames Smart 
10268f406ef7SJames Smart int
efc_send_ct_rsp(struct efc * efc,struct efc_node * node,u16 ox_id,struct fc_ct_hdr * ct_hdr,u32 cmd_rsp_code,u32 reason_code,u32 reason_code_explanation)10278f406ef7SJames Smart efc_send_ct_rsp(struct efc *efc, struct efc_node *node, u16 ox_id,
10288f406ef7SJames Smart 		struct fc_ct_hdr *ct_hdr, u32 cmd_rsp_code,
10298f406ef7SJames Smart 		u32 reason_code, u32 reason_code_explanation)
10308f406ef7SJames Smart {
10318f406ef7SJames Smart 	struct efc_els_io_req *els = NULL;
10328f406ef7SJames Smart 	struct fc_ct_hdr  *rsp = NULL;
10338f406ef7SJames Smart 
10348f406ef7SJames Smart 	els = efc_els_io_alloc(node, 256);
10358f406ef7SJames Smart 	if (!els) {
10368f406ef7SJames Smart 		efc_log_err(efc, "IO alloc failed\n");
10378f406ef7SJames Smart 		return -EIO;
10388f406ef7SJames Smart 	}
10398f406ef7SJames Smart 
10408f406ef7SJames Smart 	rsp = els->io.rsp.virt;
10418f406ef7SJames Smart 
10428f406ef7SJames Smart 	*rsp = *ct_hdr;
10438f406ef7SJames Smart 
10448f406ef7SJames Smart 	fcct_build_req_header(rsp, cmd_rsp_code, 0);
10458f406ef7SJames Smart 	rsp->ct_reason = reason_code;
10468f406ef7SJames Smart 	rsp->ct_explan = reason_code_explanation;
10478f406ef7SJames Smart 
10488f406ef7SJames Smart 	els->display_name = "ct_rsp";
10498f406ef7SJames Smart 	els->cb = efc_ct_acc_cb;
10508f406ef7SJames Smart 
10518f406ef7SJames Smart 	/* Prepare the IO request details */
10528f406ef7SJames Smart 	els->io.io_type = EFC_DISC_IO_CT_RESP;
10538f406ef7SJames Smart 	els->io.xmit_len = sizeof(*rsp);
10548f406ef7SJames Smart 
10558f406ef7SJames Smart 	els->io.rpi = node->rnode.indicator;
10568f406ef7SJames Smart 	els->io.d_id = node->rnode.fc_id;
10578f406ef7SJames Smart 
10588f406ef7SJames Smart 	memset(&els->io.iparam, 0, sizeof(els->io.iparam));
10598f406ef7SJames Smart 
10608f406ef7SJames Smart 	els->io.iparam.ct.ox_id = ox_id;
10618f406ef7SJames Smart 	els->io.iparam.ct.r_ctl = 3;
10628f406ef7SJames Smart 	els->io.iparam.ct.type = FC_TYPE_CT;
10638f406ef7SJames Smart 	els->io.iparam.ct.df_ctl = 0;
10648f406ef7SJames Smart 	els->io.iparam.ct.timeout = 5;
10658f406ef7SJames Smart 
10668f406ef7SJames Smart 	if (efc->tt.send_els(efc, &els->io)) {
10678f406ef7SJames Smart 		efc_els_io_free(els);
10688f406ef7SJames Smart 		return -EIO;
10698f406ef7SJames Smart 	}
10708f406ef7SJames Smart 	return 0;
10718f406ef7SJames Smart }
10728f406ef7SJames Smart 
10738f406ef7SJames Smart int
efc_send_bls_acc(struct efc_node * node,struct fc_frame_header * hdr)10748f406ef7SJames Smart efc_send_bls_acc(struct efc_node *node, struct fc_frame_header *hdr)
10758f406ef7SJames Smart {
10768f406ef7SJames Smart 	struct sli_bls_params bls;
10778f406ef7SJames Smart 	struct fc_ba_acc *acc;
10788f406ef7SJames Smart 	struct efc *efc = node->efc;
10798f406ef7SJames Smart 
10808f406ef7SJames Smart 	memset(&bls, 0, sizeof(bls));
10818f406ef7SJames Smart 	bls.ox_id = be16_to_cpu(hdr->fh_ox_id);
10828f406ef7SJames Smart 	bls.rx_id = be16_to_cpu(hdr->fh_rx_id);
10838f406ef7SJames Smart 	bls.s_id = ntoh24(hdr->fh_d_id);
10848f406ef7SJames Smart 	bls.d_id = node->rnode.fc_id;
10858f406ef7SJames Smart 	bls.rpi = node->rnode.indicator;
10868f406ef7SJames Smart 	bls.vpi = node->nport->indicator;
10878f406ef7SJames Smart 
10888f406ef7SJames Smart 	acc = (void *)bls.payload;
10898f406ef7SJames Smart 	acc->ba_ox_id = cpu_to_be16(bls.ox_id);
10908f406ef7SJames Smart 	acc->ba_rx_id = cpu_to_be16(bls.rx_id);
10918f406ef7SJames Smart 	acc->ba_high_seq_cnt = cpu_to_be16(U16_MAX);
10928f406ef7SJames Smart 
10938f406ef7SJames Smart 	return efc->tt.send_bls(efc, FC_RCTL_BA_ACC, &bls);
10948f406ef7SJames Smart }
1095