cxgb3i_ddp.h 8.1 KB

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