]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/scsi/cxgb3i/cxgb3i_ddp.h
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[net-next-2.6.git] / drivers / scsi / cxgb3i / cxgb3i_ddp.h
1 /*
2  * cxgb3i_ddp.h: Chelsio S3xx iSCSI DDP Manager.
3  *
4  * Copyright (c) 2008 Chelsio Communications, Inc.
5  *
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.
9  *
10  * Written by: Karen Xie (kxie@chelsio.com)
11  */
12
13 #ifndef __CXGB3I_ULP2_DDP_H__
14 #define __CXGB3I_ULP2_DDP_H__
15
16 #include <linux/slab.h>
17 #include <linux/vmalloc.h>
18
19 /**
20  * struct cxgb3i_tag_format - cxgb3i ulp tag format for an iscsi entity
21  *
22  * @sw_bits:    # of bits used by iscsi software layer
23  * @rsvd_bits:  # of bits used by h/w
24  * @rsvd_shift: h/w bits shift left
25  * @rsvd_mask:  reserved bit mask
26  */
27 struct cxgb3i_tag_format {
28         unsigned char sw_bits;
29         unsigned char rsvd_bits;
30         unsigned char rsvd_shift;
31         unsigned char filler[1];
32         u32 rsvd_mask;
33 };
34
35 /**
36  * struct cxgb3i_gather_list - cxgb3i direct data placement memory
37  *
38  * @tag:        ddp tag
39  * @length:     total data buffer length
40  * @offset:     initial offset to the 1st page
41  * @nelem:      # of pages
42  * @pages:      page pointers
43  * @phys_addr:  physical address
44  */
45 struct cxgb3i_gather_list {
46         u32 tag;
47         unsigned int length;
48         unsigned int offset;
49         unsigned int nelem;
50         struct page **pages;
51         dma_addr_t phys_addr[0];
52 };
53
54 /**
55  * struct cxgb3i_ddp_info - cxgb3i direct data placement for pdu payload
56  *
57  * @list:       list head to link elements
58  * @refcnt:     ref. count
59  * @tdev:       pointer to t3cdev used by cxgb3 driver
60  * @max_txsz:   max tx packet size for ddp
61  * @max_rxsz:   max rx packet size for ddp
62  * @llimit:     lower bound of the page pod memory
63  * @ulimit:     upper bound of the page pod memory
64  * @nppods:     # of page pod entries
65  * @idx_last:   page pod entry last used
66  * @idx_bits:   # of bits the pagepod index would take
67  * @idx_mask:   pagepod index mask
68  * @rsvd_tag_mask: tag mask
69  * @map_lock:   lock to synchonize access to the page pod map
70  * @gl_map:     ddp memory gather list
71  * @gl_skb:     skb used to program the pagepod
72  */
73 struct cxgb3i_ddp_info {
74         struct list_head list;
75         struct kref refcnt;
76         struct t3cdev *tdev;
77         struct pci_dev *pdev;
78         unsigned int max_txsz;
79         unsigned int max_rxsz;
80         unsigned int llimit;
81         unsigned int ulimit;
82         unsigned int nppods;
83         unsigned int idx_last;
84         unsigned char idx_bits;
85         unsigned char filler[3];
86         u32 idx_mask;
87         u32 rsvd_tag_mask;
88         spinlock_t map_lock;
89         struct cxgb3i_gather_list **gl_map;
90         struct sk_buff **gl_skb;
91 };
92
93 #define ISCSI_PDU_NONPAYLOAD_LEN        312 /* bhs(48) + ahs(256) + digest(8) */
94 #define ULP2_MAX_PKT_SIZE       16224
95 #define ULP2_MAX_PDU_PAYLOAD    (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_LEN)
96 #define PPOD_PAGES_MAX          4
97 #define PPOD_PAGES_SHIFT        2       /* 4 pages per pod */
98
99 /*
100  * struct pagepod_hdr, pagepod - pagepod format
101  */
102 struct pagepod_hdr {
103         u32 vld_tid;
104         u32 pgsz_tag_clr;
105         u32 maxoffset;
106         u32 pgoffset;
107         u64 rsvd;
108 };
109
110 struct pagepod {
111         struct pagepod_hdr hdr;
112         u64 addr[PPOD_PAGES_MAX + 1];
113 };
114
115 #define PPOD_SIZE               sizeof(struct pagepod)  /* 64 */
116 #define PPOD_SIZE_SHIFT         6
117
118 #define PPOD_COLOR_SHIFT        0
119 #define PPOD_COLOR_SIZE         6
120 #define PPOD_COLOR_MASK         ((1 << PPOD_COLOR_SIZE) - 1)
121
122 #define PPOD_IDX_SHIFT          PPOD_COLOR_SIZE
123 #define PPOD_IDX_MAX_SIZE       24
124
125 #define S_PPOD_TID    0
126 #define M_PPOD_TID    0xFFFFFF
127 #define V_PPOD_TID(x) ((x) << S_PPOD_TID)
128
129 #define S_PPOD_VALID    24
130 #define V_PPOD_VALID(x) ((x) << S_PPOD_VALID)
131 #define F_PPOD_VALID    V_PPOD_VALID(1U)
132
133 #define S_PPOD_COLOR    0
134 #define M_PPOD_COLOR    0x3F
135 #define V_PPOD_COLOR(x) ((x) << S_PPOD_COLOR)
136
137 #define S_PPOD_TAG    6
138 #define M_PPOD_TAG    0xFFFFFF
139 #define V_PPOD_TAG(x) ((x) << S_PPOD_TAG)
140
141 #define S_PPOD_PGSZ    30
142 #define M_PPOD_PGSZ    0x3
143 #define V_PPOD_PGSZ(x) ((x) << S_PPOD_PGSZ)
144
145 /*
146  * large memory chunk allocation/release
147  * use vmalloc() if kmalloc() fails
148  */
149 static inline void *cxgb3i_alloc_big_mem(unsigned int size,
150                                          gfp_t gfp)
151 {
152         void *p = kmalloc(size, gfp);
153         if (!p)
154                 p = vmalloc(size);
155         if (p)
156                 memset(p, 0, size);
157         return p;
158 }
159
160 static inline void cxgb3i_free_big_mem(void *addr)
161 {
162         if (is_vmalloc_addr(addr))
163                 vfree(addr);
164         else
165                 kfree(addr);
166 }
167
168 /*
169  * cxgb3i ddp tag are 32 bits, it consists of reserved bits used by h/w and
170  * non-reserved bits that can be used by the iscsi s/w.
171  * The reserved bits are identified by the rsvd_bits and rsvd_shift fields
172  * in struct cxgb3i_tag_format.
173  *
174  * The upper most reserved bit can be used to check if a tag is ddp tag or not:
175  *      if the bit is 0, the tag is a valid ddp tag
176  */
177
178 /**
179  * cxgb3i_is_ddp_tag - check if a given tag is a hw/ddp tag
180  * @tformat: tag format information
181  * @tag: tag to be checked
182  *
183  * return true if the tag is a ddp tag, false otherwise.
184  */
185 static inline int cxgb3i_is_ddp_tag(struct cxgb3i_tag_format *tformat, u32 tag)
186 {
187         return !(tag & (1 << (tformat->rsvd_bits + tformat->rsvd_shift - 1)));
188 }
189
190 /**
191  * cxgb3i_sw_tag_usable - check if s/w tag has enough bits left for hw bits
192  * @tformat: tag format information
193  * @sw_tag: s/w tag to be checked
194  *
195  * return true if the tag can be used for hw ddp tag, false otherwise.
196  */
197 static inline int cxgb3i_sw_tag_usable(struct cxgb3i_tag_format *tformat,
198                                         u32 sw_tag)
199 {
200         sw_tag >>= (32 - tformat->rsvd_bits);
201         return !sw_tag;
202 }
203
204 /**
205  * cxgb3i_set_non_ddp_tag - mark a given s/w tag as an invalid ddp tag
206  * @tformat: tag format information
207  * @sw_tag: s/w tag to be checked
208  *
209  * insert 1 at the upper most reserved bit to mark it as an invalid ddp tag.
210  */
211 static inline u32 cxgb3i_set_non_ddp_tag(struct cxgb3i_tag_format *tformat,
212                                          u32 sw_tag)
213 {
214         unsigned char shift = tformat->rsvd_bits + tformat->rsvd_shift - 1;
215         u32 mask = (1 << shift) - 1;
216
217         if (sw_tag && (sw_tag & ~mask)) {
218                 u32 v1 = sw_tag & ((1 << shift) - 1);
219                 u32 v2 = (sw_tag >> (shift - 1)) << shift;
220
221                 return v2 | v1 | 1 << shift;
222         }
223         return sw_tag | 1 << shift;
224 }
225
226 /**
227  * cxgb3i_ddp_tag_base - shift s/w tag bits so that reserved bits are not used
228  * @tformat: tag format information
229  * @sw_tag: s/w tag to be checked
230  */
231 static inline u32 cxgb3i_ddp_tag_base(struct cxgb3i_tag_format *tformat,
232                                       u32 sw_tag)
233 {
234         u32 mask = (1 << tformat->rsvd_shift) - 1;
235
236         if (sw_tag && (sw_tag & ~mask)) {
237                 u32 v1 = sw_tag & mask;
238                 u32 v2 = sw_tag >> tformat->rsvd_shift;
239
240                 v2 <<= tformat->rsvd_shift + tformat->rsvd_bits;
241                 return v2 | v1;
242         }
243         return sw_tag;
244 }
245
246 /**
247  * cxgb3i_tag_rsvd_bits - get the reserved bits used by the h/w
248  * @tformat: tag format information
249  * @tag: tag to be checked
250  *
251  * return the reserved bits in the tag
252  */
253 static inline u32 cxgb3i_tag_rsvd_bits(struct cxgb3i_tag_format *tformat,
254                                        u32 tag)
255 {
256         if (cxgb3i_is_ddp_tag(tformat, tag))
257                 return (tag >> tformat->rsvd_shift) & tformat->rsvd_mask;
258         return 0;
259 }
260
261 /**
262  * cxgb3i_tag_nonrsvd_bits - get the non-reserved bits used by the s/w
263  * @tformat: tag format information
264  * @tag: tag to be checked
265  *
266  * return the non-reserved bits in the tag.
267  */
268 static inline u32 cxgb3i_tag_nonrsvd_bits(struct cxgb3i_tag_format *tformat,
269                                           u32 tag)
270 {
271         unsigned char shift = tformat->rsvd_bits + tformat->rsvd_shift - 1;
272         u32 v1, v2;
273
274         if (cxgb3i_is_ddp_tag(tformat, tag)) {
275                 v1 = tag & ((1 << tformat->rsvd_shift) - 1);
276                 v2 = (tag >> (shift + 1)) << tformat->rsvd_shift;
277         } else {
278                 u32 mask = (1 << shift) - 1;
279
280                 tag &= ~(1 << shift);
281                 v1 = tag & mask;
282                 v2 = (tag >> 1) & ~mask;
283         }
284         return v1 | v2;
285 }
286
287 int cxgb3i_ddp_tag_reserve(struct t3cdev *, unsigned int tid,
288                            struct cxgb3i_tag_format *, u32 *tag,
289                            struct cxgb3i_gather_list *, gfp_t gfp);
290 void cxgb3i_ddp_tag_release(struct t3cdev *, u32 tag);
291
292 struct cxgb3i_gather_list *cxgb3i_ddp_make_gl(unsigned int xferlen,
293                                 struct scatterlist *sgl,
294                                 unsigned int sgcnt,
295                                 struct pci_dev *pdev,
296                                 gfp_t gfp);
297 void cxgb3i_ddp_release_gl(struct cxgb3i_gather_list *gl,
298                                 struct pci_dev *pdev);
299
300 int cxgb3i_setup_conn_host_pagesize(struct t3cdev *, unsigned int tid,
301                                     int reply);
302 int cxgb3i_setup_conn_pagesize(struct t3cdev *, unsigned int tid, int reply,
303                                unsigned long pgsz);
304 int cxgb3i_setup_conn_digest(struct t3cdev *, unsigned int tid,
305                                 int hcrc, int dcrc, int reply);
306 int cxgb3i_ddp_find_page_index(unsigned long pgsz);
307 int cxgb3i_adapter_ddp_info(struct t3cdev *, struct cxgb3i_tag_format *,
308                             unsigned int *txsz, unsigned int *rxsz);
309
310 void cxgb3i_ddp_init(struct t3cdev *);
311 void cxgb3i_ddp_cleanup(struct t3cdev *);
312 #endif