htc_packet.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*
  2. * Copyright (c) 2013-2014, 2016 The Linux Foundation. All rights reserved.
  3. *
  4. * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  5. *
  6. *
  7. * Permission to use, copy, modify, and/or distribute this software for
  8. * any purpose with or without fee is hereby granted, provided that the
  9. * above copyright notice and this permission notice appear in all
  10. * copies.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  13. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  14. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  15. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  16. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  17. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  18. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  19. * PERFORMANCE OF THIS SOFTWARE.
  20. */
  21. /*
  22. * This file was originally distributed by Qualcomm Atheros, Inc.
  23. * under proprietary terms before Copyright ownership was assigned
  24. * to the Linux Foundation.
  25. */
  26. #ifndef HTC_PACKET_H_
  27. #define HTC_PACKET_H_
  28. #include <osdep.h>
  29. #include "dl_list.h"
  30. /* ------ Endpoint IDS ------ */
  31. typedef enum {
  32. ENDPOINT_UNUSED = -1,
  33. ENDPOINT_0 = 0,
  34. ENDPOINT_1 = 1,
  35. ENDPOINT_2 = 2,
  36. ENDPOINT_3,
  37. ENDPOINT_4,
  38. ENDPOINT_5,
  39. ENDPOINT_6,
  40. ENDPOINT_7,
  41. ENDPOINT_8,
  42. ENDPOINT_MAX,
  43. } HTC_ENDPOINT_ID;
  44. struct _HTC_PACKET;
  45. typedef void (*HTC_PACKET_COMPLETION)(void *, struct _HTC_PACKET *);
  46. typedef uint16_t HTC_TX_TAG;
  47. typedef struct _HTC_TX_PACKET_INFO {
  48. HTC_TX_TAG Tag; /* tag used to selective flush packets */
  49. int CreditsUsed; /* number of credits used for this TX packet (HTC internal) */
  50. uint8_t SendFlags; /* send flags (HTC internal) */
  51. int SeqNo; /* internal seq no for debugging (HTC internal) */
  52. uint32_t Flags; /* internal use */
  53. } HTC_TX_PACKET_INFO;
  54. /**
  55. * HTC_TX_PACKET_TAG_XXX - #defines for tagging packets for special handling
  56. * HTC_TX_PACKET_TAG_ALL: zero is reserved and used to flush ALL packets
  57. * HTC_TX_PACKET_TAG_INTERNAL: internal tags start here
  58. * HTC_TX_PACKET_TAG_USER_DEFINED: user-defined tags start here
  59. * HTC_TX_PACKET_TAG_BUNDLED: indicate this is a bundled tx packet
  60. * HTC_TX_PACKET_TAG_AUTO_PM: indicate a power management wmi command
  61. */
  62. #define HTC_TX_PACKET_TAG_ALL 0
  63. #define HTC_TX_PACKET_TAG_INTERNAL 1
  64. #define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_TX_PACKET_TAG_INTERNAL + 9)
  65. #define HTC_TX_PACKET_TAG_BUNDLED (HTC_TX_PACKET_TAG_USER_DEFINED + 1)
  66. #define HTC_TX_PACKET_TAG_AUTO_PM (HTC_TX_PACKET_TAG_USER_DEFINED + 2)
  67. /* Tag packet for runtime put after sending */
  68. #define HTC_TX_PACKET_TAG_RUNTIME_PUT (HTC_TX_PACKET_TAG_USER_DEFINED + 3)
  69. #define HTC_TX_PACKET_FLAG_FIXUP_NETBUF (1 << 0)
  70. typedef struct _HTC_RX_PACKET_INFO {
  71. uint32_t ExpectedHdr; /* HTC internal use */
  72. uint32_t HTCRxFlags; /* HTC internal use */
  73. uint32_t IndicationFlags; /* indication flags set on each RX packet indication */
  74. } HTC_RX_PACKET_INFO;
  75. #define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0) /* more packets on this endpoint are being fetched */
  76. /* wrapper around endpoint-specific packets */
  77. typedef struct _HTC_PACKET {
  78. DL_LIST ListLink; /* double link */
  79. void *pPktContext; /* caller's per packet specific context */
  80. uint8_t *pBufferStart; /* the true buffer start , the caller can
  81. store the real buffer start here. In
  82. receive callbacks, the HTC layer sets pBuffer
  83. to the start of the payload past the header. This
  84. field allows the caller to reset pBuffer when it
  85. recycles receive packets back to HTC */
  86. /*
  87. * Pointer to the start of the buffer. In the transmit
  88. * direction this points to the start of the payload. In the
  89. * receive direction, however, the buffer when queued up
  90. * points to the start of the HTC header but when returned
  91. * to the caller points to the start of the payload
  92. */
  93. uint8_t *pBuffer; /* payload start (RX/TX) */
  94. uint32_t BufferLength; /* length of buffer */
  95. uint32_t ActualLength; /* actual length of payload */
  96. HTC_ENDPOINT_ID Endpoint; /* endpoint that this packet was sent/recv'd from */
  97. A_STATUS Status; /* completion status */
  98. union {
  99. HTC_TX_PACKET_INFO AsTx; /* Tx Packet specific info */
  100. HTC_RX_PACKET_INFO AsRx; /* Rx Packet specific info */
  101. } PktInfo;
  102. /* the following fields are for internal HTC use */
  103. uint32_t netbufOrigHeadRoom;
  104. HTC_PACKET_COMPLETION Completion; /* completion */
  105. void *pContext; /* HTC private completion context */
  106. void *pNetBufContext; /* optimization for network-oriented data, the HTC packet
  107. can pass the network buffer corresponding to the HTC packet
  108. lower layers may optimized the transfer knowing this is
  109. a network buffer */
  110. } HTC_PACKET;
  111. #define COMPLETE_HTC_PACKET(p, status) \
  112. { \
  113. (p)->Status = (status); \
  114. (p)->Completion((p)->pContext, (p)); \
  115. }
  116. #define INIT_HTC_PACKET_INFO(p, b, len) \
  117. { \
  118. (p)->pBufferStart = (b); \
  119. (p)->BufferLength = (len); \
  120. }
  121. /* macro to set an initial RX packet for refilling HTC */
  122. #define SET_HTC_PACKET_INFO_RX_REFILL(p, c, b, len, ep) \
  123. do { \
  124. (p)->pPktContext = (c); \
  125. (p)->pBuffer = (b); \
  126. (p)->pBufferStart = (b); \
  127. (p)->BufferLength = (len); \
  128. (p)->Endpoint = (ep); \
  129. } while (0)
  130. /* fast macro to recycle an RX packet that will be re-queued to HTC */
  131. #define HTC_PACKET_RESET_RX(p) \
  132. { (p)->pBuffer = (p)->pBufferStart; (p)->ActualLength = 0; }
  133. /* macro to set packet parameters for TX */
  134. #define SET_HTC_PACKET_INFO_TX(p, c, b, len, ep, tag) \
  135. do { \
  136. (p)->pPktContext = (c); \
  137. (p)->pBuffer = (b); \
  138. (p)->ActualLength = (len); \
  139. (p)->Endpoint = (ep); \
  140. (p)->PktInfo.AsTx.Tag = (tag); \
  141. (p)->PktInfo.AsTx.Flags = 0; \
  142. (p)->PktInfo.AsTx.SendFlags = 0; \
  143. } while (0)
  144. #define SET_HTC_PACKET_NET_BUF_CONTEXT(p, nb) \
  145. do { \
  146. (p)->pNetBufContext = (nb); \
  147. } while (0)
  148. #define GET_HTC_PACKET_NET_BUF_CONTEXT(p) (p)->pNetBufContext
  149. /* HTC Packet Queueing Macros */
  150. typedef struct _HTC_PACKET_QUEUE {
  151. DL_LIST QueueHead;
  152. int Depth;
  153. } HTC_PACKET_QUEUE;
  154. /* initialize queue */
  155. #define INIT_HTC_PACKET_QUEUE(pQ) \
  156. { \
  157. DL_LIST_INIT(&(pQ)->QueueHead); \
  158. (pQ)->Depth = 0; \
  159. }
  160. /* enqueue HTC packet to the tail of the queue */
  161. #define HTC_PACKET_ENQUEUE(pQ, p) \
  162. { dl_list_insert_tail(&(pQ)->QueueHead, &(p)->ListLink); \
  163. (pQ)->Depth++; \
  164. }
  165. /* enqueue HTC packet to the tail of the queue */
  166. #define HTC_PACKET_ENQUEUE_TO_HEAD(pQ, p) \
  167. { dl_list_insert_head(&(pQ)->QueueHead, &(p)->ListLink); \
  168. (pQ)->Depth++; \
  169. }
  170. /* test if a queue is empty */
  171. #define HTC_QUEUE_EMPTY(pQ) ((pQ)->Depth == 0)
  172. /* get packet at head without removing it */
  173. static inline HTC_PACKET *htc_get_pkt_at_head(HTC_PACKET_QUEUE *queue)
  174. {
  175. if (queue->Depth == 0) {
  176. return NULL;
  177. }
  178. return
  179. A_CONTAINING_STRUCT((DL_LIST_GET_ITEM_AT_HEAD(&queue->QueueHead)),
  180. HTC_PACKET, ListLink);
  181. }
  182. /* remove a packet from a queue, where-ever it is in the queue */
  183. #define HTC_PACKET_REMOVE(pQ, p) \
  184. { \
  185. dl_list_remove(&(p)->ListLink); \
  186. (pQ)->Depth--; \
  187. }
  188. /* dequeue an HTC packet from the head of the queue */
  189. static inline HTC_PACKET *htc_packet_dequeue(HTC_PACKET_QUEUE *queue)
  190. {
  191. DL_LIST *pItem = dl_list_remove_item_from_head(&queue->QueueHead);
  192. if (pItem != NULL) {
  193. queue->Depth--;
  194. return A_CONTAINING_STRUCT(pItem, HTC_PACKET, ListLink);
  195. }
  196. return NULL;
  197. }
  198. /* dequeue an HTC packet from the tail of the queue */
  199. static inline HTC_PACKET *htc_packet_dequeue_tail(HTC_PACKET_QUEUE *queue)
  200. {
  201. DL_LIST *pItem = dl_list_remove_item_from_tail(&queue->QueueHead);
  202. if (pItem != NULL) {
  203. queue->Depth--;
  204. return A_CONTAINING_STRUCT(pItem, HTC_PACKET, ListLink);
  205. }
  206. return NULL;
  207. }
  208. #define HTC_PACKET_QUEUE_DEPTH(pQ) (pQ)->Depth
  209. #define HTC_GET_ENDPOINT_FROM_PKT(p) (p)->Endpoint
  210. #define HTC_GET_TAG_FROM_PKT(p) (p)->PktInfo.AsTx.Tag
  211. /* transfer the packets from one queue to the tail of another queue */
  212. #define HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(pQDest, pQSrc) \
  213. { \
  214. dl_list_transfer_items_to_tail(&(pQDest)->QueueHead, &(pQSrc)->QueueHead); \
  215. (pQDest)->Depth += (pQSrc)->Depth; \
  216. (pQSrc)->Depth = 0; \
  217. }
  218. /*
  219. * Transfer the packets from one queue to the head of another queue.
  220. * This xfer_to_head(q1,q2) is basically equivalent to xfer_to_tail(q2,q1),
  221. * but it updates the queue descriptor object for the initial queue to refer
  222. * to the concatenated queue.
  223. */
  224. #define HTC_PACKET_QUEUE_TRANSFER_TO_HEAD(pQDest, pQSrc) \
  225. { \
  226. dl_list_transfer_items_to_head(&(pQDest)->QueueHead, &(pQSrc)->QueueHead); \
  227. (pQDest)->Depth += (pQSrc)->Depth; \
  228. (pQSrc)->Depth = 0; \
  229. }
  230. /* fast version to init and add a single packet to a queue */
  231. #define INIT_HTC_PACKET_QUEUE_AND_ADD(pQ, pP) \
  232. { \
  233. DL_LIST_INIT_AND_ADD(&(pQ)->QueueHead, &(pP)->ListLink) \
  234. (pQ)->Depth = 1; \
  235. }
  236. #define HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pQ, pPTemp) \
  237. ITERATE_OVER_LIST_ALLOW_REMOVE(&(pQ)->QueueHead, (pPTemp), HTC_PACKET, ListLink)
  238. #define HTC_PACKET_QUEUE_ITERATE_IS_VALID(pQ) ITERATE_IS_VALID(&(pQ)->QueueHead)
  239. #define HTC_PACKET_QUEUE_ITERATE_RESET(pQ) ITERATE_RESET(&(pQ)->QueueHead)
  240. #define HTC_PACKET_QUEUE_ITERATE_END ITERATE_END
  241. #endif /*HTC_PACKET_H_ */