18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * QLogic iSCSI Offload Driver
48c2ecf20Sopenharmony_ci * Copyright (c) 2016 Cavium Inc.
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#ifndef _QEDI_ISCSI_H_
88c2ecf20Sopenharmony_ci#define _QEDI_ISCSI_H_
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/socket.h>
118c2ecf20Sopenharmony_ci#include <linux/completion.h>
128c2ecf20Sopenharmony_ci#include "qedi.h"
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#define ISCSI_MAX_SESS_PER_HBA	4096
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#define DEF_KA_TIMEOUT		7200000
178c2ecf20Sopenharmony_ci#define DEF_KA_INTERVAL		10000
188c2ecf20Sopenharmony_ci#define DEF_KA_MAX_PROBE_COUNT	10
198c2ecf20Sopenharmony_ci#define DEF_TOS			0
208c2ecf20Sopenharmony_ci#define DEF_TTL			0xfe
218c2ecf20Sopenharmony_ci#define DEF_SND_SEQ_SCALE	0
228c2ecf20Sopenharmony_ci#define DEF_RCV_BUF		0xffff
238c2ecf20Sopenharmony_ci#define DEF_SND_BUF		0xffff
248c2ecf20Sopenharmony_ci#define DEF_SEED		0
258c2ecf20Sopenharmony_ci#define DEF_MAX_RT_TIME		8000
268c2ecf20Sopenharmony_ci#define DEF_MAX_DA_COUNT        2
278c2ecf20Sopenharmony_ci#define DEF_SWS_TIMER		1000
288c2ecf20Sopenharmony_ci#define DEF_MAX_CWND		2
298c2ecf20Sopenharmony_ci#define DEF_PATH_MTU		1500
308c2ecf20Sopenharmony_ci#define DEF_MSS			1460
318c2ecf20Sopenharmony_ci#define DEF_LL2_MTU		1560
328c2ecf20Sopenharmony_ci#define JUMBO_MTU		9000
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#define MIN_MTU         576 /* rfc 793 */
358c2ecf20Sopenharmony_ci#define IPV4_HDR_LEN    20
368c2ecf20Sopenharmony_ci#define IPV6_HDR_LEN    40
378c2ecf20Sopenharmony_ci#define TCP_HDR_LEN     20
388c2ecf20Sopenharmony_ci#define TCP_OPTION_LEN  12
398c2ecf20Sopenharmony_ci#define VLAN_LEN         4
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_cienum {
428c2ecf20Sopenharmony_ci	EP_STATE_IDLE                   = 0x0,
438c2ecf20Sopenharmony_ci	EP_STATE_ACQRCONN_START         = 0x1,
448c2ecf20Sopenharmony_ci	EP_STATE_ACQRCONN_COMPL         = 0x2,
458c2ecf20Sopenharmony_ci	EP_STATE_OFLDCONN_START         = 0x4,
468c2ecf20Sopenharmony_ci	EP_STATE_OFLDCONN_COMPL         = 0x8,
478c2ecf20Sopenharmony_ci	EP_STATE_DISCONN_START          = 0x10,
488c2ecf20Sopenharmony_ci	EP_STATE_DISCONN_COMPL          = 0x20,
498c2ecf20Sopenharmony_ci	EP_STATE_CLEANUP_START          = 0x40,
508c2ecf20Sopenharmony_ci	EP_STATE_CLEANUP_CMPL           = 0x80,
518c2ecf20Sopenharmony_ci	EP_STATE_TCP_FIN_RCVD           = 0x100,
528c2ecf20Sopenharmony_ci	EP_STATE_TCP_RST_RCVD           = 0x200,
538c2ecf20Sopenharmony_ci	EP_STATE_LOGOUT_SENT            = 0x400,
548c2ecf20Sopenharmony_ci	EP_STATE_LOGOUT_RESP_RCVD       = 0x800,
558c2ecf20Sopenharmony_ci	EP_STATE_CLEANUP_FAILED         = 0x1000,
568c2ecf20Sopenharmony_ci	EP_STATE_OFLDCONN_FAILED        = 0x2000,
578c2ecf20Sopenharmony_ci	EP_STATE_CONNECT_FAILED         = 0x4000,
588c2ecf20Sopenharmony_ci	EP_STATE_DISCONN_TIMEDOUT       = 0x8000,
598c2ecf20Sopenharmony_ci	EP_STATE_OFLDCONN_NONE          = 0x10000,
608c2ecf20Sopenharmony_ci};
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_cistruct qedi_conn;
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_cistruct qedi_endpoint {
658c2ecf20Sopenharmony_ci	struct qedi_ctx *qedi;
668c2ecf20Sopenharmony_ci	u32 dst_addr[4];
678c2ecf20Sopenharmony_ci	u32 src_addr[4];
688c2ecf20Sopenharmony_ci	u16 src_port;
698c2ecf20Sopenharmony_ci	u16 dst_port;
708c2ecf20Sopenharmony_ci	u16 vlan_id;
718c2ecf20Sopenharmony_ci	u16 pmtu;
728c2ecf20Sopenharmony_ci	u8 src_mac[ETH_ALEN];
738c2ecf20Sopenharmony_ci	u8 dst_mac[ETH_ALEN];
748c2ecf20Sopenharmony_ci	u8 ip_type;
758c2ecf20Sopenharmony_ci	int state;
768c2ecf20Sopenharmony_ci	wait_queue_head_t ofld_wait;
778c2ecf20Sopenharmony_ci	wait_queue_head_t tcp_ofld_wait;
788c2ecf20Sopenharmony_ci	u32 iscsi_cid;
798c2ecf20Sopenharmony_ci	/* identifier of the connection from qed */
808c2ecf20Sopenharmony_ci	u32 handle;
818c2ecf20Sopenharmony_ci	u32 fw_cid;
828c2ecf20Sopenharmony_ci	void __iomem *p_doorbell;
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	/* Send queue management */
858c2ecf20Sopenharmony_ci	struct iscsi_wqe *sq;
868c2ecf20Sopenharmony_ci	dma_addr_t sq_dma;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	u16 sq_prod_idx;
898c2ecf20Sopenharmony_ci	u16 fw_sq_prod_idx;
908c2ecf20Sopenharmony_ci	u16 sq_con_idx;
918c2ecf20Sopenharmony_ci	u32 sq_mem_size;
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	void *sq_pbl;
948c2ecf20Sopenharmony_ci	dma_addr_t sq_pbl_dma;
958c2ecf20Sopenharmony_ci	u32 sq_pbl_size;
968c2ecf20Sopenharmony_ci	struct qedi_conn *conn;
978c2ecf20Sopenharmony_ci	struct work_struct offload_work;
988c2ecf20Sopenharmony_ci};
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci#define QEDI_SQ_WQES_MIN	16
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_cistruct qedi_io_bdt {
1038c2ecf20Sopenharmony_ci	struct scsi_sge *sge_tbl;
1048c2ecf20Sopenharmony_ci	dma_addr_t sge_tbl_dma;
1058c2ecf20Sopenharmony_ci	u16 sge_valid;
1068c2ecf20Sopenharmony_ci};
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci/**
1098c2ecf20Sopenharmony_ci * struct generic_pdu_resc - login pdu resource structure
1108c2ecf20Sopenharmony_ci *
1118c2ecf20Sopenharmony_ci * @req_buf:            driver buffer used to stage payload associated with
1128c2ecf20Sopenharmony_ci *                      the login request
1138c2ecf20Sopenharmony_ci * @req_dma_addr:       dma address for iscsi login request payload buffer
1148c2ecf20Sopenharmony_ci * @req_buf_size:       actual login request payload length
1158c2ecf20Sopenharmony_ci * @req_wr_ptr:         pointer into login request buffer when next data is
1168c2ecf20Sopenharmony_ci *                      to be written
1178c2ecf20Sopenharmony_ci * @resp_hdr:           iscsi header where iscsi login response header is to
1188c2ecf20Sopenharmony_ci *                      be recreated
1198c2ecf20Sopenharmony_ci * @resp_buf:           buffer to stage login response payload
1208c2ecf20Sopenharmony_ci * @resp_dma_addr:      login response payload buffer dma address
1218c2ecf20Sopenharmony_ci * @resp_buf_size:      login response paylod length
1228c2ecf20Sopenharmony_ci * @resp_wr_ptr:        pointer into login response buffer when next data is
1238c2ecf20Sopenharmony_ci *                      to be written
1248c2ecf20Sopenharmony_ci * @req_bd_tbl:         iscsi login request payload BD table
1258c2ecf20Sopenharmony_ci * @req_bd_dma:         login request BD table dma address
1268c2ecf20Sopenharmony_ci * @resp_bd_tbl:        iscsi login response payload BD table
1278c2ecf20Sopenharmony_ci * @resp_bd_dma:        login request BD table dma address
1288c2ecf20Sopenharmony_ci *
1298c2ecf20Sopenharmony_ci * following structure defines buffer info for generic pdus such as iSCSI Login,
1308c2ecf20Sopenharmony_ci *      Logout and NOP
1318c2ecf20Sopenharmony_ci */
1328c2ecf20Sopenharmony_cistruct generic_pdu_resc {
1338c2ecf20Sopenharmony_ci	char *req_buf;
1348c2ecf20Sopenharmony_ci	dma_addr_t req_dma_addr;
1358c2ecf20Sopenharmony_ci	u32 req_buf_size;
1368c2ecf20Sopenharmony_ci	char *req_wr_ptr;
1378c2ecf20Sopenharmony_ci	struct iscsi_hdr resp_hdr;
1388c2ecf20Sopenharmony_ci	char *resp_buf;
1398c2ecf20Sopenharmony_ci	dma_addr_t resp_dma_addr;
1408c2ecf20Sopenharmony_ci	u32 resp_buf_size;
1418c2ecf20Sopenharmony_ci	char *resp_wr_ptr;
1428c2ecf20Sopenharmony_ci	char *req_bd_tbl;
1438c2ecf20Sopenharmony_ci	dma_addr_t req_bd_dma;
1448c2ecf20Sopenharmony_ci	char *resp_bd_tbl;
1458c2ecf20Sopenharmony_ci	dma_addr_t resp_bd_dma;
1468c2ecf20Sopenharmony_ci};
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cistruct qedi_conn {
1498c2ecf20Sopenharmony_ci	struct iscsi_cls_conn *cls_conn;
1508c2ecf20Sopenharmony_ci	struct qedi_ctx *qedi;
1518c2ecf20Sopenharmony_ci	struct qedi_endpoint *ep;
1528c2ecf20Sopenharmony_ci	struct iscsi_endpoint *iscsi_ep;
1538c2ecf20Sopenharmony_ci	struct list_head active_cmd_list;
1548c2ecf20Sopenharmony_ci	spinlock_t list_lock;		/* internal conn lock */
1558c2ecf20Sopenharmony_ci	u32 active_cmd_count;
1568c2ecf20Sopenharmony_ci	u32 cmd_cleanup_req;
1578c2ecf20Sopenharmony_ci	u32 cmd_cleanup_cmpl;
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	u32 iscsi_conn_id;
1608c2ecf20Sopenharmony_ci	int itt;
1618c2ecf20Sopenharmony_ci	int abrt_conn;
1628c2ecf20Sopenharmony_ci#define QEDI_CID_RESERVED	0x5AFF
1638c2ecf20Sopenharmony_ci	u32 fw_cid;
1648c2ecf20Sopenharmony_ci	/*
1658c2ecf20Sopenharmony_ci	 * Buffer for login negotiation process
1668c2ecf20Sopenharmony_ci	 */
1678c2ecf20Sopenharmony_ci	struct generic_pdu_resc gen_pdu;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	struct list_head tmf_work_list;
1708c2ecf20Sopenharmony_ci	wait_queue_head_t wait_queue;
1718c2ecf20Sopenharmony_ci	spinlock_t tmf_work_lock;	/* tmf work lock */
1728c2ecf20Sopenharmony_ci	unsigned long flags;
1738c2ecf20Sopenharmony_ci#define QEDI_CONN_FW_CLEANUP	1
1748c2ecf20Sopenharmony_ci};
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_cistruct qedi_cmd {
1778c2ecf20Sopenharmony_ci	struct list_head io_cmd;
1788c2ecf20Sopenharmony_ci	bool io_cmd_in_list;
1798c2ecf20Sopenharmony_ci	struct iscsi_hdr hdr;
1808c2ecf20Sopenharmony_ci	struct qedi_conn *conn;
1818c2ecf20Sopenharmony_ci	struct scsi_cmnd *scsi_cmd;
1828c2ecf20Sopenharmony_ci	struct scatterlist *sg;
1838c2ecf20Sopenharmony_ci	struct qedi_io_bdt io_tbl;
1848c2ecf20Sopenharmony_ci	struct e4_iscsi_task_context request;
1858c2ecf20Sopenharmony_ci	unsigned char *sense_buffer;
1868c2ecf20Sopenharmony_ci	dma_addr_t sense_buffer_dma;
1878c2ecf20Sopenharmony_ci	u16 task_id;
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	/* field populated for tmf work queue */
1908c2ecf20Sopenharmony_ci	struct iscsi_task *task;
1918c2ecf20Sopenharmony_ci	struct work_struct tmf_work;
1928c2ecf20Sopenharmony_ci	int state;
1938c2ecf20Sopenharmony_ci#define CLEANUP_WAIT	1
1948c2ecf20Sopenharmony_ci#define CLEANUP_RECV	2
1958c2ecf20Sopenharmony_ci#define CLEANUP_WAIT_FAILED	3
1968c2ecf20Sopenharmony_ci#define CLEANUP_NOT_REQUIRED	4
1978c2ecf20Sopenharmony_ci#define LUN_RESET_RESPONSE_RECEIVED	5
1988c2ecf20Sopenharmony_ci#define RESPONSE_RECEIVED	6
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	int type;
2018c2ecf20Sopenharmony_ci#define TYPEIO		1
2028c2ecf20Sopenharmony_ci#define TYPERESET	2
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci	struct qedi_work_map *list_tmf_work;
2058c2ecf20Sopenharmony_ci	/* slowpath management */
2068c2ecf20Sopenharmony_ci	bool use_slowpath;
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci	struct iscsi_tm_rsp *tmf_resp_buf;
2098c2ecf20Sopenharmony_ci	struct qedi_work cqe_work;
2108c2ecf20Sopenharmony_ci};
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_cistruct qedi_work_map {
2138c2ecf20Sopenharmony_ci	struct list_head list;
2148c2ecf20Sopenharmony_ci	struct qedi_cmd *qedi_cmd;
2158c2ecf20Sopenharmony_ci	int rtid;
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ci	int state;
2188c2ecf20Sopenharmony_ci#define QEDI_WORK_QUEUED	1
2198c2ecf20Sopenharmony_ci#define QEDI_WORK_SCHEDULED	2
2208c2ecf20Sopenharmony_ci#define QEDI_WORK_EXIT		3
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	struct work_struct *ptr_tmf_work;
2238c2ecf20Sopenharmony_ci};
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_cistruct qedi_boot_target {
2268c2ecf20Sopenharmony_ci	char ip_addr[64];
2278c2ecf20Sopenharmony_ci	char iscsi_name[255];
2288c2ecf20Sopenharmony_ci	u32 ipv6_en;
2298c2ecf20Sopenharmony_ci};
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci#define qedi_set_itt(task_id, itt) ((u32)(((task_id) & 0xffff) | ((itt) << 16)))
2328c2ecf20Sopenharmony_ci#define qedi_get_itt(cqe) (cqe.iscsi_hdr.cmd.itt >> 16)
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci#define QEDI_OFLD_WAIT_STATE(q) ((q)->state == EP_STATE_OFLDCONN_FAILED || \
2358c2ecf20Sopenharmony_ci				(q)->state == EP_STATE_OFLDCONN_COMPL)
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci#endif /* _QEDI_ISCSI_H_ */
238