InterfaceRx.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #include "headers.h"
  2. static void handle_control_packet(struct bcm_interface_adapter *interface,
  3. struct bcm_mini_adapter *ad,
  4. struct bcm_leader *leader,
  5. struct sk_buff *skb,
  6. struct urb *urb)
  7. {
  8. BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL,
  9. "Received control pkt...");
  10. *(PUSHORT)skb->data = leader->Status;
  11. memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer +
  12. (sizeof(struct bcm_leader)), leader->PLength);
  13. skb->len = leader->PLength + sizeof(USHORT);
  14. spin_lock(&ad->control_queue_lock);
  15. ENQUEUEPACKET(ad->RxControlHead, ad->RxControlTail, skb);
  16. spin_unlock(&ad->control_queue_lock);
  17. atomic_inc(&ad->cntrlpktCnt);
  18. wake_up(&ad->process_rx_cntrlpkt);
  19. }
  20. static void format_eth_hdr_to_stack(struct bcm_interface_adapter *interface,
  21. struct bcm_mini_adapter *ad,
  22. struct bcm_leader *p_leader,
  23. struct sk_buff *skb,
  24. struct urb *urb,
  25. UINT ui_index,
  26. int queue_index,
  27. bool b_header_supression_endabled)
  28. {
  29. /*
  30. * Data Packet, Format a proper Ethernet Header
  31. * and give it to the stack
  32. */
  33. BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_DATA,
  34. DBG_LVL_ALL, "Received Data pkt...");
  35. skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES);
  36. memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer +
  37. sizeof(struct bcm_leader), p_leader->PLength);
  38. skb->dev = ad->dev;
  39. /* currently skb->len has extra ETH_HLEN bytes in the beginning */
  40. skb_put(skb, p_leader->PLength + ETH_HLEN);
  41. ad->PackInfo[queue_index].uiTotalRxBytes += p_leader->PLength;
  42. ad->PackInfo[queue_index].uiThisPeriodRxBytes += p_leader->PLength;
  43. BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_DATA,
  44. DBG_LVL_ALL, "Received Data pkt of len :0x%X",
  45. p_leader->PLength);
  46. if (netif_running(ad->dev)) {
  47. /* Moving ahead by ETH_HLEN to the data ptr as received from FW */
  48. skb_pull(skb, ETH_HLEN);
  49. PHSReceive(ad, p_leader->Vcid, skb, &skb->len,
  50. NULL, b_header_supression_endabled);
  51. if (!ad->PackInfo[queue_index].bEthCSSupport) {
  52. skb_push(skb, ETH_HLEN);
  53. memcpy(skb->data, skb->dev->dev_addr, 6);
  54. memcpy(skb->data+6, skb->dev->dev_addr, 6);
  55. (*(skb->data+11))++;
  56. *(skb->data+12) = 0x08;
  57. *(skb->data+13) = 0x00;
  58. p_leader->PLength += ETH_HLEN;
  59. }
  60. skb->protocol = eth_type_trans(skb, ad->dev);
  61. netif_rx(skb);
  62. } else {
  63. BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX,
  64. RX_DATA, DBG_LVL_ALL,
  65. "i/f not up hance freeing SKB...");
  66. dev_kfree_skb(skb);
  67. }
  68. ++ad->dev->stats.rx_packets;
  69. ad->dev->stats.rx_bytes += p_leader->PLength;
  70. for (ui_index = 0; ui_index < MIBS_MAX_HIST_ENTRIES; ui_index++) {
  71. if ((p_leader->PLength <=
  72. MIBS_PKTSIZEHIST_RANGE*(ui_index+1)) &&
  73. (p_leader->PLength > MIBS_PKTSIZEHIST_RANGE*(ui_index)))
  74. ad->aRxPktSizeHist[ui_index]++;
  75. }
  76. }
  77. static int SearchVcid(struct bcm_mini_adapter *Adapter, unsigned short usVcid)
  78. {
  79. int iIndex = 0;
  80. for (iIndex = (NO_OF_QUEUES-1); iIndex >= 0; iIndex--)
  81. if (Adapter->PackInfo[iIndex].usVCID_Value == usVcid)
  82. return iIndex;
  83. return NO_OF_QUEUES+1;
  84. }
  85. static struct bcm_usb_rcb *
  86. GetBulkInRcb(struct bcm_interface_adapter *psIntfAdapter)
  87. {
  88. struct bcm_usb_rcb *pRcb = NULL;
  89. UINT index = 0;
  90. if ((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) &&
  91. (psIntfAdapter->psAdapter->StopAllXaction == false)) {
  92. index = atomic_read(&psIntfAdapter->uCurrRcb);
  93. pRcb = &psIntfAdapter->asUsbRcb[index];
  94. pRcb->bUsed = TRUE;
  95. pRcb->psIntfAdapter = psIntfAdapter;
  96. BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DPC,
  97. DBG_LVL_ALL, "Got Rx desc %d used %d", index,
  98. atomic_read(&psIntfAdapter->uNumRcbUsed));
  99. index = (index + 1) % MAXIMUM_USB_RCB;
  100. atomic_set(&psIntfAdapter->uCurrRcb, index);
  101. atomic_inc(&psIntfAdapter->uNumRcbUsed);
  102. }
  103. return pRcb;
  104. }
  105. /*this is receive call back - when pkt available for receive (BULK IN- end point)*/
  106. static void read_bulk_callback(struct urb *urb)
  107. {
  108. struct sk_buff *skb = NULL;
  109. bool bHeaderSupressionEnabled = false;
  110. int QueueIndex = NO_OF_QUEUES + 1;
  111. UINT uiIndex = 0;
  112. struct bcm_usb_rcb *pRcb = (struct bcm_usb_rcb *)urb->context;
  113. struct bcm_interface_adapter *psIntfAdapter = pRcb->psIntfAdapter;
  114. struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter;
  115. struct bcm_leader *pLeader = urb->transfer_buffer;
  116. if (unlikely(netif_msg_rx_status(Adapter)))
  117. pr_info(PFX "%s: rx urb status %d length %d\n",
  118. Adapter->dev->name, urb->status, urb->actual_length);
  119. if ((Adapter->device_removed == TRUE) ||
  120. (TRUE == Adapter->bEndPointHalted) ||
  121. (0 == urb->actual_length)) {
  122. pRcb->bUsed = false;
  123. atomic_dec(&psIntfAdapter->uNumRcbUsed);
  124. return;
  125. }
  126. if (urb->status != STATUS_SUCCESS) {
  127. if (urb->status == -EPIPE) {
  128. Adapter->bEndPointHalted = TRUE;
  129. wake_up(&Adapter->tx_packet_wait_queue);
  130. } else {
  131. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC,
  132. DBG_LVL_ALL,
  133. "Rx URB has got cancelled. status :%d",
  134. urb->status);
  135. }
  136. pRcb->bUsed = false;
  137. atomic_dec(&psIntfAdapter->uNumRcbUsed);
  138. urb->status = STATUS_SUCCESS;
  139. return;
  140. }
  141. if (Adapter->bDoSuspend && (Adapter->bPreparingForLowPowerMode)) {
  142. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,
  143. "device is going in low power mode while PMU option selected..hence rx packet should not be process");
  144. return;
  145. }
  146. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,
  147. "Read back done len %d\n", pLeader->PLength);
  148. if (!pLeader->PLength) {
  149. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,
  150. "Leader Length 0");
  151. atomic_dec(&psIntfAdapter->uNumRcbUsed);
  152. return;
  153. }
  154. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,
  155. "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX",
  156. pLeader->Status, pLeader->PLength, pLeader->Vcid);
  157. if (MAX_CNTL_PKT_SIZE < pLeader->PLength) {
  158. if (netif_msg_rx_err(Adapter))
  159. pr_info(PFX "%s: corrupted leader length...%d\n",
  160. Adapter->dev->name, pLeader->PLength);
  161. ++Adapter->dev->stats.rx_dropped;
  162. atomic_dec(&psIntfAdapter->uNumRcbUsed);
  163. return;
  164. }
  165. QueueIndex = SearchVcid(Adapter, pLeader->Vcid);
  166. if (QueueIndex < NO_OF_QUEUES) {
  167. bHeaderSupressionEnabled =
  168. Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled;
  169. bHeaderSupressionEnabled =
  170. bHeaderSupressionEnabled & Adapter->bPHSEnabled;
  171. }
  172. skb = dev_alloc_skb(pLeader->PLength + SKB_RESERVE_PHS_BYTES +
  173. SKB_RESERVE_ETHERNET_HEADER);
  174. if (!skb) {
  175. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
  176. "NO SKBUFF!!! Dropping the Packet");
  177. atomic_dec(&psIntfAdapter->uNumRcbUsed);
  178. return;
  179. }
  180. /* If it is a control Packet, then call handle_bcm_packet ()*/
  181. if ((ntohs(pLeader->Vcid) == VCID_CONTROL_PACKET) ||
  182. (!(pLeader->Status >= 0x20 && pLeader->Status <= 0x3F))) {
  183. handle_control_packet(psIntfAdapter, Adapter, pLeader, skb,
  184. urb);
  185. } else {
  186. format_eth_hdr_to_stack(psIntfAdapter, Adapter, pLeader, skb,
  187. urb, uiIndex, QueueIndex,
  188. bHeaderSupressionEnabled);
  189. }
  190. Adapter->PrevNumRecvDescs++;
  191. pRcb->bUsed = false;
  192. atomic_dec(&psIntfAdapter->uNumRcbUsed);
  193. }
  194. static int ReceiveRcb(struct bcm_interface_adapter *psIntfAdapter,
  195. struct bcm_usb_rcb *pRcb)
  196. {
  197. struct urb *urb = pRcb->urb;
  198. int retval = 0;
  199. usb_fill_bulk_urb(urb, psIntfAdapter->udev,
  200. usb_rcvbulkpipe(psIntfAdapter->udev,
  201. psIntfAdapter->sBulkIn.bulk_in_endpointAddr),
  202. urb->transfer_buffer,
  203. BCM_USB_MAX_READ_LENGTH,
  204. read_bulk_callback, pRcb);
  205. if (false == psIntfAdapter->psAdapter->device_removed &&
  206. false == psIntfAdapter->psAdapter->bEndPointHalted &&
  207. false == psIntfAdapter->bSuspended &&
  208. false == psIntfAdapter->bPreparingForBusSuspend) {
  209. retval = usb_submit_urb(urb, GFP_ATOMIC);
  210. if (retval) {
  211. BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX,
  212. RX_DPC, DBG_LVL_ALL,
  213. "failed submitting read urb, error %d",
  214. retval);
  215. /* if this return value is because of pipe halt. need to clear this. */
  216. if (retval == -EPIPE) {
  217. psIntfAdapter->psAdapter->bEndPointHalted = TRUE;
  218. wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
  219. }
  220. }
  221. }
  222. return retval;
  223. }
  224. /*
  225. Function: InterfaceRx
  226. Description: This is the hardware specific Function for Receiving
  227. data packet/control packets from the device.
  228. Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context
  229. Return: TRUE - If Rx was successful.
  230. Other - If an error occurred.
  231. */
  232. bool InterfaceRx(struct bcm_interface_adapter *psIntfAdapter)
  233. {
  234. USHORT RxDescCount = NUM_RX_DESC -
  235. atomic_read(&psIntfAdapter->uNumRcbUsed);
  236. struct bcm_usb_rcb *pRcb = NULL;
  237. while (RxDescCount) {
  238. pRcb = GetBulkInRcb(psIntfAdapter);
  239. if (pRcb == NULL) {
  240. BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
  241. DBG_TYPE_PRINTK, 0, 0,
  242. "Unable to get Rcb pointer");
  243. return false;
  244. }
  245. ReceiveRcb(psIntfAdapter, pRcb);
  246. RxDescCount--;
  247. }
  248. return TRUE;
  249. }