162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2021 Broadcom. All Rights Reserved. The term 462306a36Sopenharmony_ci * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#if !defined(__EFCT_SCSI_H__) 862306a36Sopenharmony_ci#define __EFCT_SCSI_H__ 962306a36Sopenharmony_ci#include <scsi/scsi_host.h> 1062306a36Sopenharmony_ci#include <scsi/scsi_transport_fc.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/* efct_scsi_rcv_cmd() efct_scsi_rcv_tmf() flags */ 1362306a36Sopenharmony_ci#define EFCT_SCSI_CMD_DIR_IN (1 << 0) 1462306a36Sopenharmony_ci#define EFCT_SCSI_CMD_DIR_OUT (1 << 1) 1562306a36Sopenharmony_ci#define EFCT_SCSI_CMD_SIMPLE (1 << 2) 1662306a36Sopenharmony_ci#define EFCT_SCSI_CMD_HEAD_OF_QUEUE (1 << 3) 1762306a36Sopenharmony_ci#define EFCT_SCSI_CMD_ORDERED (1 << 4) 1862306a36Sopenharmony_ci#define EFCT_SCSI_CMD_UNTAGGED (1 << 5) 1962306a36Sopenharmony_ci#define EFCT_SCSI_CMD_ACA (1 << 6) 2062306a36Sopenharmony_ci#define EFCT_SCSI_FIRST_BURST_ERR (1 << 7) 2162306a36Sopenharmony_ci#define EFCT_SCSI_FIRST_BURST_ABORTED (1 << 8) 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci/* efct_scsi_send_rd_data/recv_wr_data/send_resp flags */ 2462306a36Sopenharmony_ci#define EFCT_SCSI_LAST_DATAPHASE (1 << 0) 2562306a36Sopenharmony_ci#define EFCT_SCSI_NO_AUTO_RESPONSE (1 << 1) 2662306a36Sopenharmony_ci#define EFCT_SCSI_LOW_LATENCY (1 << 2) 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define EFCT_SCSI_SNS_BUF_VALID(sense) ((sense) && \ 2962306a36Sopenharmony_ci (0x70 == (((const u8 *)(sense))[0] & 0x70))) 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#define EFCT_SCSI_WQ_STEERING_SHIFT 16 3262306a36Sopenharmony_ci#define EFCT_SCSI_WQ_STEERING_MASK (0xf << EFCT_SCSI_WQ_STEERING_SHIFT) 3362306a36Sopenharmony_ci#define EFCT_SCSI_WQ_STEERING_CLASS (0 << EFCT_SCSI_WQ_STEERING_SHIFT) 3462306a36Sopenharmony_ci#define EFCT_SCSI_WQ_STEERING_REQUEST (1 << EFCT_SCSI_WQ_STEERING_SHIFT) 3562306a36Sopenharmony_ci#define EFCT_SCSI_WQ_STEERING_CPU (2 << EFCT_SCSI_WQ_STEERING_SHIFT) 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci#define EFCT_SCSI_WQ_CLASS_SHIFT (20) 3862306a36Sopenharmony_ci#define EFCT_SCSI_WQ_CLASS_MASK (0xf << EFCT_SCSI_WQ_CLASS_SHIFT) 3962306a36Sopenharmony_ci#define EFCT_SCSI_WQ_CLASS(x) ((x & EFCT_SCSI_WQ_CLASS_MASK) << \ 4062306a36Sopenharmony_ci EFCT_SCSI_WQ_CLASS_SHIFT) 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#define EFCT_SCSI_WQ_CLASS_LOW_LATENCY 1 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistruct efct_scsi_cmd_resp { 4562306a36Sopenharmony_ci u8 scsi_status; 4662306a36Sopenharmony_ci u16 scsi_status_qualifier; 4762306a36Sopenharmony_ci u8 *response_data; 4862306a36Sopenharmony_ci u32 response_data_length; 4962306a36Sopenharmony_ci u8 *sense_data; 5062306a36Sopenharmony_ci u32 sense_data_length; 5162306a36Sopenharmony_ci int residual; 5262306a36Sopenharmony_ci u32 response_wire_length; 5362306a36Sopenharmony_ci}; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistruct efct_vport { 5662306a36Sopenharmony_ci struct efct *efct; 5762306a36Sopenharmony_ci bool is_vport; 5862306a36Sopenharmony_ci struct fc_host_statistics fc_host_stats; 5962306a36Sopenharmony_ci struct Scsi_Host *shost; 6062306a36Sopenharmony_ci struct fc_vport *fc_vport; 6162306a36Sopenharmony_ci u64 npiv_wwpn; 6262306a36Sopenharmony_ci u64 npiv_wwnn; 6362306a36Sopenharmony_ci}; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci/* Status values returned by IO callbacks */ 6662306a36Sopenharmony_cienum efct_scsi_io_status { 6762306a36Sopenharmony_ci EFCT_SCSI_STATUS_GOOD = 0, 6862306a36Sopenharmony_ci EFCT_SCSI_STATUS_ABORTED, 6962306a36Sopenharmony_ci EFCT_SCSI_STATUS_ERROR, 7062306a36Sopenharmony_ci EFCT_SCSI_STATUS_DIF_GUARD_ERR, 7162306a36Sopenharmony_ci EFCT_SCSI_STATUS_DIF_REF_TAG_ERROR, 7262306a36Sopenharmony_ci EFCT_SCSI_STATUS_DIF_APP_TAG_ERROR, 7362306a36Sopenharmony_ci EFCT_SCSI_STATUS_DIF_UNKNOWN_ERROR, 7462306a36Sopenharmony_ci EFCT_SCSI_STATUS_PROTOCOL_CRC_ERROR, 7562306a36Sopenharmony_ci EFCT_SCSI_STATUS_NO_IO, 7662306a36Sopenharmony_ci EFCT_SCSI_STATUS_ABORT_IN_PROGRESS, 7762306a36Sopenharmony_ci EFCT_SCSI_STATUS_CHECK_RESPONSE, 7862306a36Sopenharmony_ci EFCT_SCSI_STATUS_COMMAND_TIMEOUT, 7962306a36Sopenharmony_ci EFCT_SCSI_STATUS_TIMEDOUT_AND_ABORTED, 8062306a36Sopenharmony_ci EFCT_SCSI_STATUS_SHUTDOWN, 8162306a36Sopenharmony_ci EFCT_SCSI_STATUS_NEXUS_LOST, 8262306a36Sopenharmony_ci}; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cistruct efct_node; 8562306a36Sopenharmony_cistruct efct_io; 8662306a36Sopenharmony_cistruct efc_node; 8762306a36Sopenharmony_cistruct efc_nport; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci/* Callback used by send_rd_data(), recv_wr_data(), send_resp() */ 9062306a36Sopenharmony_citypedef int (*efct_scsi_io_cb_t)(struct efct_io *io, 9162306a36Sopenharmony_ci enum efct_scsi_io_status status, 9262306a36Sopenharmony_ci u32 flags, void *arg); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci/* Callback used by send_rd_io(), send_wr_io() */ 9562306a36Sopenharmony_citypedef int (*efct_scsi_rsp_io_cb_t)(struct efct_io *io, 9662306a36Sopenharmony_ci enum efct_scsi_io_status status, 9762306a36Sopenharmony_ci struct efct_scsi_cmd_resp *rsp, 9862306a36Sopenharmony_ci u32 flags, void *arg); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci/* efct_scsi_cb_t flags */ 10162306a36Sopenharmony_ci#define EFCT_SCSI_IO_CMPL (1 << 0) 10262306a36Sopenharmony_ci/* IO completed, response sent */ 10362306a36Sopenharmony_ci#define EFCT_SCSI_IO_CMPL_RSP_SENT (1 << 1) 10462306a36Sopenharmony_ci#define EFCT_SCSI_IO_ABORTED (1 << 2) 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci/* efct_scsi_recv_tmf() request values */ 10762306a36Sopenharmony_cienum efct_scsi_tmf_cmd { 10862306a36Sopenharmony_ci EFCT_SCSI_TMF_ABORT_TASK = 1, 10962306a36Sopenharmony_ci EFCT_SCSI_TMF_QUERY_TASK_SET, 11062306a36Sopenharmony_ci EFCT_SCSI_TMF_ABORT_TASK_SET, 11162306a36Sopenharmony_ci EFCT_SCSI_TMF_CLEAR_TASK_SET, 11262306a36Sopenharmony_ci EFCT_SCSI_TMF_QUERY_ASYNCHRONOUS_EVENT, 11362306a36Sopenharmony_ci EFCT_SCSI_TMF_LOGICAL_UNIT_RESET, 11462306a36Sopenharmony_ci EFCT_SCSI_TMF_CLEAR_ACA, 11562306a36Sopenharmony_ci EFCT_SCSI_TMF_TARGET_RESET, 11662306a36Sopenharmony_ci}; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci/* efct_scsi_send_tmf_resp() response values */ 11962306a36Sopenharmony_cienum efct_scsi_tmf_resp { 12062306a36Sopenharmony_ci EFCT_SCSI_TMF_FUNCTION_COMPLETE = 1, 12162306a36Sopenharmony_ci EFCT_SCSI_TMF_FUNCTION_SUCCEEDED, 12262306a36Sopenharmony_ci EFCT_SCSI_TMF_FUNCTION_IO_NOT_FOUND, 12362306a36Sopenharmony_ci EFCT_SCSI_TMF_FUNCTION_REJECTED, 12462306a36Sopenharmony_ci EFCT_SCSI_TMF_INCORRECT_LOGICAL_UNIT_NUMBER, 12562306a36Sopenharmony_ci EFCT_SCSI_TMF_SERVICE_DELIVERY, 12662306a36Sopenharmony_ci}; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistruct efct_scsi_sgl { 12962306a36Sopenharmony_ci uintptr_t addr; 13062306a36Sopenharmony_ci uintptr_t dif_addr; 13162306a36Sopenharmony_ci size_t len; 13262306a36Sopenharmony_ci}; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cienum efct_scsi_io_role { 13562306a36Sopenharmony_ci EFCT_SCSI_IO_ROLE_ORIGINATOR, 13662306a36Sopenharmony_ci EFCT_SCSI_IO_ROLE_RESPONDER, 13762306a36Sopenharmony_ci}; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_cistruct efct_io * 14062306a36Sopenharmony_ciefct_scsi_io_alloc(struct efct_node *node); 14162306a36Sopenharmony_civoid efct_scsi_io_free(struct efct_io *io); 14262306a36Sopenharmony_cistruct efct_io *efct_io_get_instance(struct efct *efct, u32 index); 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ciint efct_scsi_tgt_driver_init(void); 14562306a36Sopenharmony_ciint efct_scsi_tgt_driver_exit(void); 14662306a36Sopenharmony_ciint efct_scsi_tgt_new_device(struct efct *efct); 14762306a36Sopenharmony_ciint efct_scsi_tgt_del_device(struct efct *efct); 14862306a36Sopenharmony_ciint 14962306a36Sopenharmony_ciefct_scsi_tgt_new_nport(struct efc *efc, struct efc_nport *nport); 15062306a36Sopenharmony_civoid 15162306a36Sopenharmony_ciefct_scsi_tgt_del_nport(struct efc *efc, struct efc_nport *nport); 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ciint 15462306a36Sopenharmony_ciefct_scsi_new_initiator(struct efc *efc, struct efc_node *node); 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_cienum efct_scsi_del_initiator_reason { 15762306a36Sopenharmony_ci EFCT_SCSI_INITIATOR_DELETED, 15862306a36Sopenharmony_ci EFCT_SCSI_INITIATOR_MISSING, 15962306a36Sopenharmony_ci}; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ciint 16262306a36Sopenharmony_ciefct_scsi_del_initiator(struct efc *efc, struct efc_node *node, int reason); 16362306a36Sopenharmony_civoid 16462306a36Sopenharmony_ciefct_scsi_recv_cmd(struct efct_io *io, uint64_t lun, u8 *cdb, u32 cdb_len, 16562306a36Sopenharmony_ci u32 flags); 16662306a36Sopenharmony_ciint 16762306a36Sopenharmony_ciefct_scsi_recv_tmf(struct efct_io *tmfio, u32 lun, enum efct_scsi_tmf_cmd cmd, 16862306a36Sopenharmony_ci struct efct_io *abortio, u32 flags); 16962306a36Sopenharmony_ciint 17062306a36Sopenharmony_ciefct_scsi_send_rd_data(struct efct_io *io, u32 flags, struct efct_scsi_sgl *sgl, 17162306a36Sopenharmony_ci u32 sgl_count, u64 wire_len, efct_scsi_io_cb_t cb, void *arg); 17262306a36Sopenharmony_ciint 17362306a36Sopenharmony_ciefct_scsi_recv_wr_data(struct efct_io *io, u32 flags, struct efct_scsi_sgl *sgl, 17462306a36Sopenharmony_ci u32 sgl_count, u64 wire_len, efct_scsi_io_cb_t cb, void *arg); 17562306a36Sopenharmony_ciint 17662306a36Sopenharmony_ciefct_scsi_send_resp(struct efct_io *io, u32 flags, 17762306a36Sopenharmony_ci struct efct_scsi_cmd_resp *rsp, efct_scsi_io_cb_t cb, void *arg); 17862306a36Sopenharmony_ciint 17962306a36Sopenharmony_ciefct_scsi_send_tmf_resp(struct efct_io *io, enum efct_scsi_tmf_resp rspcode, 18062306a36Sopenharmony_ci u8 addl_rsp_info[3], efct_scsi_io_cb_t cb, void *arg); 18162306a36Sopenharmony_ciint 18262306a36Sopenharmony_ciefct_scsi_tgt_abort_io(struct efct_io *io, efct_scsi_io_cb_t cb, void *arg); 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_civoid efct_scsi_io_complete(struct efct_io *io); 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ciint efct_scsi_reg_fc_transport(void); 18762306a36Sopenharmony_civoid efct_scsi_release_fc_transport(void); 18862306a36Sopenharmony_ciint efct_scsi_new_device(struct efct *efct); 18962306a36Sopenharmony_civoid efct_scsi_del_device(struct efct *efct); 19062306a36Sopenharmony_civoid _efct_scsi_io_free(struct kref *arg); 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ciint 19362306a36Sopenharmony_ciefct_scsi_del_vport(struct efct *efct, struct Scsi_Host *shost); 19462306a36Sopenharmony_cistruct efct_vport * 19562306a36Sopenharmony_ciefct_scsi_new_vport(struct efct *efct, struct device *dev); 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ciint efct_scsi_io_dispatch(struct efct_io *io, void *cb); 19862306a36Sopenharmony_ciint efct_scsi_io_dispatch_abort(struct efct_io *io, void *cb); 19962306a36Sopenharmony_civoid efct_scsi_check_pending(struct efct *efct); 20062306a36Sopenharmony_cistruct efct_io * 20162306a36Sopenharmony_ciefct_bls_send_rjt(struct efct_io *io, struct fc_frame_header *hdr); 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci#endif /* __EFCT_SCSI_H__ */ 204