2 * cxgb3i_ddp.h: Chelsio S3xx iSCSI DDP Manager.
4 * Copyright (c) 2008 Chelsio Communications, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation.
10 * Written by: Karen Xie (kxie@chelsio.com)
13 #ifndef __CXGB3I_ULP2_DDP_H__
14 #define __CXGB3I_ULP2_DDP_H__
16 #include <linux/vmalloc.h>
19 * struct cxgb3i_tag_format - cxgb3i ulp tag format for an iscsi entity
21 * @sw_bits: # of bits used by iscsi software layer
22 * @rsvd_bits: # of bits used by h/w
23 * @rsvd_shift: h/w bits shift left
24 * @rsvd_mask: reserved bit mask
26 struct cxgb3i_tag_format
{
27 unsigned char sw_bits
;
28 unsigned char rsvd_bits
;
29 unsigned char rsvd_shift
;
30 unsigned char filler
[1];
35 * struct cxgb3i_gather_list - cxgb3i direct data placement memory
38 * @length: total data buffer length
39 * @offset: initial offset to the 1st page
41 * @pages: page pointers
42 * @phys_addr: physical address
44 struct cxgb3i_gather_list
{
50 dma_addr_t phys_addr
[0];
54 * struct cxgb3i_ddp_info - cxgb3i direct data placement for pdu payload
56 * @list: list head to link elements
58 * @tdev: pointer to t3cdev used by cxgb3 driver
59 * @max_txsz: max tx packet size for ddp
60 * @max_rxsz: max rx packet size for ddp
61 * @llimit: lower bound of the page pod memory
62 * @ulimit: upper bound of the page pod memory
63 * @nppods: # of page pod entries
64 * @idx_last: page pod entry last used
65 * @idx_bits: # of bits the pagepod index would take
66 * @idx_mask: pagepod index mask
67 * @rsvd_tag_mask: tag mask
68 * @map_lock: lock to synchonize access to the page pod map
69 * @gl_map: ddp memory gather list
70 * @gl_skb: skb used to program the pagepod
72 struct cxgb3i_ddp_info
{
73 struct list_head list
;
77 unsigned int max_txsz
;
78 unsigned int max_rxsz
;
82 unsigned int idx_last
;
83 unsigned char idx_bits
;
84 unsigned char filler
[3];
88 struct cxgb3i_gather_list
**gl_map
;
89 struct sk_buff
**gl_skb
;
92 #define ISCSI_PDU_NONPAYLOAD_LEN 312 /* bhs(48) + ahs(256) + digest(8) */
93 #define ULP2_MAX_PKT_SIZE 16224
94 #define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_LEN)
95 #define PPOD_PAGES_MAX 4
96 #define PPOD_PAGES_SHIFT 2 /* 4 pages per pod */
99 * struct pagepod_hdr, pagepod - pagepod format
110 struct pagepod_hdr hdr
;
111 u64 addr
[PPOD_PAGES_MAX
+ 1];
114 #define PPOD_SIZE sizeof(struct pagepod) /* 64 */
115 #define PPOD_SIZE_SHIFT 6
117 #define PPOD_COLOR_SHIFT 0
118 #define PPOD_COLOR_SIZE 6
119 #define PPOD_COLOR_MASK ((1 << PPOD_COLOR_SIZE) - 1)
121 #define PPOD_IDX_SHIFT PPOD_COLOR_SIZE
122 #define PPOD_IDX_MAX_SIZE 24
125 #define M_PPOD_TID 0xFFFFFF
126 #define V_PPOD_TID(x) ((x) << S_PPOD_TID)
128 #define S_PPOD_VALID 24
129 #define V_PPOD_VALID(x) ((x) << S_PPOD_VALID)
130 #define F_PPOD_VALID V_PPOD_VALID(1U)
132 #define S_PPOD_COLOR 0
133 #define M_PPOD_COLOR 0x3F
134 #define V_PPOD_COLOR(x) ((x) << S_PPOD_COLOR)
137 #define M_PPOD_TAG 0xFFFFFF
138 #define V_PPOD_TAG(x) ((x) << S_PPOD_TAG)
140 #define S_PPOD_PGSZ 30
141 #define M_PPOD_PGSZ 0x3
142 #define V_PPOD_PGSZ(x) ((x) << S_PPOD_PGSZ)
145 * large memory chunk allocation/release
146 * use vmalloc() if kmalloc() fails
148 static inline void *cxgb3i_alloc_big_mem(unsigned int size
,
151 void *p
= kmalloc(size
, gfp
);
159 static inline void cxgb3i_free_big_mem(void *addr
)
161 if (is_vmalloc_addr(addr
))
168 * cxgb3i ddp tag are 32 bits, it consists of reserved bits used by h/w and
169 * non-reserved bits that can be used by the iscsi s/w.
170 * The reserved bits are identified by the rsvd_bits and rsvd_shift fields
171 * in struct cxgb3i_tag_format.
173 * The upper most reserved bit can be used to check if a tag is ddp tag or not:
174 * if the bit is 0, the tag is a valid ddp tag
178 * cxgb3i_is_ddp_tag - check if a given tag is a hw/ddp tag
179 * @tformat: tag format information
180 * @tag: tag to be checked
182 * return true if the tag is a ddp tag, false otherwise.
184 static inline int cxgb3i_is_ddp_tag(struct cxgb3i_tag_format
*tformat
, u32 tag
)
186 return !(tag
& (1 << (tformat
->rsvd_bits
+ tformat
->rsvd_shift
- 1)));
190 * cxgb3i_sw_tag_usable - check if s/w tag has enough bits left for hw bits
191 * @tformat: tag format information
192 * @sw_tag: s/w tag to be checked
194 * return true if the tag can be used for hw ddp tag, false otherwise.
196 static inline int cxgb3i_sw_tag_usable(struct cxgb3i_tag_format
*tformat
,
199 sw_tag
>>= (32 - tformat
->rsvd_bits
);
204 * cxgb3i_set_non_ddp_tag - mark a given s/w tag as an invalid ddp tag
205 * @tformat: tag format information
206 * @sw_tag: s/w tag to be checked
208 * insert 1 at the upper most reserved bit to mark it as an invalid ddp tag.
210 static inline u32
cxgb3i_set_non_ddp_tag(struct cxgb3i_tag_format
*tformat
,
213 unsigned char shift
= tformat
->rsvd_bits
+ tformat
->rsvd_shift
- 1;
214 u32 mask
= (1 << shift
) - 1;
216 if (sw_tag
&& (sw_tag
& ~mask
)) {
217 u32 v1
= sw_tag
& ((1 << shift
) - 1);
218 u32 v2
= (sw_tag
>> (shift
- 1)) << shift
;
220 return v2
| v1
| 1 << shift
;
222 return sw_tag
| 1 << shift
;
226 * cxgb3i_ddp_tag_base - shift s/w tag bits so that reserved bits are not used
227 * @tformat: tag format information
228 * @sw_tag: s/w tag to be checked
230 static inline u32
cxgb3i_ddp_tag_base(struct cxgb3i_tag_format
*tformat
,
233 u32 mask
= (1 << tformat
->rsvd_shift
) - 1;
235 if (sw_tag
&& (sw_tag
& ~mask
)) {
236 u32 v1
= sw_tag
& mask
;
237 u32 v2
= sw_tag
>> tformat
->rsvd_shift
;
239 v2
<<= tformat
->rsvd_shift
+ tformat
->rsvd_bits
;
246 * cxgb3i_tag_rsvd_bits - get the reserved bits used by the h/w
247 * @tformat: tag format information
248 * @tag: tag to be checked
250 * return the reserved bits in the tag
252 static inline u32
cxgb3i_tag_rsvd_bits(struct cxgb3i_tag_format
*tformat
,
255 if (cxgb3i_is_ddp_tag(tformat
, tag
))
256 return (tag
>> tformat
->rsvd_shift
) & tformat
->rsvd_mask
;
261 * cxgb3i_tag_nonrsvd_bits - get the non-reserved bits used by the s/w
262 * @tformat: tag format information
263 * @tag: tag to be checked
265 * return the non-reserved bits in the tag.
267 static inline u32
cxgb3i_tag_nonrsvd_bits(struct cxgb3i_tag_format
*tformat
,
270 unsigned char shift
= tformat
->rsvd_bits
+ tformat
->rsvd_shift
- 1;
273 if (cxgb3i_is_ddp_tag(tformat
, tag
)) {
274 v1
= tag
& ((1 << tformat
->rsvd_shift
) - 1);
275 v2
= (tag
>> (shift
+ 1)) << tformat
->rsvd_shift
;
277 u32 mask
= (1 << shift
) - 1;
279 tag
&= ~(1 << shift
);
281 v2
= (tag
>> 1) & ~mask
;
286 int cxgb3i_ddp_tag_reserve(struct t3cdev
*, unsigned int tid
,
287 struct cxgb3i_tag_format
*, u32
*tag
,
288 struct cxgb3i_gather_list
*, gfp_t gfp
);
289 void cxgb3i_ddp_tag_release(struct t3cdev
*, u32 tag
);
291 struct cxgb3i_gather_list
*cxgb3i_ddp_make_gl(unsigned int xferlen
,
292 struct scatterlist
*sgl
,
294 struct pci_dev
*pdev
,
296 void cxgb3i_ddp_release_gl(struct cxgb3i_gather_list
*gl
,
297 struct pci_dev
*pdev
);
299 int cxgb3i_setup_conn_host_pagesize(struct t3cdev
*, unsigned int tid
,
301 int cxgb3i_setup_conn_pagesize(struct t3cdev
*, unsigned int tid
, int reply
,
303 int cxgb3i_setup_conn_digest(struct t3cdev
*, unsigned int tid
,
304 int hcrc
, int dcrc
, int reply
);
305 int cxgb3i_ddp_find_page_index(unsigned long pgsz
);
306 int cxgb3i_adapter_ddp_info(struct t3cdev
*, struct cxgb3i_tag_format
*,
307 unsigned int *txsz
, unsigned int *rxsz
);
309 void cxgb3i_ddp_init(struct t3cdev
*);
310 void cxgb3i_ddp_cleanup(struct t3cdev
*);