19ba682f0Skxie@chelsio.com /* 29ba682f0Skxie@chelsio.com * libcxgbi.h: Chelsio common library for T3/T4 iSCSI driver. 39ba682f0Skxie@chelsio.com * 49ba682f0Skxie@chelsio.com * Copyright (c) 2010 Chelsio Communications, Inc. 59ba682f0Skxie@chelsio.com * 69ba682f0Skxie@chelsio.com * This program is free software; you can redistribute it and/or modify 79ba682f0Skxie@chelsio.com * it under the terms of the GNU General Public License as published by 89ba682f0Skxie@chelsio.com * the Free Software Foundation. 99ba682f0Skxie@chelsio.com * 109ba682f0Skxie@chelsio.com * Written by: Karen Xie (kxie@chelsio.com) 119ba682f0Skxie@chelsio.com * Written by: Rakesh Ranjan (rranjan@chelsio.com) 129ba682f0Skxie@chelsio.com */ 139ba682f0Skxie@chelsio.com 149ba682f0Skxie@chelsio.com #ifndef __LIBCXGBI_H__ 159ba682f0Skxie@chelsio.com #define __LIBCXGBI_H__ 169ba682f0Skxie@chelsio.com 179ba682f0Skxie@chelsio.com #include <linux/kernel.h> 189ba682f0Skxie@chelsio.com #include <linux/errno.h> 199ba682f0Skxie@chelsio.com #include <linux/types.h> 209ba682f0Skxie@chelsio.com #include <linux/debugfs.h> 219ba682f0Skxie@chelsio.com #include <linux/list.h> 229ba682f0Skxie@chelsio.com #include <linux/netdevice.h> 239ba682f0Skxie@chelsio.com #include <linux/if_vlan.h> 249ba682f0Skxie@chelsio.com #include <linux/scatterlist.h> 259ba682f0Skxie@chelsio.com #include <linux/skbuff.h> 269ba682f0Skxie@chelsio.com #include <linux/vmalloc.h> 279ba682f0Skxie@chelsio.com #include <scsi/scsi_device.h> 289ba682f0Skxie@chelsio.com #include <scsi/libiscsi_tcp.h> 299ba682f0Skxie@chelsio.com 309ba682f0Skxie@chelsio.com enum cxgbi_dbg_flag { 319ba682f0Skxie@chelsio.com CXGBI_DBG_ISCSI, 329ba682f0Skxie@chelsio.com CXGBI_DBG_DDP, 339ba682f0Skxie@chelsio.com CXGBI_DBG_TOE, 349ba682f0Skxie@chelsio.com CXGBI_DBG_SOCK, 359ba682f0Skxie@chelsio.com 369ba682f0Skxie@chelsio.com CXGBI_DBG_PDU_TX, 379ba682f0Skxie@chelsio.com CXGBI_DBG_PDU_RX, 389ba682f0Skxie@chelsio.com CXGBI_DBG_DEV, 399ba682f0Skxie@chelsio.com }; 409ba682f0Skxie@chelsio.com 419ba682f0Skxie@chelsio.com #define log_debug(level, fmt, ...) \ 429ba682f0Skxie@chelsio.com do { \ 439ba682f0Skxie@chelsio.com if (dbg_level & (level)) \ 449ba682f0Skxie@chelsio.com pr_info(fmt, ##__VA_ARGS__); \ 459ba682f0Skxie@chelsio.com } while (0) 469ba682f0Skxie@chelsio.com 47fc8d0590SAnish Bhatt #define pr_info_ipaddr(fmt_trail, \ 48fc8d0590SAnish Bhatt addr1, addr2, args_trail...) \ 49fc8d0590SAnish Bhatt do { \ 50fc8d0590SAnish Bhatt if (!((1 << CXGBI_DBG_SOCK) & dbg_level)) \ 51fc8d0590SAnish Bhatt break; \ 52fc8d0590SAnish Bhatt pr_info("%pISpc - %pISpc, " fmt_trail, \ 53fc8d0590SAnish Bhatt addr1, addr2, args_trail); \ 54fc8d0590SAnish Bhatt } while (0) 55fc8d0590SAnish Bhatt 569ba682f0Skxie@chelsio.com /* max. connections per adapter */ 579ba682f0Skxie@chelsio.com #define CXGBI_MAX_CONN 16384 589ba682f0Skxie@chelsio.com 599ba682f0Skxie@chelsio.com /* always allocate rooms for AHS */ 609ba682f0Skxie@chelsio.com #define SKB_TX_ISCSI_PDU_HEADER_MAX \ 619ba682f0Skxie@chelsio.com (sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE) 629ba682f0Skxie@chelsio.com 639ba682f0Skxie@chelsio.com #define ISCSI_PDU_NONPAYLOAD_LEN 312 /* bhs(48) + ahs(256) + digest(8)*/ 649ba682f0Skxie@chelsio.com 659ba682f0Skxie@chelsio.com /* 669ba682f0Skxie@chelsio.com * align pdu size to multiple of 512 for better performance 679ba682f0Skxie@chelsio.com */ 689ba682f0Skxie@chelsio.com #define cxgbi_align_pdu_size(n) do { n = (n) & (~511); } while (0) 699ba682f0Skxie@chelsio.com 709ba682f0Skxie@chelsio.com #define ULP2_MODE_ISCSI 2 719ba682f0Skxie@chelsio.com 729ba682f0Skxie@chelsio.com #define ULP2_MAX_PKT_SIZE 16224 739ba682f0Skxie@chelsio.com #define ULP2_MAX_PDU_PAYLOAD \ 749ba682f0Skxie@chelsio.com (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_LEN) 759ba682f0Skxie@chelsio.com 769ba682f0Skxie@chelsio.com /* 779ba682f0Skxie@chelsio.com * For iscsi connections HW may inserts digest bytes into the pdu. Those digest 789ba682f0Skxie@chelsio.com * bytes are not sent by the host but are part of the TCP payload and therefore 799ba682f0Skxie@chelsio.com * consume TCP sequence space. 809ba682f0Skxie@chelsio.com */ 819ba682f0Skxie@chelsio.com static const unsigned int ulp2_extra_len[] = { 0, 4, 4, 8 }; 829ba682f0Skxie@chelsio.com static inline unsigned int cxgbi_ulp_extra_len(int submode) 839ba682f0Skxie@chelsio.com { 849ba682f0Skxie@chelsio.com return ulp2_extra_len[submode & 3]; 859ba682f0Skxie@chelsio.com } 869ba682f0Skxie@chelsio.com 879ba682f0Skxie@chelsio.com /* 889ba682f0Skxie@chelsio.com * struct pagepod_hdr, pagepod - pagepod format 899ba682f0Skxie@chelsio.com */ 909ba682f0Skxie@chelsio.com 919ba682f0Skxie@chelsio.com #define CPL_RX_DDP_STATUS_DDP_SHIFT 16 /* ddp'able */ 929ba682f0Skxie@chelsio.com #define CPL_RX_DDP_STATUS_PAD_SHIFT 19 /* pad error */ 939ba682f0Skxie@chelsio.com #define CPL_RX_DDP_STATUS_HCRC_SHIFT 20 /* hcrc error */ 949ba682f0Skxie@chelsio.com #define CPL_RX_DDP_STATUS_DCRC_SHIFT 21 /* dcrc error */ 959ba682f0Skxie@chelsio.com 969ba682f0Skxie@chelsio.com struct cxgbi_pagepod_hdr { 979ba682f0Skxie@chelsio.com u32 vld_tid; 989ba682f0Skxie@chelsio.com u32 pgsz_tag_clr; 999ba682f0Skxie@chelsio.com u32 max_offset; 1009ba682f0Skxie@chelsio.com u32 page_offset; 1019ba682f0Skxie@chelsio.com u64 rsvd; 1029ba682f0Skxie@chelsio.com }; 1039ba682f0Skxie@chelsio.com 1049ba682f0Skxie@chelsio.com #define PPOD_PAGES_MAX 4 1059ba682f0Skxie@chelsio.com struct cxgbi_pagepod { 1069ba682f0Skxie@chelsio.com struct cxgbi_pagepod_hdr hdr; 1079ba682f0Skxie@chelsio.com u64 addr[PPOD_PAGES_MAX + 1]; 1089ba682f0Skxie@chelsio.com }; 1099ba682f0Skxie@chelsio.com 1109ba682f0Skxie@chelsio.com struct cxgbi_tag_format { 1119ba682f0Skxie@chelsio.com unsigned char sw_bits; 1129ba682f0Skxie@chelsio.com unsigned char rsvd_bits; 1139ba682f0Skxie@chelsio.com unsigned char rsvd_shift; 1149ba682f0Skxie@chelsio.com unsigned char filler[1]; 1159ba682f0Skxie@chelsio.com u32 rsvd_mask; 1169ba682f0Skxie@chelsio.com }; 1179ba682f0Skxie@chelsio.com 1189ba682f0Skxie@chelsio.com struct cxgbi_gather_list { 1199ba682f0Skxie@chelsio.com unsigned int tag; 1209ba682f0Skxie@chelsio.com unsigned int length; 1219ba682f0Skxie@chelsio.com unsigned int offset; 1229ba682f0Skxie@chelsio.com unsigned int nelem; 1239ba682f0Skxie@chelsio.com struct page **pages; 1249ba682f0Skxie@chelsio.com dma_addr_t phys_addr[0]; 1259ba682f0Skxie@chelsio.com }; 1269ba682f0Skxie@chelsio.com 1279ba682f0Skxie@chelsio.com struct cxgbi_ddp_info { 1289ba682f0Skxie@chelsio.com struct kref refcnt; 1299ba682f0Skxie@chelsio.com struct cxgbi_device *cdev; 1309ba682f0Skxie@chelsio.com struct pci_dev *pdev; 1319ba682f0Skxie@chelsio.com unsigned int max_txsz; 1329ba682f0Skxie@chelsio.com unsigned int max_rxsz; 1339ba682f0Skxie@chelsio.com unsigned int llimit; 1349ba682f0Skxie@chelsio.com unsigned int ulimit; 1359ba682f0Skxie@chelsio.com unsigned int nppods; 1369ba682f0Skxie@chelsio.com unsigned int idx_last; 1379ba682f0Skxie@chelsio.com unsigned char idx_bits; 1389ba682f0Skxie@chelsio.com unsigned char filler[3]; 1399ba682f0Skxie@chelsio.com unsigned int idx_mask; 1409ba682f0Skxie@chelsio.com unsigned int rsvd_tag_mask; 1419ba682f0Skxie@chelsio.com spinlock_t map_lock; 1429ba682f0Skxie@chelsio.com struct cxgbi_gather_list **gl_map; 1439ba682f0Skxie@chelsio.com }; 1449ba682f0Skxie@chelsio.com 1459ba682f0Skxie@chelsio.com #define DDP_PGIDX_MAX 4 1469ba682f0Skxie@chelsio.com #define DDP_THRESHOLD 2048 1479ba682f0Skxie@chelsio.com 1489ba682f0Skxie@chelsio.com #define PPOD_PAGES_SHIFT 2 /* 4 pages per pod */ 1499ba682f0Skxie@chelsio.com 1509ba682f0Skxie@chelsio.com #define PPOD_SIZE sizeof(struct cxgbi_pagepod) /* 64 */ 1519ba682f0Skxie@chelsio.com #define PPOD_SIZE_SHIFT 6 1529ba682f0Skxie@chelsio.com 1539ba682f0Skxie@chelsio.com #define ULPMEM_DSGL_MAX_NPPODS 16 /* 1024/PPOD_SIZE */ 1549ba682f0Skxie@chelsio.com #define ULPMEM_IDATA_MAX_NPPODS 4 /* 256/PPOD_SIZE */ 1559ba682f0Skxie@chelsio.com #define PCIE_MEMWIN_MAX_NPPODS 16 /* 1024/PPOD_SIZE */ 1569ba682f0Skxie@chelsio.com 1579ba682f0Skxie@chelsio.com #define PPOD_COLOR_SHIFT 0 1589ba682f0Skxie@chelsio.com #define PPOD_COLOR(x) ((x) << PPOD_COLOR_SHIFT) 1599ba682f0Skxie@chelsio.com 1609ba682f0Skxie@chelsio.com #define PPOD_IDX_SHIFT 6 1619ba682f0Skxie@chelsio.com #define PPOD_IDX_MAX_SIZE 24 1629ba682f0Skxie@chelsio.com 1639ba682f0Skxie@chelsio.com #define PPOD_TID_SHIFT 0 1649ba682f0Skxie@chelsio.com #define PPOD_TID(x) ((x) << PPOD_TID_SHIFT) 1659ba682f0Skxie@chelsio.com 1669ba682f0Skxie@chelsio.com #define PPOD_TAG_SHIFT 6 1679ba682f0Skxie@chelsio.com #define PPOD_TAG(x) ((x) << PPOD_TAG_SHIFT) 1689ba682f0Skxie@chelsio.com 1699ba682f0Skxie@chelsio.com #define PPOD_VALID_SHIFT 24 1709ba682f0Skxie@chelsio.com #define PPOD_VALID(x) ((x) << PPOD_VALID_SHIFT) 1719ba682f0Skxie@chelsio.com #define PPOD_VALID_FLAG PPOD_VALID(1U) 1729ba682f0Skxie@chelsio.com 1739ba682f0Skxie@chelsio.com /* 1749ba682f0Skxie@chelsio.com * sge_opaque_hdr - 1759ba682f0Skxie@chelsio.com * Opaque version of structure the SGE stores at skb->head of TX_DATA packets 1769ba682f0Skxie@chelsio.com * and for which we must reserve space. 1779ba682f0Skxie@chelsio.com */ 1789ba682f0Skxie@chelsio.com struct sge_opaque_hdr { 1799ba682f0Skxie@chelsio.com void *dev; 1809ba682f0Skxie@chelsio.com dma_addr_t addr[MAX_SKB_FRAGS + 1]; 1819ba682f0Skxie@chelsio.com }; 1829ba682f0Skxie@chelsio.com 1839ba682f0Skxie@chelsio.com struct cxgbi_sock { 1849ba682f0Skxie@chelsio.com struct cxgbi_device *cdev; 1859ba682f0Skxie@chelsio.com 1869ba682f0Skxie@chelsio.com int tid; 1879ba682f0Skxie@chelsio.com int atid; 1889ba682f0Skxie@chelsio.com unsigned long flags; 1899ba682f0Skxie@chelsio.com unsigned int mtu; 1909ba682f0Skxie@chelsio.com unsigned short rss_qid; 1919ba682f0Skxie@chelsio.com unsigned short txq_idx; 1929ba682f0Skxie@chelsio.com unsigned short advmss; 1939ba682f0Skxie@chelsio.com unsigned int tx_chan; 1949ba682f0Skxie@chelsio.com unsigned int rx_chan; 1959ba682f0Skxie@chelsio.com unsigned int mss_idx; 1969ba682f0Skxie@chelsio.com unsigned int smac_idx; 1979ba682f0Skxie@chelsio.com unsigned char port_id; 1989ba682f0Skxie@chelsio.com int wr_max_cred; 1999ba682f0Skxie@chelsio.com int wr_cred; 2009ba682f0Skxie@chelsio.com int wr_una_cred; 2019ba682f0Skxie@chelsio.com unsigned char hcrc_len; 2029ba682f0Skxie@chelsio.com unsigned char dcrc_len; 2039ba682f0Skxie@chelsio.com 2049ba682f0Skxie@chelsio.com void *l2t; 2059ba682f0Skxie@chelsio.com struct sk_buff *wr_pending_head; 2069ba682f0Skxie@chelsio.com struct sk_buff *wr_pending_tail; 2079ba682f0Skxie@chelsio.com struct sk_buff *cpl_close; 2089ba682f0Skxie@chelsio.com struct sk_buff *cpl_abort_req; 2099ba682f0Skxie@chelsio.com struct sk_buff *cpl_abort_rpl; 2109ba682f0Skxie@chelsio.com struct sk_buff *skb_ulp_lhdr; 2119ba682f0Skxie@chelsio.com spinlock_t lock; 2129ba682f0Skxie@chelsio.com struct kref refcnt; 2139ba682f0Skxie@chelsio.com unsigned int state; 214fc8d0590SAnish Bhatt unsigned int csk_family; 215fc8d0590SAnish Bhatt union { 2169ba682f0Skxie@chelsio.com struct sockaddr_in saddr; 217fc8d0590SAnish Bhatt struct sockaddr_in6 saddr6; 218fc8d0590SAnish Bhatt }; 219fc8d0590SAnish Bhatt union { 2209ba682f0Skxie@chelsio.com struct sockaddr_in daddr; 221fc8d0590SAnish Bhatt struct sockaddr_in6 daddr6; 222fc8d0590SAnish Bhatt }; 2239ba682f0Skxie@chelsio.com struct dst_entry *dst; 2249ba682f0Skxie@chelsio.com struct sk_buff_head receive_queue; 2259ba682f0Skxie@chelsio.com struct sk_buff_head write_queue; 2269ba682f0Skxie@chelsio.com struct timer_list retry_timer; 2279ba682f0Skxie@chelsio.com int err; 2289ba682f0Skxie@chelsio.com rwlock_t callback_lock; 2299ba682f0Skxie@chelsio.com void *user_data; 2309ba682f0Skxie@chelsio.com 2319ba682f0Skxie@chelsio.com u32 rcv_nxt; 2329ba682f0Skxie@chelsio.com u32 copied_seq; 2339ba682f0Skxie@chelsio.com u32 rcv_wup; 2349ba682f0Skxie@chelsio.com u32 snd_nxt; 2359ba682f0Skxie@chelsio.com u32 snd_una; 2369ba682f0Skxie@chelsio.com u32 write_seq; 2379ba682f0Skxie@chelsio.com }; 2389ba682f0Skxie@chelsio.com 2399ba682f0Skxie@chelsio.com /* 2409ba682f0Skxie@chelsio.com * connection states 2419ba682f0Skxie@chelsio.com */ 2429ba682f0Skxie@chelsio.com enum cxgbi_sock_states{ 2439ba682f0Skxie@chelsio.com CTP_CLOSED, 2449ba682f0Skxie@chelsio.com CTP_CONNECTING, 2459ba682f0Skxie@chelsio.com CTP_ACTIVE_OPEN, 2469ba682f0Skxie@chelsio.com CTP_ESTABLISHED, 2479ba682f0Skxie@chelsio.com CTP_ACTIVE_CLOSE, 2489ba682f0Skxie@chelsio.com CTP_PASSIVE_CLOSE, 2499ba682f0Skxie@chelsio.com CTP_CLOSE_WAIT_1, 2509ba682f0Skxie@chelsio.com CTP_CLOSE_WAIT_2, 2519ba682f0Skxie@chelsio.com CTP_ABORTING, 2529ba682f0Skxie@chelsio.com }; 2539ba682f0Skxie@chelsio.com 2549ba682f0Skxie@chelsio.com /* 2559ba682f0Skxie@chelsio.com * Connection flags -- many to track some close related events. 2569ba682f0Skxie@chelsio.com */ 2579ba682f0Skxie@chelsio.com enum cxgbi_sock_flags { 2589ba682f0Skxie@chelsio.com CTPF_ABORT_RPL_RCVD, /*received one ABORT_RPL_RSS message */ 2599ba682f0Skxie@chelsio.com CTPF_ABORT_REQ_RCVD, /*received one ABORT_REQ_RSS message */ 2609ba682f0Skxie@chelsio.com CTPF_ABORT_RPL_PENDING, /* expecting an abort reply */ 2619ba682f0Skxie@chelsio.com CTPF_TX_DATA_SENT, /* already sent a TX_DATA WR */ 2629ba682f0Skxie@chelsio.com CTPF_ACTIVE_CLOSE_NEEDED,/* need to be closed */ 2639ba682f0Skxie@chelsio.com CTPF_HAS_ATID, /* reserved atid */ 2649ba682f0Skxie@chelsio.com CTPF_HAS_TID, /* reserved hw tid */ 2659ba682f0Skxie@chelsio.com CTPF_OFFLOAD_DOWN, /* offload function off */ 2669ba682f0Skxie@chelsio.com }; 2679ba682f0Skxie@chelsio.com 2689ba682f0Skxie@chelsio.com struct cxgbi_skb_rx_cb { 2699ba682f0Skxie@chelsio.com __u32 ddigest; 2709ba682f0Skxie@chelsio.com __u32 pdulen; 2719ba682f0Skxie@chelsio.com }; 2729ba682f0Skxie@chelsio.com 2739ba682f0Skxie@chelsio.com struct cxgbi_skb_tx_cb { 2749ba682f0Skxie@chelsio.com void *l2t; 2759ba682f0Skxie@chelsio.com struct sk_buff *wr_next; 2769ba682f0Skxie@chelsio.com }; 2779ba682f0Skxie@chelsio.com 2789ba682f0Skxie@chelsio.com enum cxgbi_skcb_flags { 2799ba682f0Skxie@chelsio.com SKCBF_TX_NEED_HDR, /* packet needs a header */ 2809ba682f0Skxie@chelsio.com SKCBF_RX_COALESCED, /* received whole pdu */ 28125985edcSLucas De Marchi SKCBF_RX_HDR, /* received pdu header */ 28225985edcSLucas De Marchi SKCBF_RX_DATA, /* received pdu payload */ 28325985edcSLucas De Marchi SKCBF_RX_STATUS, /* received ddp status */ 2849ba682f0Skxie@chelsio.com SKCBF_RX_DATA_DDPD, /* pdu payload ddp'd */ 2859ba682f0Skxie@chelsio.com SKCBF_RX_HCRC_ERR, /* header digest error */ 2869ba682f0Skxie@chelsio.com SKCBF_RX_DCRC_ERR, /* data digest error */ 2879ba682f0Skxie@chelsio.com SKCBF_RX_PAD_ERR, /* padding byte error */ 2889ba682f0Skxie@chelsio.com }; 2899ba682f0Skxie@chelsio.com 2909ba682f0Skxie@chelsio.com struct cxgbi_skb_cb { 2919ba682f0Skxie@chelsio.com unsigned char ulp_mode; 2929ba682f0Skxie@chelsio.com unsigned long flags; 2939ba682f0Skxie@chelsio.com unsigned int seq; 2949ba682f0Skxie@chelsio.com union { 2959ba682f0Skxie@chelsio.com struct cxgbi_skb_rx_cb rx; 2969ba682f0Skxie@chelsio.com struct cxgbi_skb_tx_cb tx; 2979ba682f0Skxie@chelsio.com }; 2989ba682f0Skxie@chelsio.com }; 2999ba682f0Skxie@chelsio.com 3009ba682f0Skxie@chelsio.com #define CXGBI_SKB_CB(skb) ((struct cxgbi_skb_cb *)&((skb)->cb[0])) 3019ba682f0Skxie@chelsio.com #define cxgbi_skcb_flags(skb) (CXGBI_SKB_CB(skb)->flags) 3029ba682f0Skxie@chelsio.com #define cxgbi_skcb_ulp_mode(skb) (CXGBI_SKB_CB(skb)->ulp_mode) 3039ba682f0Skxie@chelsio.com #define cxgbi_skcb_tcp_seq(skb) (CXGBI_SKB_CB(skb)->seq) 3049ba682f0Skxie@chelsio.com #define cxgbi_skcb_rx_ddigest(skb) (CXGBI_SKB_CB(skb)->rx.ddigest) 3059ba682f0Skxie@chelsio.com #define cxgbi_skcb_rx_pdulen(skb) (CXGBI_SKB_CB(skb)->rx.pdulen) 3069ba682f0Skxie@chelsio.com #define cxgbi_skcb_tx_wr_next(skb) (CXGBI_SKB_CB(skb)->tx.wr_next) 3079ba682f0Skxie@chelsio.com 3089ba682f0Skxie@chelsio.com static inline void cxgbi_skcb_set_flag(struct sk_buff *skb, 3099ba682f0Skxie@chelsio.com enum cxgbi_skcb_flags flag) 3109ba682f0Skxie@chelsio.com { 3119ba682f0Skxie@chelsio.com __set_bit(flag, &(cxgbi_skcb_flags(skb))); 3129ba682f0Skxie@chelsio.com } 3139ba682f0Skxie@chelsio.com 3149ba682f0Skxie@chelsio.com static inline void cxgbi_skcb_clear_flag(struct sk_buff *skb, 3159ba682f0Skxie@chelsio.com enum cxgbi_skcb_flags flag) 3169ba682f0Skxie@chelsio.com { 3179ba682f0Skxie@chelsio.com __clear_bit(flag, &(cxgbi_skcb_flags(skb))); 3189ba682f0Skxie@chelsio.com } 3199ba682f0Skxie@chelsio.com 3209ba682f0Skxie@chelsio.com static inline int cxgbi_skcb_test_flag(struct sk_buff *skb, 3219ba682f0Skxie@chelsio.com enum cxgbi_skcb_flags flag) 3229ba682f0Skxie@chelsio.com { 3239ba682f0Skxie@chelsio.com return test_bit(flag, &(cxgbi_skcb_flags(skb))); 3249ba682f0Skxie@chelsio.com } 3259ba682f0Skxie@chelsio.com 3269ba682f0Skxie@chelsio.com static inline void cxgbi_sock_set_flag(struct cxgbi_sock *csk, 3279ba682f0Skxie@chelsio.com enum cxgbi_sock_flags flag) 3289ba682f0Skxie@chelsio.com { 3299ba682f0Skxie@chelsio.com __set_bit(flag, &csk->flags); 3309ba682f0Skxie@chelsio.com log_debug(1 << CXGBI_DBG_SOCK, 3319ba682f0Skxie@chelsio.com "csk 0x%p,%u,0x%lx, bit %d.\n", 3329ba682f0Skxie@chelsio.com csk, csk->state, csk->flags, flag); 3339ba682f0Skxie@chelsio.com } 3349ba682f0Skxie@chelsio.com 3359ba682f0Skxie@chelsio.com static inline void cxgbi_sock_clear_flag(struct cxgbi_sock *csk, 3369ba682f0Skxie@chelsio.com enum cxgbi_sock_flags flag) 3379ba682f0Skxie@chelsio.com { 3389ba682f0Skxie@chelsio.com __clear_bit(flag, &csk->flags); 3399ba682f0Skxie@chelsio.com log_debug(1 << CXGBI_DBG_SOCK, 3409ba682f0Skxie@chelsio.com "csk 0x%p,%u,0x%lx, bit %d.\n", 3419ba682f0Skxie@chelsio.com csk, csk->state, csk->flags, flag); 3429ba682f0Skxie@chelsio.com } 3439ba682f0Skxie@chelsio.com 3449ba682f0Skxie@chelsio.com static inline int cxgbi_sock_flag(struct cxgbi_sock *csk, 3459ba682f0Skxie@chelsio.com enum cxgbi_sock_flags flag) 3469ba682f0Skxie@chelsio.com { 3479ba682f0Skxie@chelsio.com if (csk == NULL) 3489ba682f0Skxie@chelsio.com return 0; 3499ba682f0Skxie@chelsio.com return test_bit(flag, &csk->flags); 3509ba682f0Skxie@chelsio.com } 3519ba682f0Skxie@chelsio.com 3529ba682f0Skxie@chelsio.com static inline void cxgbi_sock_set_state(struct cxgbi_sock *csk, int state) 3539ba682f0Skxie@chelsio.com { 3549ba682f0Skxie@chelsio.com log_debug(1 << CXGBI_DBG_SOCK, 3559ba682f0Skxie@chelsio.com "csk 0x%p,%u,0x%lx, state -> %u.\n", 3569ba682f0Skxie@chelsio.com csk, csk->state, csk->flags, state); 3579ba682f0Skxie@chelsio.com csk->state = state; 3589ba682f0Skxie@chelsio.com } 3599ba682f0Skxie@chelsio.com 3609ba682f0Skxie@chelsio.com static inline void cxgbi_sock_free(struct kref *kref) 3619ba682f0Skxie@chelsio.com { 3629ba682f0Skxie@chelsio.com struct cxgbi_sock *csk = container_of(kref, 3639ba682f0Skxie@chelsio.com struct cxgbi_sock, 3649ba682f0Skxie@chelsio.com refcnt); 3659ba682f0Skxie@chelsio.com if (csk) { 3669ba682f0Skxie@chelsio.com log_debug(1 << CXGBI_DBG_SOCK, 3679ba682f0Skxie@chelsio.com "free csk 0x%p, state %u, flags 0x%lx\n", 3689ba682f0Skxie@chelsio.com csk, csk->state, csk->flags); 3699ba682f0Skxie@chelsio.com kfree(csk); 3709ba682f0Skxie@chelsio.com } 3719ba682f0Skxie@chelsio.com } 3729ba682f0Skxie@chelsio.com 3739ba682f0Skxie@chelsio.com static inline void __cxgbi_sock_put(const char *fn, struct cxgbi_sock *csk) 3749ba682f0Skxie@chelsio.com { 3759ba682f0Skxie@chelsio.com log_debug(1 << CXGBI_DBG_SOCK, 3769ba682f0Skxie@chelsio.com "%s, put csk 0x%p, ref %u-1.\n", 3779ba682f0Skxie@chelsio.com fn, csk, atomic_read(&csk->refcnt.refcount)); 3789ba682f0Skxie@chelsio.com kref_put(&csk->refcnt, cxgbi_sock_free); 3799ba682f0Skxie@chelsio.com } 3809ba682f0Skxie@chelsio.com #define cxgbi_sock_put(csk) __cxgbi_sock_put(__func__, csk) 3819ba682f0Skxie@chelsio.com 3829ba682f0Skxie@chelsio.com static inline void __cxgbi_sock_get(const char *fn, struct cxgbi_sock *csk) 3839ba682f0Skxie@chelsio.com { 3849ba682f0Skxie@chelsio.com log_debug(1 << CXGBI_DBG_SOCK, 3859ba682f0Skxie@chelsio.com "%s, get csk 0x%p, ref %u+1.\n", 3869ba682f0Skxie@chelsio.com fn, csk, atomic_read(&csk->refcnt.refcount)); 3879ba682f0Skxie@chelsio.com kref_get(&csk->refcnt); 3889ba682f0Skxie@chelsio.com } 3899ba682f0Skxie@chelsio.com #define cxgbi_sock_get(csk) __cxgbi_sock_get(__func__, csk) 3909ba682f0Skxie@chelsio.com 3919ba682f0Skxie@chelsio.com static inline int cxgbi_sock_is_closing(struct cxgbi_sock *csk) 3929ba682f0Skxie@chelsio.com { 3939ba682f0Skxie@chelsio.com return csk->state >= CTP_ACTIVE_CLOSE; 3949ba682f0Skxie@chelsio.com } 3959ba682f0Skxie@chelsio.com 3969ba682f0Skxie@chelsio.com static inline int cxgbi_sock_is_established(struct cxgbi_sock *csk) 3979ba682f0Skxie@chelsio.com { 3989ba682f0Skxie@chelsio.com return csk->state == CTP_ESTABLISHED; 3999ba682f0Skxie@chelsio.com } 4009ba682f0Skxie@chelsio.com 4019ba682f0Skxie@chelsio.com static inline void cxgbi_sock_purge_write_queue(struct cxgbi_sock *csk) 4029ba682f0Skxie@chelsio.com { 4039ba682f0Skxie@chelsio.com struct sk_buff *skb; 4049ba682f0Skxie@chelsio.com 4059ba682f0Skxie@chelsio.com while ((skb = __skb_dequeue(&csk->write_queue))) 4069ba682f0Skxie@chelsio.com __kfree_skb(skb); 4079ba682f0Skxie@chelsio.com } 4089ba682f0Skxie@chelsio.com 4099ba682f0Skxie@chelsio.com static inline unsigned int cxgbi_sock_compute_wscale(unsigned int win) 4109ba682f0Skxie@chelsio.com { 4119ba682f0Skxie@chelsio.com unsigned int wscale = 0; 4129ba682f0Skxie@chelsio.com 4139ba682f0Skxie@chelsio.com while (wscale < 14 && (65535 << wscale) < win) 4149ba682f0Skxie@chelsio.com wscale++; 4159ba682f0Skxie@chelsio.com return wscale; 4169ba682f0Skxie@chelsio.com } 4179ba682f0Skxie@chelsio.com 41824d3f95aSkxie@chelsio.com static inline struct sk_buff *alloc_wr(int wrlen, int dlen, gfp_t gfp) 4199ba682f0Skxie@chelsio.com { 4209ba682f0Skxie@chelsio.com struct sk_buff *skb = alloc_skb(wrlen + dlen, gfp); 4219ba682f0Skxie@chelsio.com 4229ba682f0Skxie@chelsio.com if (skb) { 4239ba682f0Skxie@chelsio.com __skb_put(skb, wrlen); 4249ba682f0Skxie@chelsio.com memset(skb->head, 0, wrlen + dlen); 4259ba682f0Skxie@chelsio.com } else 42624d3f95aSkxie@chelsio.com pr_info("alloc cpl wr skb %u+%u, OOM.\n", wrlen, dlen); 4279ba682f0Skxie@chelsio.com return skb; 4289ba682f0Skxie@chelsio.com } 4299ba682f0Skxie@chelsio.com 4309ba682f0Skxie@chelsio.com 4319ba682f0Skxie@chelsio.com /* 4329ba682f0Skxie@chelsio.com * The number of WRs needed for an skb depends on the number of fragments 4339ba682f0Skxie@chelsio.com * in the skb and whether it has any payload in its main body. This maps the 4349ba682f0Skxie@chelsio.com * length of the gather list represented by an skb into the # of necessary WRs. 4359ba682f0Skxie@chelsio.com * The extra two fragments are for iscsi bhs and payload padding. 4369ba682f0Skxie@chelsio.com */ 4379ba682f0Skxie@chelsio.com #define SKB_WR_LIST_SIZE (MAX_SKB_FRAGS + 2) 4389ba682f0Skxie@chelsio.com 4399ba682f0Skxie@chelsio.com static inline void cxgbi_sock_reset_wr_list(struct cxgbi_sock *csk) 4409ba682f0Skxie@chelsio.com { 4419ba682f0Skxie@chelsio.com csk->wr_pending_head = csk->wr_pending_tail = NULL; 4429ba682f0Skxie@chelsio.com } 4439ba682f0Skxie@chelsio.com 4449ba682f0Skxie@chelsio.com static inline void cxgbi_sock_enqueue_wr(struct cxgbi_sock *csk, 4459ba682f0Skxie@chelsio.com struct sk_buff *skb) 4469ba682f0Skxie@chelsio.com { 4479ba682f0Skxie@chelsio.com cxgbi_skcb_tx_wr_next(skb) = NULL; 4489ba682f0Skxie@chelsio.com /* 4499ba682f0Skxie@chelsio.com * We want to take an extra reference since both us and the driver 4509ba682f0Skxie@chelsio.com * need to free the packet before it's really freed. We know there's 4519ba682f0Skxie@chelsio.com * just one user currently so we use atomic_set rather than skb_get 4529ba682f0Skxie@chelsio.com * to avoid the atomic op. 4539ba682f0Skxie@chelsio.com */ 4549ba682f0Skxie@chelsio.com atomic_set(&skb->users, 2); 4559ba682f0Skxie@chelsio.com 4569ba682f0Skxie@chelsio.com if (!csk->wr_pending_head) 4579ba682f0Skxie@chelsio.com csk->wr_pending_head = skb; 4589ba682f0Skxie@chelsio.com else 4599ba682f0Skxie@chelsio.com cxgbi_skcb_tx_wr_next(csk->wr_pending_tail) = skb; 4609ba682f0Skxie@chelsio.com csk->wr_pending_tail = skb; 4619ba682f0Skxie@chelsio.com } 4629ba682f0Skxie@chelsio.com 4639ba682f0Skxie@chelsio.com static inline int cxgbi_sock_count_pending_wrs(const struct cxgbi_sock *csk) 4649ba682f0Skxie@chelsio.com { 4659ba682f0Skxie@chelsio.com int n = 0; 4669ba682f0Skxie@chelsio.com const struct sk_buff *skb = csk->wr_pending_head; 4679ba682f0Skxie@chelsio.com 4689ba682f0Skxie@chelsio.com while (skb) { 4699ba682f0Skxie@chelsio.com n += skb->csum; 4709ba682f0Skxie@chelsio.com skb = cxgbi_skcb_tx_wr_next(skb); 4719ba682f0Skxie@chelsio.com } 4729ba682f0Skxie@chelsio.com return n; 4739ba682f0Skxie@chelsio.com } 4749ba682f0Skxie@chelsio.com 4759ba682f0Skxie@chelsio.com static inline struct sk_buff *cxgbi_sock_peek_wr(const struct cxgbi_sock *csk) 4769ba682f0Skxie@chelsio.com { 4779ba682f0Skxie@chelsio.com return csk->wr_pending_head; 4789ba682f0Skxie@chelsio.com } 4799ba682f0Skxie@chelsio.com 4809ba682f0Skxie@chelsio.com static inline struct sk_buff *cxgbi_sock_dequeue_wr(struct cxgbi_sock *csk) 4819ba682f0Skxie@chelsio.com { 4829ba682f0Skxie@chelsio.com struct sk_buff *skb = csk->wr_pending_head; 4839ba682f0Skxie@chelsio.com 4849ba682f0Skxie@chelsio.com if (likely(skb)) { 4859ba682f0Skxie@chelsio.com csk->wr_pending_head = cxgbi_skcb_tx_wr_next(skb); 4869ba682f0Skxie@chelsio.com cxgbi_skcb_tx_wr_next(skb) = NULL; 4879ba682f0Skxie@chelsio.com } 4889ba682f0Skxie@chelsio.com return skb; 4899ba682f0Skxie@chelsio.com } 4909ba682f0Skxie@chelsio.com 4919ba682f0Skxie@chelsio.com void cxgbi_sock_check_wr_invariants(const struct cxgbi_sock *); 4929ba682f0Skxie@chelsio.com void cxgbi_sock_purge_wr_queue(struct cxgbi_sock *); 4939ba682f0Skxie@chelsio.com void cxgbi_sock_skb_entail(struct cxgbi_sock *, struct sk_buff *); 4949ba682f0Skxie@chelsio.com void cxgbi_sock_fail_act_open(struct cxgbi_sock *, int); 4959ba682f0Skxie@chelsio.com void cxgbi_sock_act_open_req_arp_failure(void *, struct sk_buff *); 4969ba682f0Skxie@chelsio.com void cxgbi_sock_closed(struct cxgbi_sock *); 4979ba682f0Skxie@chelsio.com void cxgbi_sock_established(struct cxgbi_sock *, unsigned int, unsigned int); 4989ba682f0Skxie@chelsio.com void cxgbi_sock_rcv_abort_rpl(struct cxgbi_sock *); 4999ba682f0Skxie@chelsio.com void cxgbi_sock_rcv_peer_close(struct cxgbi_sock *); 5009ba682f0Skxie@chelsio.com void cxgbi_sock_rcv_close_conn_rpl(struct cxgbi_sock *, u32); 5019ba682f0Skxie@chelsio.com void cxgbi_sock_rcv_wr_ack(struct cxgbi_sock *, unsigned int, unsigned int, 5029ba682f0Skxie@chelsio.com int); 5039ba682f0Skxie@chelsio.com unsigned int cxgbi_sock_select_mss(struct cxgbi_sock *, unsigned int); 5049ba682f0Skxie@chelsio.com void cxgbi_sock_free_cpl_skbs(struct cxgbi_sock *); 5059ba682f0Skxie@chelsio.com 5069ba682f0Skxie@chelsio.com struct cxgbi_hba { 5079ba682f0Skxie@chelsio.com struct net_device *ndev; 5080b3d8947Skxie@chelsio.com struct net_device *vdev; /* vlan dev */ 5099ba682f0Skxie@chelsio.com struct Scsi_Host *shost; 5109ba682f0Skxie@chelsio.com struct cxgbi_device *cdev; 5119ba682f0Skxie@chelsio.com __be32 ipv4addr; 5129ba682f0Skxie@chelsio.com unsigned char port_id; 5139ba682f0Skxie@chelsio.com }; 5149ba682f0Skxie@chelsio.com 5159ba682f0Skxie@chelsio.com struct cxgbi_ports_map { 5169ba682f0Skxie@chelsio.com unsigned int max_connect; 5179ba682f0Skxie@chelsio.com unsigned int used; 5189ba682f0Skxie@chelsio.com unsigned short sport_base; 5199ba682f0Skxie@chelsio.com spinlock_t lock; 5209ba682f0Skxie@chelsio.com unsigned int next; 5219ba682f0Skxie@chelsio.com struct cxgbi_sock **port_csk; 5229ba682f0Skxie@chelsio.com }; 5239ba682f0Skxie@chelsio.com 5249ba682f0Skxie@chelsio.com #define CXGBI_FLAG_DEV_T3 0x1 5259ba682f0Skxie@chelsio.com #define CXGBI_FLAG_DEV_T4 0x2 5269ba682f0Skxie@chelsio.com #define CXGBI_FLAG_ADAPTER_RESET 0x4 5279ba682f0Skxie@chelsio.com #define CXGBI_FLAG_IPV4_SET 0x10 5289ba682f0Skxie@chelsio.com struct cxgbi_device { 5299ba682f0Skxie@chelsio.com struct list_head list_head; 530078efae0SAnish Bhatt struct list_head rcu_node; 5319ba682f0Skxie@chelsio.com unsigned int flags; 5329ba682f0Skxie@chelsio.com struct net_device **ports; 5339ba682f0Skxie@chelsio.com void *lldev; 5349ba682f0Skxie@chelsio.com struct cxgbi_hba **hbas; 5359ba682f0Skxie@chelsio.com const unsigned short *mtus; 5369ba682f0Skxie@chelsio.com unsigned char nmtus; 5379ba682f0Skxie@chelsio.com unsigned char nports; 5389ba682f0Skxie@chelsio.com struct pci_dev *pdev; 5399ba682f0Skxie@chelsio.com struct dentry *debugfs_root; 5409ba682f0Skxie@chelsio.com struct iscsi_transport *itp; 5419ba682f0Skxie@chelsio.com 5429ba682f0Skxie@chelsio.com unsigned int pfvf; 5439ba682f0Skxie@chelsio.com unsigned int snd_win; 5449ba682f0Skxie@chelsio.com unsigned int rcv_win; 5459ba682f0Skxie@chelsio.com unsigned int rx_credit_thres; 5469ba682f0Skxie@chelsio.com unsigned int skb_tx_rsvd; 5479ba682f0Skxie@chelsio.com unsigned int skb_rx_extra; /* for msg coalesced mode */ 5489ba682f0Skxie@chelsio.com unsigned int tx_max_size; 5499ba682f0Skxie@chelsio.com unsigned int rx_max_size; 5509ba682f0Skxie@chelsio.com struct cxgbi_ports_map pmap; 5519ba682f0Skxie@chelsio.com struct cxgbi_tag_format tag_format; 5529ba682f0Skxie@chelsio.com struct cxgbi_ddp_info *ddp; 5539ba682f0Skxie@chelsio.com 5549ba682f0Skxie@chelsio.com void (*dev_ddp_cleanup)(struct cxgbi_device *); 5559ba682f0Skxie@chelsio.com int (*csk_ddp_set)(struct cxgbi_sock *, struct cxgbi_pagepod_hdr *, 5569ba682f0Skxie@chelsio.com unsigned int, unsigned int, 5579ba682f0Skxie@chelsio.com struct cxgbi_gather_list *); 5589ba682f0Skxie@chelsio.com void (*csk_ddp_clear)(struct cxgbi_hba *, 5599ba682f0Skxie@chelsio.com unsigned int, unsigned int, unsigned int); 5609ba682f0Skxie@chelsio.com int (*csk_ddp_setup_digest)(struct cxgbi_sock *, 5619ba682f0Skxie@chelsio.com unsigned int, int, int, int); 5629ba682f0Skxie@chelsio.com int (*csk_ddp_setup_pgidx)(struct cxgbi_sock *, 5639ba682f0Skxie@chelsio.com unsigned int, int, bool); 5649ba682f0Skxie@chelsio.com 5659ba682f0Skxie@chelsio.com void (*csk_release_offload_resources)(struct cxgbi_sock *); 5669ba682f0Skxie@chelsio.com int (*csk_rx_pdu_ready)(struct cxgbi_sock *, struct sk_buff *); 5679ba682f0Skxie@chelsio.com u32 (*csk_send_rx_credits)(struct cxgbi_sock *, u32); 5689ba682f0Skxie@chelsio.com int (*csk_push_tx_frames)(struct cxgbi_sock *, int); 5699ba682f0Skxie@chelsio.com void (*csk_send_abort_req)(struct cxgbi_sock *); 5709ba682f0Skxie@chelsio.com void (*csk_send_close_req)(struct cxgbi_sock *); 5719ba682f0Skxie@chelsio.com int (*csk_alloc_cpls)(struct cxgbi_sock *); 5729ba682f0Skxie@chelsio.com int (*csk_init_act_open)(struct cxgbi_sock *); 5739ba682f0Skxie@chelsio.com 5749ba682f0Skxie@chelsio.com void *dd_data; 5759ba682f0Skxie@chelsio.com }; 5769ba682f0Skxie@chelsio.com #define cxgbi_cdev_priv(cdev) ((cdev)->dd_data) 5779ba682f0Skxie@chelsio.com 5789ba682f0Skxie@chelsio.com struct cxgbi_conn { 5799ba682f0Skxie@chelsio.com struct cxgbi_endpoint *cep; 5809ba682f0Skxie@chelsio.com struct iscsi_conn *iconn; 5819ba682f0Skxie@chelsio.com struct cxgbi_hba *chba; 5829ba682f0Skxie@chelsio.com u32 task_idx_bits; 5839ba682f0Skxie@chelsio.com }; 5849ba682f0Skxie@chelsio.com 5859ba682f0Skxie@chelsio.com struct cxgbi_endpoint { 5869ba682f0Skxie@chelsio.com struct cxgbi_conn *cconn; 5879ba682f0Skxie@chelsio.com struct cxgbi_hba *chba; 5889ba682f0Skxie@chelsio.com struct cxgbi_sock *csk; 5899ba682f0Skxie@chelsio.com }; 5909ba682f0Skxie@chelsio.com 5919ba682f0Skxie@chelsio.com #define MAX_PDU_FRAGS ((ULP2_MAX_PDU_PAYLOAD + 512 - 1) / 512) 5929ba682f0Skxie@chelsio.com struct cxgbi_task_data { 5939ba682f0Skxie@chelsio.com unsigned short nr_frags; 5946a39a16aSIan Campbell struct page_frag frags[MAX_PDU_FRAGS]; 5959ba682f0Skxie@chelsio.com struct sk_buff *skb; 5969ba682f0Skxie@chelsio.com unsigned int offset; 5979ba682f0Skxie@chelsio.com unsigned int count; 5989ba682f0Skxie@chelsio.com unsigned int sgoffset; 5999ba682f0Skxie@chelsio.com }; 600e3d2ad8cSkxie@chelsio.com #define iscsi_task_cxgbi_data(task) \ 601e3d2ad8cSkxie@chelsio.com ((task)->dd_data + sizeof(struct iscsi_tcp_task)) 6029ba682f0Skxie@chelsio.com 6039ba682f0Skxie@chelsio.com static inline int cxgbi_is_ddp_tag(struct cxgbi_tag_format *tformat, u32 tag) 6049ba682f0Skxie@chelsio.com { 6059ba682f0Skxie@chelsio.com return !(tag & (1 << (tformat->rsvd_bits + tformat->rsvd_shift - 1))); 6069ba682f0Skxie@chelsio.com } 6079ba682f0Skxie@chelsio.com 6089ba682f0Skxie@chelsio.com static inline int cxgbi_sw_tag_usable(struct cxgbi_tag_format *tformat, 6099ba682f0Skxie@chelsio.com u32 sw_tag) 6109ba682f0Skxie@chelsio.com { 6119ba682f0Skxie@chelsio.com sw_tag >>= (32 - tformat->rsvd_bits); 6129ba682f0Skxie@chelsio.com return !sw_tag; 6139ba682f0Skxie@chelsio.com } 6149ba682f0Skxie@chelsio.com 6159ba682f0Skxie@chelsio.com static inline u32 cxgbi_set_non_ddp_tag(struct cxgbi_tag_format *tformat, 6169ba682f0Skxie@chelsio.com u32 sw_tag) 6179ba682f0Skxie@chelsio.com { 6189ba682f0Skxie@chelsio.com unsigned char shift = tformat->rsvd_bits + tformat->rsvd_shift - 1; 6199ba682f0Skxie@chelsio.com u32 mask = (1 << shift) - 1; 6209ba682f0Skxie@chelsio.com 6219ba682f0Skxie@chelsio.com if (sw_tag && (sw_tag & ~mask)) { 6229ba682f0Skxie@chelsio.com u32 v1 = sw_tag & ((1 << shift) - 1); 6239ba682f0Skxie@chelsio.com u32 v2 = (sw_tag >> (shift - 1)) << shift; 6249ba682f0Skxie@chelsio.com 6259ba682f0Skxie@chelsio.com return v2 | v1 | 1 << shift; 6269ba682f0Skxie@chelsio.com } 6279ba682f0Skxie@chelsio.com 6289ba682f0Skxie@chelsio.com return sw_tag | 1 << shift; 6299ba682f0Skxie@chelsio.com } 6309ba682f0Skxie@chelsio.com 6319ba682f0Skxie@chelsio.com static inline u32 cxgbi_ddp_tag_base(struct cxgbi_tag_format *tformat, 6329ba682f0Skxie@chelsio.com u32 sw_tag) 6339ba682f0Skxie@chelsio.com { 6349ba682f0Skxie@chelsio.com u32 mask = (1 << tformat->rsvd_shift) - 1; 6359ba682f0Skxie@chelsio.com 6369ba682f0Skxie@chelsio.com if (sw_tag && (sw_tag & ~mask)) { 6379ba682f0Skxie@chelsio.com u32 v1 = sw_tag & mask; 6389ba682f0Skxie@chelsio.com u32 v2 = sw_tag >> tformat->rsvd_shift; 6399ba682f0Skxie@chelsio.com 6409ba682f0Skxie@chelsio.com v2 <<= tformat->rsvd_bits + tformat->rsvd_shift; 6419ba682f0Skxie@chelsio.com 6429ba682f0Skxie@chelsio.com return v2 | v1; 6439ba682f0Skxie@chelsio.com } 6449ba682f0Skxie@chelsio.com 6459ba682f0Skxie@chelsio.com return sw_tag; 6469ba682f0Skxie@chelsio.com } 6479ba682f0Skxie@chelsio.com 6489ba682f0Skxie@chelsio.com static inline u32 cxgbi_tag_rsvd_bits(struct cxgbi_tag_format *tformat, 6499ba682f0Skxie@chelsio.com u32 tag) 6509ba682f0Skxie@chelsio.com { 6519ba682f0Skxie@chelsio.com if (cxgbi_is_ddp_tag(tformat, tag)) 6529ba682f0Skxie@chelsio.com return (tag >> tformat->rsvd_shift) & tformat->rsvd_mask; 6539ba682f0Skxie@chelsio.com 6549ba682f0Skxie@chelsio.com return 0; 6559ba682f0Skxie@chelsio.com } 6569ba682f0Skxie@chelsio.com 6579ba682f0Skxie@chelsio.com static inline u32 cxgbi_tag_nonrsvd_bits(struct cxgbi_tag_format *tformat, 6589ba682f0Skxie@chelsio.com u32 tag) 6599ba682f0Skxie@chelsio.com { 6609ba682f0Skxie@chelsio.com unsigned char shift = tformat->rsvd_bits + tformat->rsvd_shift - 1; 6619ba682f0Skxie@chelsio.com u32 v1, v2; 6629ba682f0Skxie@chelsio.com 6639ba682f0Skxie@chelsio.com if (cxgbi_is_ddp_tag(tformat, tag)) { 6649ba682f0Skxie@chelsio.com v1 = tag & ((1 << tformat->rsvd_shift) - 1); 6659ba682f0Skxie@chelsio.com v2 = (tag >> (shift + 1)) << tformat->rsvd_shift; 6669ba682f0Skxie@chelsio.com } else { 6679ba682f0Skxie@chelsio.com u32 mask = (1 << shift) - 1; 6689ba682f0Skxie@chelsio.com tag &= ~(1 << shift); 6699ba682f0Skxie@chelsio.com v1 = tag & mask; 6709ba682f0Skxie@chelsio.com v2 = (tag >> 1) & ~mask; 6719ba682f0Skxie@chelsio.com } 6729ba682f0Skxie@chelsio.com return v1 | v2; 6739ba682f0Skxie@chelsio.com } 6749ba682f0Skxie@chelsio.com 6759ba682f0Skxie@chelsio.com static inline void *cxgbi_alloc_big_mem(unsigned int size, 6769ba682f0Skxie@chelsio.com gfp_t gfp) 6779ba682f0Skxie@chelsio.com { 6788be04b93SJoe Perches void *p = kzalloc(size, gfp | __GFP_NOWARN); 6798be04b93SJoe Perches 6809ba682f0Skxie@chelsio.com if (!p) 6818be04b93SJoe Perches p = vzalloc(size); 6828be04b93SJoe Perches 6839ba682f0Skxie@chelsio.com return p; 6849ba682f0Skxie@chelsio.com } 6859ba682f0Skxie@chelsio.com 6869ba682f0Skxie@chelsio.com static inline void cxgbi_free_big_mem(void *addr) 6879ba682f0Skxie@chelsio.com { 6889ba682f0Skxie@chelsio.com if (is_vmalloc_addr(addr)) 6899ba682f0Skxie@chelsio.com vfree(addr); 6909ba682f0Skxie@chelsio.com else 6919ba682f0Skxie@chelsio.com kfree(addr); 6929ba682f0Skxie@chelsio.com } 6939ba682f0Skxie@chelsio.com 6949ba682f0Skxie@chelsio.com static inline void cxgbi_set_iscsi_ipv4(struct cxgbi_hba *chba, __be32 ipaddr) 6959ba682f0Skxie@chelsio.com { 6969ba682f0Skxie@chelsio.com if (chba->cdev->flags & CXGBI_FLAG_IPV4_SET) 6979ba682f0Skxie@chelsio.com chba->ipv4addr = ipaddr; 6989ba682f0Skxie@chelsio.com else 6999ba682f0Skxie@chelsio.com pr_info("set iscsi ipv4 NOT supported, using %s ipv4.\n", 7009ba682f0Skxie@chelsio.com chba->ndev->name); 7019ba682f0Skxie@chelsio.com } 7029ba682f0Skxie@chelsio.com 7039ba682f0Skxie@chelsio.com static inline __be32 cxgbi_get_iscsi_ipv4(struct cxgbi_hba *chba) 7049ba682f0Skxie@chelsio.com { 7059ba682f0Skxie@chelsio.com return chba->ipv4addr; 7069ba682f0Skxie@chelsio.com } 7079ba682f0Skxie@chelsio.com 7089ba682f0Skxie@chelsio.com struct cxgbi_device *cxgbi_device_register(unsigned int, unsigned int); 7099ba682f0Skxie@chelsio.com void cxgbi_device_unregister(struct cxgbi_device *); 7109ba682f0Skxie@chelsio.com void cxgbi_device_unregister_all(unsigned int flag); 7119ba682f0Skxie@chelsio.com struct cxgbi_device *cxgbi_device_find_by_lldev(void *); 712fc8d0590SAnish Bhatt struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *, int *); 713078efae0SAnish Bhatt struct cxgbi_device *cxgbi_device_find_by_netdev_rcu(struct net_device *, 714078efae0SAnish Bhatt int *); 7151abf635dSHannes Reinecke int cxgbi_hbas_add(struct cxgbi_device *, u64, unsigned int, 7169ba682f0Skxie@chelsio.com struct scsi_host_template *, 7179ba682f0Skxie@chelsio.com struct scsi_transport_template *); 7189ba682f0Skxie@chelsio.com void cxgbi_hbas_remove(struct cxgbi_device *); 7199ba682f0Skxie@chelsio.com 7209ba682f0Skxie@chelsio.com int cxgbi_device_portmap_create(struct cxgbi_device *cdev, unsigned int base, 7219ba682f0Skxie@chelsio.com unsigned int max_conn); 7229ba682f0Skxie@chelsio.com void cxgbi_device_portmap_cleanup(struct cxgbi_device *cdev); 7239ba682f0Skxie@chelsio.com 7249ba682f0Skxie@chelsio.com void cxgbi_conn_tx_open(struct cxgbi_sock *); 7259ba682f0Skxie@chelsio.com void cxgbi_conn_pdu_ready(struct cxgbi_sock *); 7269ba682f0Skxie@chelsio.com int cxgbi_conn_alloc_pdu(struct iscsi_task *, u8); 7279ba682f0Skxie@chelsio.com int cxgbi_conn_init_pdu(struct iscsi_task *, unsigned int , unsigned int); 7289ba682f0Skxie@chelsio.com int cxgbi_conn_xmit_pdu(struct iscsi_task *); 7299ba682f0Skxie@chelsio.com 7309ba682f0Skxie@chelsio.com void cxgbi_cleanup_task(struct iscsi_task *task); 7319ba682f0Skxie@chelsio.com 732587a1f16SAl Viro umode_t cxgbi_attr_is_visible(int param_type, int param); 7339ba682f0Skxie@chelsio.com void cxgbi_get_conn_stats(struct iscsi_cls_conn *, struct iscsi_stats *); 7349ba682f0Skxie@chelsio.com int cxgbi_set_conn_param(struct iscsi_cls_conn *, 7359ba682f0Skxie@chelsio.com enum iscsi_param, char *, int); 736c71b9b66SMike Christie int cxgbi_get_ep_param(struct iscsi_endpoint *ep, enum iscsi_param, char *); 7379ba682f0Skxie@chelsio.com struct iscsi_cls_conn *cxgbi_create_conn(struct iscsi_cls_session *, u32); 7389ba682f0Skxie@chelsio.com int cxgbi_bind_conn(struct iscsi_cls_session *, 7399ba682f0Skxie@chelsio.com struct iscsi_cls_conn *, u64, int); 7409ba682f0Skxie@chelsio.com void cxgbi_destroy_session(struct iscsi_cls_session *); 7419ba682f0Skxie@chelsio.com struct iscsi_cls_session *cxgbi_create_session(struct iscsi_endpoint *, 7429ba682f0Skxie@chelsio.com u16, u16, u32); 7439ba682f0Skxie@chelsio.com int cxgbi_set_host_param(struct Scsi_Host *, 7449ba682f0Skxie@chelsio.com enum iscsi_host_param, char *, int); 7459ba682f0Skxie@chelsio.com int cxgbi_get_host_param(struct Scsi_Host *, enum iscsi_host_param, char *); 7469ba682f0Skxie@chelsio.com struct iscsi_endpoint *cxgbi_ep_connect(struct Scsi_Host *, 7479ba682f0Skxie@chelsio.com struct sockaddr *, int); 7489ba682f0Skxie@chelsio.com int cxgbi_ep_poll(struct iscsi_endpoint *, int); 7499ba682f0Skxie@chelsio.com void cxgbi_ep_disconnect(struct iscsi_endpoint *); 7509ba682f0Skxie@chelsio.com 7519ba682f0Skxie@chelsio.com int cxgbi_iscsi_init(struct iscsi_transport *, 7529ba682f0Skxie@chelsio.com struct scsi_transport_template **); 7539ba682f0Skxie@chelsio.com void cxgbi_iscsi_cleanup(struct iscsi_transport *, 7549ba682f0Skxie@chelsio.com struct scsi_transport_template **); 7559ba682f0Skxie@chelsio.com void cxgbi_parse_pdu_itt(struct iscsi_conn *, itt_t, int *, int *); 7569ba682f0Skxie@chelsio.com int cxgbi_ddp_init(struct cxgbi_device *, unsigned int, unsigned int, 7579ba682f0Skxie@chelsio.com unsigned int, unsigned int); 7589ba682f0Skxie@chelsio.com int cxgbi_ddp_cleanup(struct cxgbi_device *); 7599ba682f0Skxie@chelsio.com void cxgbi_ddp_page_size_factor(int *); 7609ba682f0Skxie@chelsio.com void cxgbi_ddp_ppod_clear(struct cxgbi_pagepod *); 7619ba682f0Skxie@chelsio.com void cxgbi_ddp_ppod_set(struct cxgbi_pagepod *, struct cxgbi_pagepod_hdr *, 7629ba682f0Skxie@chelsio.com struct cxgbi_gather_list *, unsigned int); 7639ba682f0Skxie@chelsio.com #endif /*__LIBCXGBI_H__*/ 764