InterfaceTx.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #include "headers.h"
  2. static void prepare_low_power_mode(struct urb *urb,
  3. struct bcm_interface_adapter *interface,
  4. struct bcm_mini_adapter *ps_adapter,
  5. struct bcm_mini_adapter *ad,
  6. struct bcm_link_request *p_control_msg,
  7. bool *b_power_down_msg)
  8. {
  9. if (((p_control_msg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) &&
  10. (p_control_msg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) {
  11. *b_power_down_msg = TRUE;
  12. /*
  13. * This covers the bus err while Idle Request msg
  14. * sent down.
  15. */
  16. if (urb->status != STATUS_SUCCESS) {
  17. ps_adapter->bPreparingForLowPowerMode = false;
  18. BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND,
  19. DBG_LVL_ALL,
  20. "Idle Mode Request msg failed to reach to Modem");
  21. /* Signalling the cntrl pkt path in Ioctl */
  22. wake_up(&ps_adapter->lowpower_mode_wait_queue);
  23. StartInterruptUrb(interface);
  24. return;
  25. }
  26. if (ps_adapter->bDoSuspend == false) {
  27. ps_adapter->IdleMode = TRUE;
  28. /* since going in Idle mode completed hence making this var false */
  29. ps_adapter->bPreparingForLowPowerMode = false;
  30. BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND,
  31. DBG_LVL_ALL,
  32. "Host Entered in Idle Mode State...");
  33. /* Signalling the cntrl pkt path in Ioctl*/
  34. wake_up(&ps_adapter->lowpower_mode_wait_queue);
  35. }
  36. } else if ((p_control_msg->Leader.Status == LINK_UP_CONTROL_REQ) &&
  37. (p_control_msg->szData[0] == LINK_UP_ACK) &&
  38. (p_control_msg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) &&
  39. (p_control_msg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) {
  40. /*
  41. * This covers the bus err while shutdown Request
  42. * msg sent down.
  43. */
  44. if (urb->status != STATUS_SUCCESS) {
  45. ps_adapter->bPreparingForLowPowerMode = false;
  46. BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND,
  47. DBG_LVL_ALL,
  48. "Shutdown Request Msg failed to reach to Modem");
  49. /* Signalling the cntrl pkt path in Ioctl */
  50. wake_up(&ps_adapter->lowpower_mode_wait_queue);
  51. StartInterruptUrb(interface);
  52. return;
  53. }
  54. *b_power_down_msg = TRUE;
  55. if (ps_adapter->bDoSuspend == false) {
  56. ps_adapter->bShutStatus = TRUE;
  57. /*
  58. * since going in shutdown mode completed hence
  59. * making this var false
  60. */
  61. ps_adapter->bPreparingForLowPowerMode = false;
  62. BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND,
  63. DBG_LVL_ALL,
  64. "Host Entered in shutdown Mode State...");
  65. /* Signalling the cntrl pkt path in Ioctl */
  66. wake_up(&ps_adapter->lowpower_mode_wait_queue);
  67. }
  68. }
  69. if (ps_adapter->bDoSuspend && *b_power_down_msg) {
  70. /* issuing bus suspend request */
  71. BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,
  72. "Issuing the Bus suspend request to USB stack");
  73. interface->bPreparingForBusSuspend = TRUE;
  74. schedule_work(&interface->usbSuspendWork);
  75. }
  76. }
  77. /*this is transmit call-back(BULK OUT)*/
  78. static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
  79. {
  80. struct bcm_usb_tcb *pTcb = (struct bcm_usb_tcb *)urb->context;
  81. struct bcm_interface_adapter *psIntfAdapter = pTcb->psIntfAdapter;
  82. struct bcm_link_request *pControlMsg =
  83. (struct bcm_link_request *)urb->transfer_buffer;
  84. struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter;
  85. bool bpowerDownMsg = false;
  86. struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
  87. if (unlikely(netif_msg_tx_done(Adapter)))
  88. pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name,
  89. urb->status);
  90. if (urb->status != STATUS_SUCCESS) {
  91. if (urb->status == -EPIPE) {
  92. psIntfAdapter->psAdapter->bEndPointHalted = TRUE;
  93. wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
  94. } else {
  95. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND,
  96. DBG_LVL_ALL,
  97. "Tx URB has got cancelled. status :%d",
  98. urb->status);
  99. }
  100. }
  101. pTcb->bUsed = false;
  102. atomic_dec(&psIntfAdapter->uNumTcbUsed);
  103. if (TRUE == psAdapter->bPreparingForLowPowerMode) {
  104. prepare_low_power_mode(urb, psIntfAdapter, psAdapter, Adapter,
  105. pControlMsg, &bpowerDownMsg);
  106. }
  107. usb_free_coherent(urb->dev, urb->transfer_buffer_length,
  108. urb->transfer_buffer, urb->transfer_dma);
  109. }
  110. static struct bcm_usb_tcb *GetBulkOutTcb(struct bcm_interface_adapter *psIntfAdapter)
  111. {
  112. struct bcm_usb_tcb *pTcb = NULL;
  113. UINT index = 0;
  114. if ((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) &&
  115. (psIntfAdapter->psAdapter->StopAllXaction == false)) {
  116. index = atomic_read(&psIntfAdapter->uCurrTcb);
  117. pTcb = &psIntfAdapter->asUsbTcb[index];
  118. pTcb->bUsed = TRUE;
  119. pTcb->psIntfAdapter = psIntfAdapter;
  120. BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX,
  121. NEXT_SEND, DBG_LVL_ALL,
  122. "Got Tx desc %d used %d",
  123. index,
  124. atomic_read(&psIntfAdapter->uNumTcbUsed));
  125. index = (index + 1) % MAXIMUM_USB_TCB;
  126. atomic_set(&psIntfAdapter->uCurrTcb, index);
  127. atomic_inc(&psIntfAdapter->uNumTcbUsed);
  128. }
  129. return pTcb;
  130. }
  131. static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter,
  132. struct bcm_usb_tcb *pTcb, PVOID data, int len)
  133. {
  134. struct urb *urb = pTcb->urb;
  135. int retval = 0;
  136. urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len,
  137. GFP_ATOMIC, &urb->transfer_dma);
  138. if (!urb->transfer_buffer) {
  139. BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
  140. "Error allocating memory\n");
  141. return -ENOMEM;
  142. }
  143. memcpy(urb->transfer_buffer, data, len);
  144. urb->transfer_buffer_length = len;
  145. BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, NEXT_SEND,
  146. DBG_LVL_ALL, "Sending Bulk out packet\n");
  147. /* For T3B,INT OUT end point will be used as bulk out end point */
  148. if ((psIntfAdapter->psAdapter->chip_id == T3B) &&
  149. (psIntfAdapter->bHighSpeedDevice == TRUE)) {
  150. usb_fill_int_urb(urb, psIntfAdapter->udev,
  151. psIntfAdapter->sBulkOut.bulk_out_pipe,
  152. urb->transfer_buffer, len, write_bulk_callback, pTcb,
  153. psIntfAdapter->sBulkOut.int_out_interval);
  154. } else {
  155. usb_fill_bulk_urb(urb, psIntfAdapter->udev,
  156. psIntfAdapter->sBulkOut.bulk_out_pipe,
  157. urb->transfer_buffer, len, write_bulk_callback, pTcb);
  158. }
  159. urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* For DMA transfer */
  160. if (false == psIntfAdapter->psAdapter->device_removed &&
  161. false == psIntfAdapter->psAdapter->bEndPointHalted &&
  162. false == psIntfAdapter->bSuspended &&
  163. false == psIntfAdapter->bPreparingForBusSuspend) {
  164. retval = usb_submit_urb(urb, GFP_ATOMIC);
  165. if (retval) {
  166. BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX,
  167. NEXT_SEND, DBG_LVL_ALL,
  168. "failed submitting write urb, error %d",
  169. retval);
  170. if (retval == -EPIPE) {
  171. psIntfAdapter->psAdapter->bEndPointHalted = TRUE;
  172. wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
  173. }
  174. }
  175. }
  176. return retval;
  177. }
  178. int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len)
  179. {
  180. struct bcm_usb_tcb *pTcb = NULL;
  181. struct bcm_interface_adapter *psIntfAdapter = arg;
  182. pTcb = GetBulkOutTcb(psIntfAdapter);
  183. if (pTcb == NULL) {
  184. BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
  185. "No URB to transmit packet, dropping packet");
  186. return -EFAULT;
  187. }
  188. return TransmitTcb(psIntfAdapter, pTcb, data, len);
  189. }