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