1*3e641400SJames Smart /* SPDX-License-Identifier: GPL-2.0 */ 2*3e641400SJames Smart /* 3*3e641400SJames Smart * Copyright (C) 2021 Broadcom. All Rights Reserved. The term 4*3e641400SJames Smart * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 5*3e641400SJames Smart */ 6*3e641400SJames Smart 7*3e641400SJames Smart #if !defined(__EFCT_SCSI_H__) 8*3e641400SJames Smart #define __EFCT_SCSI_H__ 9*3e641400SJames Smart #include <scsi/scsi_host.h> 10*3e641400SJames Smart #include <scsi/scsi_transport_fc.h> 11*3e641400SJames Smart 12*3e641400SJames Smart /* efct_scsi_rcv_cmd() efct_scsi_rcv_tmf() flags */ 13*3e641400SJames Smart #define EFCT_SCSI_CMD_DIR_IN (1 << 0) 14*3e641400SJames Smart #define EFCT_SCSI_CMD_DIR_OUT (1 << 1) 15*3e641400SJames Smart #define EFCT_SCSI_CMD_SIMPLE (1 << 2) 16*3e641400SJames Smart #define EFCT_SCSI_CMD_HEAD_OF_QUEUE (1 << 3) 17*3e641400SJames Smart #define EFCT_SCSI_CMD_ORDERED (1 << 4) 18*3e641400SJames Smart #define EFCT_SCSI_CMD_UNTAGGED (1 << 5) 19*3e641400SJames Smart #define EFCT_SCSI_CMD_ACA (1 << 6) 20*3e641400SJames Smart #define EFCT_SCSI_FIRST_BURST_ERR (1 << 7) 21*3e641400SJames Smart #define EFCT_SCSI_FIRST_BURST_ABORTED (1 << 8) 22*3e641400SJames Smart 23*3e641400SJames Smart /* efct_scsi_send_rd_data/recv_wr_data/send_resp flags */ 24*3e641400SJames Smart #define EFCT_SCSI_LAST_DATAPHASE (1 << 0) 25*3e641400SJames Smart #define EFCT_SCSI_NO_AUTO_RESPONSE (1 << 1) 26*3e641400SJames Smart #define EFCT_SCSI_LOW_LATENCY (1 << 2) 27*3e641400SJames Smart 28*3e641400SJames Smart #define EFCT_SCSI_SNS_BUF_VALID(sense) ((sense) && \ 29*3e641400SJames Smart (0x70 == (((const u8 *)(sense))[0] & 0x70))) 30*3e641400SJames Smart 31*3e641400SJames Smart #define EFCT_SCSI_WQ_STEERING_SHIFT 16 32*3e641400SJames Smart #define EFCT_SCSI_WQ_STEERING_MASK (0xf << EFCT_SCSI_WQ_STEERING_SHIFT) 33*3e641400SJames Smart #define EFCT_SCSI_WQ_STEERING_CLASS (0 << EFCT_SCSI_WQ_STEERING_SHIFT) 34*3e641400SJames Smart #define EFCT_SCSI_WQ_STEERING_REQUEST (1 << EFCT_SCSI_WQ_STEERING_SHIFT) 35*3e641400SJames Smart #define EFCT_SCSI_WQ_STEERING_CPU (2 << EFCT_SCSI_WQ_STEERING_SHIFT) 36*3e641400SJames Smart 37*3e641400SJames Smart #define EFCT_SCSI_WQ_CLASS_SHIFT (20) 38*3e641400SJames Smart #define EFCT_SCSI_WQ_CLASS_MASK (0xf << EFCT_SCSI_WQ_CLASS_SHIFT) 39*3e641400SJames Smart #define EFCT_SCSI_WQ_CLASS(x) ((x & EFCT_SCSI_WQ_CLASS_MASK) << \ 40*3e641400SJames Smart EFCT_SCSI_WQ_CLASS_SHIFT) 41*3e641400SJames Smart 42*3e641400SJames Smart #define EFCT_SCSI_WQ_CLASS_LOW_LATENCY 1 43*3e641400SJames Smart 44*3e641400SJames Smart struct efct_scsi_cmd_resp { 45*3e641400SJames Smart u8 scsi_status; 46*3e641400SJames Smart u16 scsi_status_qualifier; 47*3e641400SJames Smart u8 *response_data; 48*3e641400SJames Smart u32 response_data_length; 49*3e641400SJames Smart u8 *sense_data; 50*3e641400SJames Smart u32 sense_data_length; 51*3e641400SJames Smart int residual; 52*3e641400SJames Smart u32 response_wire_length; 53*3e641400SJames Smart }; 54*3e641400SJames Smart 55*3e641400SJames Smart struct efct_vport { 56*3e641400SJames Smart struct efct *efct; 57*3e641400SJames Smart bool is_vport; 58*3e641400SJames Smart struct fc_host_statistics fc_host_stats; 59*3e641400SJames Smart struct Scsi_Host *shost; 60*3e641400SJames Smart struct fc_vport *fc_vport; 61*3e641400SJames Smart u64 npiv_wwpn; 62*3e641400SJames Smart u64 npiv_wwnn; 63*3e641400SJames Smart }; 64*3e641400SJames Smart 65*3e641400SJames Smart /* Status values returned by IO callbacks */ 66*3e641400SJames Smart enum efct_scsi_io_status { 67*3e641400SJames Smart EFCT_SCSI_STATUS_GOOD = 0, 68*3e641400SJames Smart EFCT_SCSI_STATUS_ABORTED, 69*3e641400SJames Smart EFCT_SCSI_STATUS_ERROR, 70*3e641400SJames Smart EFCT_SCSI_STATUS_DIF_GUARD_ERR, 71*3e641400SJames Smart EFCT_SCSI_STATUS_DIF_REF_TAG_ERROR, 72*3e641400SJames Smart EFCT_SCSI_STATUS_DIF_APP_TAG_ERROR, 73*3e641400SJames Smart EFCT_SCSI_STATUS_DIF_UNKNOWN_ERROR, 74*3e641400SJames Smart EFCT_SCSI_STATUS_PROTOCOL_CRC_ERROR, 75*3e641400SJames Smart EFCT_SCSI_STATUS_NO_IO, 76*3e641400SJames Smart EFCT_SCSI_STATUS_ABORT_IN_PROGRESS, 77*3e641400SJames Smart EFCT_SCSI_STATUS_CHECK_RESPONSE, 78*3e641400SJames Smart EFCT_SCSI_STATUS_COMMAND_TIMEOUT, 79*3e641400SJames Smart EFCT_SCSI_STATUS_TIMEDOUT_AND_ABORTED, 80*3e641400SJames Smart EFCT_SCSI_STATUS_SHUTDOWN, 81*3e641400SJames Smart EFCT_SCSI_STATUS_NEXUS_LOST, 82*3e641400SJames Smart }; 83*3e641400SJames Smart 84*3e641400SJames Smart struct efct_node; 85*3e641400SJames Smart struct efct_io; 86*3e641400SJames Smart struct efc_node; 87*3e641400SJames Smart struct efc_nport; 88*3e641400SJames Smart 89*3e641400SJames Smart /* Callback used by send_rd_data(), recv_wr_data(), send_resp() */ 90*3e641400SJames Smart typedef int (*efct_scsi_io_cb_t)(struct efct_io *io, 91*3e641400SJames Smart enum efct_scsi_io_status status, 92*3e641400SJames Smart u32 flags, void *arg); 93*3e641400SJames Smart 94*3e641400SJames Smart /* Callback used by send_rd_io(), send_wr_io() */ 95*3e641400SJames Smart typedef int (*efct_scsi_rsp_io_cb_t)(struct efct_io *io, 96*3e641400SJames Smart enum efct_scsi_io_status status, 97*3e641400SJames Smart struct efct_scsi_cmd_resp *rsp, 98*3e641400SJames Smart u32 flags, void *arg); 99*3e641400SJames Smart 100*3e641400SJames Smart /* efct_scsi_cb_t flags */ 101*3e641400SJames Smart #define EFCT_SCSI_IO_CMPL (1 << 0) 102*3e641400SJames Smart /* IO completed, response sent */ 103*3e641400SJames Smart #define EFCT_SCSI_IO_CMPL_RSP_SENT (1 << 1) 104*3e641400SJames Smart #define EFCT_SCSI_IO_ABORTED (1 << 2) 105*3e641400SJames Smart 106*3e641400SJames Smart /* efct_scsi_recv_tmf() request values */ 107*3e641400SJames Smart enum efct_scsi_tmf_cmd { 108*3e641400SJames Smart EFCT_SCSI_TMF_ABORT_TASK = 1, 109*3e641400SJames Smart EFCT_SCSI_TMF_QUERY_TASK_SET, 110*3e641400SJames Smart EFCT_SCSI_TMF_ABORT_TASK_SET, 111*3e641400SJames Smart EFCT_SCSI_TMF_CLEAR_TASK_SET, 112*3e641400SJames Smart EFCT_SCSI_TMF_QUERY_ASYNCHRONOUS_EVENT, 113*3e641400SJames Smart EFCT_SCSI_TMF_LOGICAL_UNIT_RESET, 114*3e641400SJames Smart EFCT_SCSI_TMF_CLEAR_ACA, 115*3e641400SJames Smart EFCT_SCSI_TMF_TARGET_RESET, 116*3e641400SJames Smart }; 117*3e641400SJames Smart 118*3e641400SJames Smart /* efct_scsi_send_tmf_resp() response values */ 119*3e641400SJames Smart enum efct_scsi_tmf_resp { 120*3e641400SJames Smart EFCT_SCSI_TMF_FUNCTION_COMPLETE = 1, 121*3e641400SJames Smart EFCT_SCSI_TMF_FUNCTION_SUCCEEDED, 122*3e641400SJames Smart EFCT_SCSI_TMF_FUNCTION_IO_NOT_FOUND, 123*3e641400SJames Smart EFCT_SCSI_TMF_FUNCTION_REJECTED, 124*3e641400SJames Smart EFCT_SCSI_TMF_INCORRECT_LOGICAL_UNIT_NUMBER, 125*3e641400SJames Smart EFCT_SCSI_TMF_SERVICE_DELIVERY, 126*3e641400SJames Smart }; 127*3e641400SJames Smart 128*3e641400SJames Smart struct efct_scsi_sgl { 129*3e641400SJames Smart uintptr_t addr; 130*3e641400SJames Smart uintptr_t dif_addr; 131*3e641400SJames Smart size_t len; 132*3e641400SJames Smart }; 133*3e641400SJames Smart 134*3e641400SJames Smart enum efct_scsi_io_role { 135*3e641400SJames Smart EFCT_SCSI_IO_ROLE_ORIGINATOR, 136*3e641400SJames Smart EFCT_SCSI_IO_ROLE_RESPONDER, 137*3e641400SJames Smart }; 138*3e641400SJames Smart 139*3e641400SJames Smart struct efct_io * 140*3e641400SJames Smart efct_scsi_io_alloc(struct efct_node *node); 141*3e641400SJames Smart void efct_scsi_io_free(struct efct_io *io); 142*3e641400SJames Smart struct efct_io *efct_io_get_instance(struct efct *efct, u32 index); 143*3e641400SJames Smart 144*3e641400SJames Smart int efct_scsi_tgt_driver_init(void); 145*3e641400SJames Smart int efct_scsi_tgt_driver_exit(void); 146*3e641400SJames Smart int efct_scsi_tgt_new_device(struct efct *efct); 147*3e641400SJames Smart int efct_scsi_tgt_del_device(struct efct *efct); 148*3e641400SJames Smart int 149*3e641400SJames Smart efct_scsi_tgt_new_nport(struct efc *efc, struct efc_nport *nport); 150*3e641400SJames Smart void 151*3e641400SJames Smart efct_scsi_tgt_del_nport(struct efc *efc, struct efc_nport *nport); 152*3e641400SJames Smart 153*3e641400SJames Smart int 154*3e641400SJames Smart efct_scsi_new_initiator(struct efc *efc, struct efc_node *node); 155*3e641400SJames Smart 156*3e641400SJames Smart enum efct_scsi_del_initiator_reason { 157*3e641400SJames Smart EFCT_SCSI_INITIATOR_DELETED, 158*3e641400SJames Smart EFCT_SCSI_INITIATOR_MISSING, 159*3e641400SJames Smart }; 160*3e641400SJames Smart 161*3e641400SJames Smart int 162*3e641400SJames Smart efct_scsi_del_initiator(struct efc *efc, struct efc_node *node, int reason); 163*3e641400SJames Smart void 164*3e641400SJames Smart efct_scsi_recv_cmd(struct efct_io *io, uint64_t lun, u8 *cdb, u32 cdb_len, 165*3e641400SJames Smart u32 flags); 166*3e641400SJames Smart int 167*3e641400SJames Smart efct_scsi_recv_tmf(struct efct_io *tmfio, u32 lun, enum efct_scsi_tmf_cmd cmd, 168*3e641400SJames Smart struct efct_io *abortio, u32 flags); 169*3e641400SJames Smart int 170*3e641400SJames Smart efct_scsi_send_rd_data(struct efct_io *io, u32 flags, struct efct_scsi_sgl *sgl, 171*3e641400SJames Smart u32 sgl_count, u64 wire_len, efct_scsi_io_cb_t cb, void *arg); 172*3e641400SJames Smart int 173*3e641400SJames Smart efct_scsi_recv_wr_data(struct efct_io *io, u32 flags, struct efct_scsi_sgl *sgl, 174*3e641400SJames Smart u32 sgl_count, u64 wire_len, efct_scsi_io_cb_t cb, void *arg); 175*3e641400SJames Smart int 176*3e641400SJames Smart efct_scsi_send_resp(struct efct_io *io, u32 flags, 177*3e641400SJames Smart struct efct_scsi_cmd_resp *rsp, efct_scsi_io_cb_t cb, void *arg); 178*3e641400SJames Smart int 179*3e641400SJames Smart efct_scsi_send_tmf_resp(struct efct_io *io, enum efct_scsi_tmf_resp rspcode, 180*3e641400SJames Smart u8 addl_rsp_info[3], efct_scsi_io_cb_t cb, void *arg); 181*3e641400SJames Smart int 182*3e641400SJames Smart efct_scsi_tgt_abort_io(struct efct_io *io, efct_scsi_io_cb_t cb, void *arg); 183*3e641400SJames Smart 184*3e641400SJames Smart void efct_scsi_io_complete(struct efct_io *io); 185*3e641400SJames Smart 186*3e641400SJames Smart int efct_scsi_reg_fc_transport(void); 187*3e641400SJames Smart void efct_scsi_release_fc_transport(void); 188*3e641400SJames Smart int efct_scsi_new_device(struct efct *efct); 189*3e641400SJames Smart void efct_scsi_del_device(struct efct *efct); 190*3e641400SJames Smart void _efct_scsi_io_free(struct kref *arg); 191*3e641400SJames Smart 192*3e641400SJames Smart int 193*3e641400SJames Smart efct_scsi_del_vport(struct efct *efct, struct Scsi_Host *shost); 194*3e641400SJames Smart struct efct_vport * 195*3e641400SJames Smart efct_scsi_new_vport(struct efct *efct, struct device *dev); 196*3e641400SJames Smart 197*3e641400SJames Smart int efct_scsi_io_dispatch(struct efct_io *io, void *cb); 198*3e641400SJames Smart int efct_scsi_io_dispatch_abort(struct efct_io *io, void *cb); 199*3e641400SJames Smart void efct_scsi_check_pending(struct efct *efct); 200*3e641400SJames Smart struct efct_io * 201*3e641400SJames Smart efct_bls_send_rjt(struct efct_io *io, struct fc_frame_header *hdr); 202*3e641400SJames Smart 203*3e641400SJames Smart #endif /* __EFCT_SCSI_H__ */ 204