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