1*d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 29730ffcbSVarun Prakash /* 39730ffcbSVarun Prakash * Copyright (c) 2016 Chelsio Communications, Inc. 49730ffcbSVarun Prakash */ 59730ffcbSVarun Prakash 69730ffcbSVarun Prakash #ifndef __CXGBIT_H__ 79730ffcbSVarun Prakash #define __CXGBIT_H__ 89730ffcbSVarun Prakash 99730ffcbSVarun Prakash #include <linux/mutex.h> 109730ffcbSVarun Prakash #include <linux/list.h> 119730ffcbSVarun Prakash #include <linux/spinlock.h> 129730ffcbSVarun Prakash #include <linux/idr.h> 139730ffcbSVarun Prakash #include <linux/completion.h> 149730ffcbSVarun Prakash #include <linux/netdevice.h> 159730ffcbSVarun Prakash #include <linux/sched.h> 169730ffcbSVarun Prakash #include <linux/pci.h> 179730ffcbSVarun Prakash #include <linux/dma-mapping.h> 189730ffcbSVarun Prakash #include <linux/inet.h> 199730ffcbSVarun Prakash #include <linux/wait.h> 209730ffcbSVarun Prakash #include <linux/kref.h> 219730ffcbSVarun Prakash #include <linux/timer.h> 229730ffcbSVarun Prakash #include <linux/io.h> 239730ffcbSVarun Prakash 249730ffcbSVarun Prakash #include <asm/byteorder.h> 259730ffcbSVarun Prakash 269730ffcbSVarun Prakash #include <net/net_namespace.h> 279730ffcbSVarun Prakash 289730ffcbSVarun Prakash #include <target/iscsi/iscsi_transport.h> 299730ffcbSVarun Prakash #include <iscsi_target_parameters.h> 309730ffcbSVarun Prakash #include <iscsi_target_login.h> 319730ffcbSVarun Prakash 329730ffcbSVarun Prakash #include "t4_regs.h" 339730ffcbSVarun Prakash #include "t4_msg.h" 349730ffcbSVarun Prakash #include "cxgb4.h" 359730ffcbSVarun Prakash #include "cxgb4_uld.h" 369730ffcbSVarun Prakash #include "l2t.h" 37b8b9d81bSVarun Prakash #include "libcxgb_ppm.h" 389730ffcbSVarun Prakash #include "cxgbit_lro.h" 399730ffcbSVarun Prakash 409730ffcbSVarun Prakash extern struct mutex cdev_list_lock; 419730ffcbSVarun Prakash extern struct list_head cdev_list_head; 429730ffcbSVarun Prakash struct cxgbit_np; 439730ffcbSVarun Prakash 449730ffcbSVarun Prakash struct cxgbit_sock; 459730ffcbSVarun Prakash 469730ffcbSVarun Prakash struct cxgbit_cmd { 479730ffcbSVarun Prakash struct scatterlist sg; 489730ffcbSVarun Prakash struct cxgbi_task_tag_info ttinfo; 499730ffcbSVarun Prakash bool setup_ddp; 509730ffcbSVarun Prakash bool release; 519730ffcbSVarun Prakash }; 529730ffcbSVarun Prakash 539730ffcbSVarun Prakash #define CXGBIT_MAX_ISO_PAYLOAD \ 549730ffcbSVarun Prakash min_t(u32, MAX_SKB_FRAGS * PAGE_SIZE, 65535) 559730ffcbSVarun Prakash 569730ffcbSVarun Prakash struct cxgbit_iso_info { 579730ffcbSVarun Prakash u8 flags; 589730ffcbSVarun Prakash u32 mpdu; 599730ffcbSVarun Prakash u32 len; 609730ffcbSVarun Prakash u32 burst_len; 619730ffcbSVarun Prakash }; 629730ffcbSVarun Prakash 639730ffcbSVarun Prakash enum cxgbit_skcb_flags { 649730ffcbSVarun Prakash SKCBF_TX_NEED_HDR = (1 << 0), /* packet needs a header */ 659730ffcbSVarun Prakash SKCBF_TX_FLAG_COMPL = (1 << 1), /* wr completion flag */ 669730ffcbSVarun Prakash SKCBF_TX_ISO = (1 << 2), /* iso cpl in tx skb */ 679730ffcbSVarun Prakash SKCBF_RX_LRO = (1 << 3), /* lro skb */ 689730ffcbSVarun Prakash }; 699730ffcbSVarun Prakash 709730ffcbSVarun Prakash struct cxgbit_skb_rx_cb { 719730ffcbSVarun Prakash u8 opcode; 729730ffcbSVarun Prakash void *pdu_cb; 739730ffcbSVarun Prakash void (*backlog_fn)(struct cxgbit_sock *, struct sk_buff *); 749730ffcbSVarun Prakash }; 759730ffcbSVarun Prakash 769730ffcbSVarun Prakash struct cxgbit_skb_tx_cb { 779730ffcbSVarun Prakash u8 submode; 789730ffcbSVarun Prakash u32 extra_len; 799730ffcbSVarun Prakash }; 809730ffcbSVarun Prakash 819730ffcbSVarun Prakash union cxgbit_skb_cb { 829730ffcbSVarun Prakash struct { 839730ffcbSVarun Prakash u8 flags; 849730ffcbSVarun Prakash union { 859730ffcbSVarun Prakash struct cxgbit_skb_tx_cb tx; 869730ffcbSVarun Prakash struct cxgbit_skb_rx_cb rx; 879730ffcbSVarun Prakash }; 889730ffcbSVarun Prakash }; 899730ffcbSVarun Prakash 909730ffcbSVarun Prakash struct { 919730ffcbSVarun Prakash /* This member must be first. */ 929730ffcbSVarun Prakash struct l2t_skb_cb l2t; 939730ffcbSVarun Prakash struct sk_buff *wr_next; 949730ffcbSVarun Prakash }; 959730ffcbSVarun Prakash }; 969730ffcbSVarun Prakash 979730ffcbSVarun Prakash #define CXGBIT_SKB_CB(skb) ((union cxgbit_skb_cb *)&((skb)->cb[0])) 989730ffcbSVarun Prakash #define cxgbit_skcb_flags(skb) (CXGBIT_SKB_CB(skb)->flags) 999730ffcbSVarun Prakash #define cxgbit_skcb_submode(skb) (CXGBIT_SKB_CB(skb)->tx.submode) 1009730ffcbSVarun Prakash #define cxgbit_skcb_tx_wr_next(skb) (CXGBIT_SKB_CB(skb)->wr_next) 1019730ffcbSVarun Prakash #define cxgbit_skcb_tx_extralen(skb) (CXGBIT_SKB_CB(skb)->tx.extra_len) 1029730ffcbSVarun Prakash #define cxgbit_skcb_rx_opcode(skb) (CXGBIT_SKB_CB(skb)->rx.opcode) 1039730ffcbSVarun Prakash #define cxgbit_skcb_rx_backlog_fn(skb) (CXGBIT_SKB_CB(skb)->rx.backlog_fn) 1049730ffcbSVarun Prakash #define cxgbit_rx_pdu_cb(skb) (CXGBIT_SKB_CB(skb)->rx.pdu_cb) 1059730ffcbSVarun Prakash 1069730ffcbSVarun Prakash static inline void *cplhdr(struct sk_buff *skb) 1079730ffcbSVarun Prakash { 1089730ffcbSVarun Prakash return skb->data; 1099730ffcbSVarun Prakash } 1109730ffcbSVarun Prakash 1119730ffcbSVarun Prakash enum cxgbit_cdev_flags { 1129730ffcbSVarun Prakash CDEV_STATE_UP = 0, 1139730ffcbSVarun Prakash CDEV_ISO_ENABLE, 1149730ffcbSVarun Prakash CDEV_DDP_ENABLE, 1159730ffcbSVarun Prakash }; 1169730ffcbSVarun Prakash 1179730ffcbSVarun Prakash #define NP_INFO_HASH_SIZE 32 1189730ffcbSVarun Prakash 1199730ffcbSVarun Prakash struct np_info { 1209730ffcbSVarun Prakash struct np_info *next; 1219730ffcbSVarun Prakash struct cxgbit_np *cnp; 1229730ffcbSVarun Prakash unsigned int stid; 1239730ffcbSVarun Prakash }; 1249730ffcbSVarun Prakash 1259730ffcbSVarun Prakash struct cxgbit_list_head { 1269730ffcbSVarun Prakash struct list_head list; 1279730ffcbSVarun Prakash /* device lock */ 1289730ffcbSVarun Prakash spinlock_t lock; 1299730ffcbSVarun Prakash }; 1309730ffcbSVarun Prakash 1319730ffcbSVarun Prakash struct cxgbit_device { 1329730ffcbSVarun Prakash struct list_head list; 1339730ffcbSVarun Prakash struct cxgb4_lld_info lldi; 1349730ffcbSVarun Prakash struct np_info *np_hash_tab[NP_INFO_HASH_SIZE]; 1359730ffcbSVarun Prakash /* np lock */ 1369730ffcbSVarun Prakash spinlock_t np_lock; 1379730ffcbSVarun Prakash u8 selectq[MAX_NPORTS][2]; 1389730ffcbSVarun Prakash struct cxgbit_list_head cskq; 1399730ffcbSVarun Prakash u32 mdsl; 1409730ffcbSVarun Prakash struct kref kref; 1419730ffcbSVarun Prakash unsigned long flags; 1429730ffcbSVarun Prakash }; 1439730ffcbSVarun Prakash 1449730ffcbSVarun Prakash struct cxgbit_wr_wait { 1459730ffcbSVarun Prakash struct completion completion; 1469730ffcbSVarun Prakash int ret; 1479730ffcbSVarun Prakash }; 1489730ffcbSVarun Prakash 1499730ffcbSVarun Prakash enum cxgbit_csk_state { 1509730ffcbSVarun Prakash CSK_STATE_IDLE = 0, 1519730ffcbSVarun Prakash CSK_STATE_LISTEN, 1529730ffcbSVarun Prakash CSK_STATE_CONNECTING, 1539730ffcbSVarun Prakash CSK_STATE_ESTABLISHED, 1549730ffcbSVarun Prakash CSK_STATE_ABORTING, 1559730ffcbSVarun Prakash CSK_STATE_CLOSING, 1569730ffcbSVarun Prakash CSK_STATE_MORIBUND, 1579730ffcbSVarun Prakash CSK_STATE_DEAD, 1589730ffcbSVarun Prakash }; 1599730ffcbSVarun Prakash 1609730ffcbSVarun Prakash enum cxgbit_csk_flags { 1619730ffcbSVarun Prakash CSK_TX_DATA_SENT = 0, 1629730ffcbSVarun Prakash CSK_LOGIN_PDU_DONE, 1639730ffcbSVarun Prakash CSK_LOGIN_DONE, 1649730ffcbSVarun Prakash CSK_DDP_ENABLE, 1651ae01724SVarun Prakash CSK_ABORT_RPL_WAIT, 1669730ffcbSVarun Prakash }; 1679730ffcbSVarun Prakash 1689730ffcbSVarun Prakash struct cxgbit_sock_common { 1699730ffcbSVarun Prakash struct cxgbit_device *cdev; 1709730ffcbSVarun Prakash struct sockaddr_storage local_addr; 1719730ffcbSVarun Prakash struct sockaddr_storage remote_addr; 1729730ffcbSVarun Prakash struct cxgbit_wr_wait wr_wait; 1739730ffcbSVarun Prakash enum cxgbit_csk_state state; 1749730ffcbSVarun Prakash unsigned long flags; 1759730ffcbSVarun Prakash }; 1769730ffcbSVarun Prakash 1779730ffcbSVarun Prakash struct cxgbit_np { 1789730ffcbSVarun Prakash struct cxgbit_sock_common com; 1799730ffcbSVarun Prakash wait_queue_head_t accept_wait; 1809730ffcbSVarun Prakash struct iscsi_np *np; 1819730ffcbSVarun Prakash struct completion accept_comp; 1829730ffcbSVarun Prakash struct list_head np_accept_list; 1839730ffcbSVarun Prakash /* np accept lock */ 1849730ffcbSVarun Prakash spinlock_t np_accept_lock; 1859730ffcbSVarun Prakash struct kref kref; 1869730ffcbSVarun Prakash unsigned int stid; 1879730ffcbSVarun Prakash }; 1889730ffcbSVarun Prakash 1899730ffcbSVarun Prakash struct cxgbit_sock { 1909730ffcbSVarun Prakash struct cxgbit_sock_common com; 1919730ffcbSVarun Prakash struct cxgbit_np *cnp; 1929730ffcbSVarun Prakash struct iscsi_conn *conn; 1939730ffcbSVarun Prakash struct l2t_entry *l2t; 1949730ffcbSVarun Prakash struct dst_entry *dst; 1959730ffcbSVarun Prakash struct list_head list; 1969730ffcbSVarun Prakash struct sk_buff_head rxq; 1979730ffcbSVarun Prakash struct sk_buff_head txq; 1989730ffcbSVarun Prakash struct sk_buff_head ppodq; 1999730ffcbSVarun Prakash struct sk_buff_head backlogq; 2009730ffcbSVarun Prakash struct sk_buff_head skbq; 2019730ffcbSVarun Prakash struct sk_buff *wr_pending_head; 2029730ffcbSVarun Prakash struct sk_buff *wr_pending_tail; 2039730ffcbSVarun Prakash struct sk_buff *skb; 2049730ffcbSVarun Prakash struct sk_buff *lro_skb; 2059730ffcbSVarun Prakash struct sk_buff *lro_hskb; 2069730ffcbSVarun Prakash struct list_head accept_node; 2079730ffcbSVarun Prakash /* socket lock */ 2089730ffcbSVarun Prakash spinlock_t lock; 2099730ffcbSVarun Prakash wait_queue_head_t waitq; 2109730ffcbSVarun Prakash wait_queue_head_t ack_waitq; 2119730ffcbSVarun Prakash bool lock_owner; 2129730ffcbSVarun Prakash struct kref kref; 2139730ffcbSVarun Prakash u32 max_iso_npdu; 2149730ffcbSVarun Prakash u32 wr_cred; 2159730ffcbSVarun Prakash u32 wr_una_cred; 2169730ffcbSVarun Prakash u32 wr_max_cred; 2179730ffcbSVarun Prakash u32 snd_una; 2189730ffcbSVarun Prakash u32 tid; 2199730ffcbSVarun Prakash u32 snd_nxt; 2209730ffcbSVarun Prakash u32 rcv_nxt; 2219730ffcbSVarun Prakash u32 smac_idx; 2229730ffcbSVarun Prakash u32 tx_chan; 2239730ffcbSVarun Prakash u32 mtu; 2249730ffcbSVarun Prakash u32 write_seq; 2259730ffcbSVarun Prakash u32 rx_credits; 2269730ffcbSVarun Prakash u32 snd_win; 2279730ffcbSVarun Prakash u32 rcv_win; 2289730ffcbSVarun Prakash u16 mss; 2299730ffcbSVarun Prakash u16 emss; 2309730ffcbSVarun Prakash u16 plen; 2319730ffcbSVarun Prakash u16 rss_qid; 2329730ffcbSVarun Prakash u16 txq_idx; 2339730ffcbSVarun Prakash u16 ctrlq_idx; 2349730ffcbSVarun Prakash u8 tos; 2359730ffcbSVarun Prakash u8 port_id; 2369730ffcbSVarun Prakash #define CXGBIT_SUBMODE_HCRC 0x1 2379730ffcbSVarun Prakash #define CXGBIT_SUBMODE_DCRC 0x2 2389730ffcbSVarun Prakash u8 submode; 2399730ffcbSVarun Prakash #ifdef CONFIG_CHELSIO_T4_DCB 2409730ffcbSVarun Prakash u8 dcb_priority; 2419730ffcbSVarun Prakash #endif 2429730ffcbSVarun Prakash u8 snd_wscale; 2439730ffcbSVarun Prakash }; 2449730ffcbSVarun Prakash 2459730ffcbSVarun Prakash void _cxgbit_free_cdev(struct kref *kref); 2469730ffcbSVarun Prakash void _cxgbit_free_csk(struct kref *kref); 2479730ffcbSVarun Prakash void _cxgbit_free_cnp(struct kref *kref); 2489730ffcbSVarun Prakash 2499730ffcbSVarun Prakash static inline void cxgbit_get_cdev(struct cxgbit_device *cdev) 2509730ffcbSVarun Prakash { 2519730ffcbSVarun Prakash kref_get(&cdev->kref); 2529730ffcbSVarun Prakash } 2539730ffcbSVarun Prakash 2549730ffcbSVarun Prakash static inline void cxgbit_put_cdev(struct cxgbit_device *cdev) 2559730ffcbSVarun Prakash { 2569730ffcbSVarun Prakash kref_put(&cdev->kref, _cxgbit_free_cdev); 2579730ffcbSVarun Prakash } 2589730ffcbSVarun Prakash 2599730ffcbSVarun Prakash static inline void cxgbit_get_csk(struct cxgbit_sock *csk) 2609730ffcbSVarun Prakash { 2619730ffcbSVarun Prakash kref_get(&csk->kref); 2629730ffcbSVarun Prakash } 2639730ffcbSVarun Prakash 2649730ffcbSVarun Prakash static inline void cxgbit_put_csk(struct cxgbit_sock *csk) 2659730ffcbSVarun Prakash { 2669730ffcbSVarun Prakash kref_put(&csk->kref, _cxgbit_free_csk); 2679730ffcbSVarun Prakash } 2689730ffcbSVarun Prakash 2699730ffcbSVarun Prakash static inline void cxgbit_get_cnp(struct cxgbit_np *cnp) 2709730ffcbSVarun Prakash { 2719730ffcbSVarun Prakash kref_get(&cnp->kref); 2729730ffcbSVarun Prakash } 2739730ffcbSVarun Prakash 2749730ffcbSVarun Prakash static inline void cxgbit_put_cnp(struct cxgbit_np *cnp) 2759730ffcbSVarun Prakash { 2769730ffcbSVarun Prakash kref_put(&cnp->kref, _cxgbit_free_cnp); 2779730ffcbSVarun Prakash } 2789730ffcbSVarun Prakash 2799730ffcbSVarun Prakash static inline void cxgbit_sock_reset_wr_list(struct cxgbit_sock *csk) 2809730ffcbSVarun Prakash { 2819730ffcbSVarun Prakash csk->wr_pending_tail = NULL; 2829730ffcbSVarun Prakash csk->wr_pending_head = NULL; 2839730ffcbSVarun Prakash } 2849730ffcbSVarun Prakash 2859730ffcbSVarun Prakash static inline struct sk_buff *cxgbit_sock_peek_wr(const struct cxgbit_sock *csk) 2869730ffcbSVarun Prakash { 2879730ffcbSVarun Prakash return csk->wr_pending_head; 2889730ffcbSVarun Prakash } 2899730ffcbSVarun Prakash 2909730ffcbSVarun Prakash static inline void 2919730ffcbSVarun Prakash cxgbit_sock_enqueue_wr(struct cxgbit_sock *csk, struct sk_buff *skb) 2929730ffcbSVarun Prakash { 2939730ffcbSVarun Prakash cxgbit_skcb_tx_wr_next(skb) = NULL; 2949730ffcbSVarun Prakash 2959730ffcbSVarun Prakash skb_get(skb); 2969730ffcbSVarun Prakash 2979730ffcbSVarun Prakash if (!csk->wr_pending_head) 2989730ffcbSVarun Prakash csk->wr_pending_head = skb; 2999730ffcbSVarun Prakash else 3009730ffcbSVarun Prakash cxgbit_skcb_tx_wr_next(csk->wr_pending_tail) = skb; 3019730ffcbSVarun Prakash csk->wr_pending_tail = skb; 3029730ffcbSVarun Prakash } 3039730ffcbSVarun Prakash 3049730ffcbSVarun Prakash static inline struct sk_buff *cxgbit_sock_dequeue_wr(struct cxgbit_sock *csk) 3059730ffcbSVarun Prakash { 3069730ffcbSVarun Prakash struct sk_buff *skb = csk->wr_pending_head; 3079730ffcbSVarun Prakash 3089730ffcbSVarun Prakash if (likely(skb)) { 3099730ffcbSVarun Prakash csk->wr_pending_head = cxgbit_skcb_tx_wr_next(skb); 3109730ffcbSVarun Prakash cxgbit_skcb_tx_wr_next(skb) = NULL; 3119730ffcbSVarun Prakash } 3129730ffcbSVarun Prakash return skb; 3139730ffcbSVarun Prakash } 3149730ffcbSVarun Prakash 3159730ffcbSVarun Prakash typedef void (*cxgbit_cplhandler_func)(struct cxgbit_device *, 3169730ffcbSVarun Prakash struct sk_buff *); 3179730ffcbSVarun Prakash 3189730ffcbSVarun Prakash int cxgbit_setup_np(struct iscsi_np *, struct sockaddr_storage *); 3199730ffcbSVarun Prakash int cxgbit_setup_conn_digest(struct cxgbit_sock *); 3209730ffcbSVarun Prakash int cxgbit_accept_np(struct iscsi_np *, struct iscsi_conn *); 3219730ffcbSVarun Prakash void cxgbit_free_np(struct iscsi_np *); 3221ae01724SVarun Prakash void cxgbit_abort_conn(struct cxgbit_sock *csk); 3239730ffcbSVarun Prakash void cxgbit_free_conn(struct iscsi_conn *); 3249730ffcbSVarun Prakash extern cxgbit_cplhandler_func cxgbit_cplhandlers[NUM_CPL_CMDS]; 3259730ffcbSVarun Prakash int cxgbit_get_login_rx(struct iscsi_conn *, struct iscsi_login *); 3269730ffcbSVarun Prakash int cxgbit_rx_data_ack(struct cxgbit_sock *); 3279730ffcbSVarun Prakash int cxgbit_l2t_send(struct cxgbit_device *, struct sk_buff *, 3289730ffcbSVarun Prakash struct l2t_entry *); 3299730ffcbSVarun Prakash void cxgbit_push_tx_frames(struct cxgbit_sock *); 3309730ffcbSVarun Prakash int cxgbit_put_login_tx(struct iscsi_conn *, struct iscsi_login *, u32); 3319730ffcbSVarun Prakash int cxgbit_xmit_pdu(struct iscsi_conn *, struct iscsi_cmd *, 3329730ffcbSVarun Prakash struct iscsi_datain_req *, const void *, u32); 3339730ffcbSVarun Prakash void cxgbit_get_r2t_ttt(struct iscsi_conn *, struct iscsi_cmd *, 3349730ffcbSVarun Prakash struct iscsi_r2t *); 3359730ffcbSVarun Prakash u32 cxgbit_send_tx_flowc_wr(struct cxgbit_sock *); 3369730ffcbSVarun Prakash int cxgbit_ofld_send(struct cxgbit_device *, struct sk_buff *); 3379730ffcbSVarun Prakash void cxgbit_get_rx_pdu(struct iscsi_conn *); 3389730ffcbSVarun Prakash int cxgbit_validate_params(struct iscsi_conn *); 3399730ffcbSVarun Prakash struct cxgbit_device *cxgbit_find_device(struct net_device *, u8 *); 3409730ffcbSVarun Prakash 3419730ffcbSVarun Prakash /* DDP */ 3429730ffcbSVarun Prakash int cxgbit_ddp_init(struct cxgbit_device *); 3439730ffcbSVarun Prakash int cxgbit_setup_conn_pgidx(struct cxgbit_sock *, u32); 3449730ffcbSVarun Prakash int cxgbit_reserve_ttt(struct cxgbit_sock *, struct iscsi_cmd *); 3451e65cc16SBart Van Assche void cxgbit_unmap_cmd(struct iscsi_conn *, struct iscsi_cmd *); 3469730ffcbSVarun Prakash 3479730ffcbSVarun Prakash static inline 3489730ffcbSVarun Prakash struct cxgbi_ppm *cdev2ppm(struct cxgbit_device *cdev) 3499730ffcbSVarun Prakash { 3509730ffcbSVarun Prakash return (struct cxgbi_ppm *)(*cdev->lldi.iscsi_ppm); 3519730ffcbSVarun Prakash } 3529730ffcbSVarun Prakash #endif /* __CXGBIT_H__ */ 353