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