wb35rx.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /*
  2. * ============================================================================
  3. * Copyright (c) 1996-2002 Winbond Electronic Corporation
  4. *
  5. * Module Name:
  6. * Wb35Rx.c
  7. *
  8. * Abstract:
  9. * Processing the Rx message from down layer
  10. *
  11. * ============================================================================
  12. */
  13. #include <linux/usb.h>
  14. #include <linux/slab.h>
  15. #include "core.h"
  16. #include "wb35rx_f.h"
  17. static void packet_came(struct ieee80211_hw *hw, char *pRxBufferAddress, int PacketSize)
  18. {
  19. struct wbsoft_priv *priv = hw->priv;
  20. struct sk_buff *skb;
  21. struct ieee80211_rx_status rx_status = {0};
  22. if (!priv->enabled)
  23. return;
  24. skb = dev_alloc_skb(PacketSize);
  25. if (!skb) {
  26. printk("Not enough memory for packet, FIXME\n");
  27. return;
  28. }
  29. memcpy(skb_put(skb, PacketSize), pRxBufferAddress, PacketSize);
  30. memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
  31. ieee80211_rx_irqsafe(hw, skb);
  32. }
  33. static void Wb35Rx_adjust(struct wb35_descriptor *pRxDes)
  34. {
  35. u32 *pRxBufferAddress;
  36. u32 DecryptionMethod;
  37. u32 i;
  38. u16 BufferSize;
  39. DecryptionMethod = pRxDes->R01.R01_decryption_method;
  40. pRxBufferAddress = pRxDes->buffer_address[0];
  41. BufferSize = pRxDes->buffer_size[0];
  42. /* Adjust the last part of data. Only data left */
  43. BufferSize -= 4; /* For CRC-32 */
  44. if (DecryptionMethod)
  45. BufferSize -= 4;
  46. if (DecryptionMethod == 3) /* For CCMP */
  47. BufferSize -= 4;
  48. /* Adjust the IV field which after 802.11 header and ICV field. */
  49. if (DecryptionMethod == 1) { /* For WEP */
  50. for (i = 6; i > 0; i--)
  51. pRxBufferAddress[i] = pRxBufferAddress[i - 1];
  52. pRxDes->buffer_address[0] = pRxBufferAddress + 1;
  53. BufferSize -= 4; /* 4 byte for IV */
  54. } else if (DecryptionMethod) { /* For TKIP and CCMP */
  55. for (i = 7; i > 1; i--)
  56. pRxBufferAddress[i] = pRxBufferAddress[i - 2];
  57. pRxDes->buffer_address[0] = pRxBufferAddress + 2; /* Update the descriptor, shift 8 byte */
  58. BufferSize -= 8; /* 8 byte for IV + ICV */
  59. }
  60. pRxDes->buffer_size[0] = BufferSize;
  61. }
  62. static u16 Wb35Rx_indicate(struct ieee80211_hw *hw)
  63. {
  64. struct wbsoft_priv *priv = hw->priv;
  65. struct hw_data *pHwData = &priv->sHwData;
  66. struct wb35_descriptor RxDes;
  67. struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
  68. u8 *pRxBufferAddress;
  69. u16 PacketSize;
  70. u16 stmp, BufferSize, stmp2 = 0;
  71. u32 RxBufferId;
  72. /* Only one thread be allowed to run into the following */
  73. do {
  74. RxBufferId = pWb35Rx->RxProcessIndex;
  75. if (pWb35Rx->RxOwner[RxBufferId]) /* Owner by VM */
  76. break;
  77. pWb35Rx->RxProcessIndex++;
  78. pWb35Rx->RxProcessIndex %= MAX_USB_RX_BUFFER_NUMBER;
  79. pRxBufferAddress = pWb35Rx->pDRx;
  80. BufferSize = pWb35Rx->RxBufferSize[RxBufferId];
  81. /* Parse the bulkin buffer */
  82. while (BufferSize >= 4) {
  83. if ((cpu_to_le32(*(u32 *)pRxBufferAddress) & 0x0fffffff) == RX_END_TAG) /* Is ending? */
  84. break;
  85. /* Get the R00 R01 first */
  86. RxDes.R00.value = le32_to_cpu(*(u32 *)pRxBufferAddress);
  87. PacketSize = (u16)RxDes.R00.R00_receive_byte_count;
  88. RxDes.R01.value = le32_to_cpu(*((u32 *)(pRxBufferAddress + 4)));
  89. /* For new DMA 4k */
  90. if ((PacketSize & 0x03) > 0)
  91. PacketSize -= 4;
  92. /* Basic check for Rx length. Is length valid? */
  93. if (PacketSize > MAX_PACKET_SIZE) {
  94. pr_debug("Serious ERROR : Rx data size too long, size =%d\n", PacketSize);
  95. pWb35Rx->EP3vm_state = VM_STOP;
  96. pWb35Rx->Ep3ErrorCount2++;
  97. break;
  98. }
  99. /*
  100. * Wb35Rx_indicate() is called synchronously so it isn't
  101. * necessary to set "RxDes.Desctriptor_ID = RxBufferID;"
  102. */
  103. BufferSize -= 8; /* subtract 8 byte for 35's USB header length */
  104. pRxBufferAddress += 8;
  105. RxDes.buffer_address[0] = pRxBufferAddress;
  106. RxDes.buffer_size[0] = PacketSize;
  107. RxDes.buffer_number = 1;
  108. RxDes.buffer_start_index = 0;
  109. RxDes.buffer_total_size = RxDes.buffer_size[0];
  110. Wb35Rx_adjust(&RxDes);
  111. packet_came(hw, pRxBufferAddress, PacketSize);
  112. /* Move RxBuffer point to the next */
  113. stmp = PacketSize + 3;
  114. stmp &= ~0x03; /* 4n alignment */
  115. pRxBufferAddress += stmp;
  116. BufferSize -= stmp;
  117. stmp2 += stmp;
  118. }
  119. /* Reclaim resource */
  120. pWb35Rx->RxOwner[RxBufferId] = 1;
  121. } while (true);
  122. return stmp2;
  123. }
  124. static void Wb35Rx(struct ieee80211_hw *hw);
  125. static void Wb35Rx_Complete(struct urb *urb)
  126. {
  127. struct ieee80211_hw *hw = urb->context;
  128. struct wbsoft_priv *priv = hw->priv;
  129. struct hw_data *pHwData = &priv->sHwData;
  130. struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
  131. u8 *pRxBufferAddress;
  132. u32 SizeCheck;
  133. u16 BulkLength;
  134. u32 RxBufferId;
  135. struct R00_descriptor R00;
  136. /* Variable setting */
  137. pWb35Rx->EP3vm_state = VM_COMPLETED;
  138. pWb35Rx->EP3VM_status = urb->status; /* Store the last result of Irp */
  139. RxBufferId = pWb35Rx->CurrentRxBufferId;
  140. pRxBufferAddress = pWb35Rx->pDRx;
  141. BulkLength = (u16)urb->actual_length;
  142. /* The IRP is completed */
  143. pWb35Rx->EP3vm_state = VM_COMPLETED;
  144. if (pHwData->SurpriseRemove) /* Must be here, or RxBufferId is invalid */
  145. goto error;
  146. if (pWb35Rx->rx_halt)
  147. goto error;
  148. /* Start to process the data only in successful condition */
  149. pWb35Rx->RxOwner[RxBufferId] = 0; /* Set the owner to driver */
  150. R00.value = le32_to_cpu(*(u32 *)pRxBufferAddress);
  151. /* The URB is completed, check the result */
  152. if (pWb35Rx->EP3VM_status != 0) {
  153. pr_debug("EP3 IoCompleteRoutine return error\n");
  154. pWb35Rx->EP3vm_state = VM_STOP;
  155. goto error;
  156. }
  157. /* For recovering. check if operating in single USB mode */
  158. if (!HAL_USB_MODE_BURST(pHwData)) {
  159. SizeCheck = R00.R00_receive_byte_count;
  160. if ((SizeCheck & 0x03) > 0)
  161. SizeCheck -= 4;
  162. SizeCheck = (SizeCheck + 3) & ~0x03;
  163. SizeCheck += 12; /* 8 + 4 badbeef */
  164. if ((BulkLength > 1600) ||
  165. (SizeCheck > 1600) ||
  166. (BulkLength != SizeCheck) ||
  167. (BulkLength == 0)) { /* Add for fail Urb */
  168. pWb35Rx->EP3vm_state = VM_STOP;
  169. pWb35Rx->Ep3ErrorCount2++;
  170. }
  171. }
  172. /* Indicating the receiving data */
  173. pWb35Rx->ByteReceived += BulkLength;
  174. pWb35Rx->RxBufferSize[RxBufferId] = BulkLength;
  175. if (!pWb35Rx->RxOwner[RxBufferId])
  176. Wb35Rx_indicate(hw);
  177. kfree(pWb35Rx->pDRx);
  178. /* Do the next receive */
  179. Wb35Rx(hw);
  180. return;
  181. error:
  182. pWb35Rx->RxOwner[RxBufferId] = 1; /* Set the owner to hardware */
  183. atomic_dec(&pWb35Rx->RxFireCounter);
  184. pWb35Rx->EP3vm_state = VM_STOP;
  185. }
  186. /* This function cannot reentrain */
  187. static void Wb35Rx(struct ieee80211_hw *hw)
  188. {
  189. struct wbsoft_priv *priv = hw->priv;
  190. struct hw_data *pHwData = &priv->sHwData;
  191. struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
  192. u8 *pRxBufferAddress;
  193. struct urb *urb = pWb35Rx->RxUrb;
  194. int retv;
  195. u32 RxBufferId;
  196. /* Issuing URB */
  197. if (pHwData->SurpriseRemove)
  198. goto error;
  199. if (pWb35Rx->rx_halt)
  200. goto error;
  201. /* Get RxBuffer's ID */
  202. RxBufferId = pWb35Rx->RxBufferId;
  203. if (!pWb35Rx->RxOwner[RxBufferId]) {
  204. /* It's impossible to run here. */
  205. pr_debug("Rx driver fifo unavailable\n");
  206. goto error;
  207. }
  208. /* Update buffer point, then start to bulkin the data from USB */
  209. pWb35Rx->RxBufferId++;
  210. pWb35Rx->RxBufferId %= MAX_USB_RX_BUFFER_NUMBER;
  211. pWb35Rx->CurrentRxBufferId = RxBufferId;
  212. pWb35Rx->pDRx = kzalloc(MAX_USB_RX_BUFFER, GFP_ATOMIC);
  213. if (!pWb35Rx->pDRx) {
  214. printk("w35und: Rx memory alloc failed\n");
  215. goto error;
  216. }
  217. pRxBufferAddress = pWb35Rx->pDRx;
  218. usb_fill_bulk_urb(urb, pHwData->udev,
  219. usb_rcvbulkpipe(pHwData->udev, 3),
  220. pRxBufferAddress, MAX_USB_RX_BUFFER,
  221. Wb35Rx_Complete, hw);
  222. pWb35Rx->EP3vm_state = VM_RUNNING;
  223. retv = usb_submit_urb(urb, GFP_ATOMIC);
  224. if (retv != 0) {
  225. printk("Rx URB sending error\n");
  226. goto error;
  227. }
  228. return;
  229. error:
  230. /* VM stop */
  231. pWb35Rx->EP3vm_state = VM_STOP;
  232. atomic_dec(&pWb35Rx->RxFireCounter);
  233. }
  234. void Wb35Rx_start(struct ieee80211_hw *hw)
  235. {
  236. struct wbsoft_priv *priv = hw->priv;
  237. struct hw_data *pHwData = &priv->sHwData;
  238. struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
  239. /* Allow only one thread to run into the Wb35Rx() function */
  240. if (atomic_inc_return(&pWb35Rx->RxFireCounter) == 1) {
  241. pWb35Rx->EP3vm_state = VM_RUNNING;
  242. Wb35Rx(hw);
  243. } else
  244. atomic_dec(&pWb35Rx->RxFireCounter);
  245. }
  246. static void Wb35Rx_reset_descriptor(struct hw_data *pHwData)
  247. {
  248. struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
  249. u32 i;
  250. pWb35Rx->ByteReceived = 0;
  251. pWb35Rx->RxProcessIndex = 0;
  252. pWb35Rx->RxBufferId = 0;
  253. pWb35Rx->EP3vm_state = VM_STOP;
  254. pWb35Rx->rx_halt = 0;
  255. /* Initial the Queue. The last buffer is reserved for used if the Rx resource is unavailable. */
  256. for (i = 0; i < MAX_USB_RX_BUFFER_NUMBER; i++)
  257. pWb35Rx->RxOwner[i] = 1;
  258. }
  259. unsigned char Wb35Rx_initial(struct hw_data *pHwData)
  260. {
  261. struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
  262. /* Initial the Buffer Queue */
  263. Wb35Rx_reset_descriptor(pHwData);
  264. pWb35Rx->RxUrb = usb_alloc_urb(0, GFP_ATOMIC);
  265. return !!pWb35Rx->RxUrb;
  266. }
  267. void Wb35Rx_stop(struct hw_data *pHwData)
  268. {
  269. struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
  270. /* Canceling the Irp if already sends it out. */
  271. if (pWb35Rx->EP3vm_state == VM_RUNNING) {
  272. usb_unlink_urb(pWb35Rx->RxUrb); /* Only use unlink, let Wb35Rx_destroy to free them */
  273. pr_debug("EP3 Rx stop\n");
  274. }
  275. }
  276. /* Needs process context */
  277. void Wb35Rx_destroy(struct hw_data *pHwData)
  278. {
  279. struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
  280. do {
  281. msleep(10); /* Delay for waiting function enter */
  282. } while (pWb35Rx->EP3vm_state != VM_STOP);
  283. msleep(10); /* Delay for waiting function exit */
  284. if (pWb35Rx->RxUrb)
  285. usb_free_urb(pWb35Rx->RxUrb);
  286. pr_debug("Wb35Rx_destroy OK\n");
  287. }