at v2.6.37 259 lines 8.1 kB view raw
1#include "headers.h" 2 3#ifndef BCM_SHM_INTERFACE 4 5/* 6Function: InterfaceTxDataPacket 7 8Description: This is the hardware specific Function for Transmitting 9 data packet to the device. 10 11Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context 12 PVOID Packet - Packet Containing the data to be transmitted 13 USHORT usVcid - VCID on which data packet is to be sent 14 15 16Return: BCM_STATUS_SUCCESS - If Tx was successful. 17 Other - If an error occured. 18*/ 19 20ULONG InterfaceTxDataPacket(PMINI_ADAPTER Adapter,PVOID Packet,USHORT usVcid) 21{ 22 ULONG Status = 0; 23 return Status; 24} 25 26/* 27Function: InterfaceTxControlPacket 28 29Description: This is the hardware specific Function for Transmitting 30 control packet to the device. 31 32Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context 33 PVOID pvBuffer - Buffer containg control packet 34 UINT uiBufferLength - Buffer Length 35 36Return: BCM_STATUS_SUCCESS - If control packet transmit was successful. 37 Other - If an error occured. 38*/ 39 40ULONG InterfaceTxControlPacket(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT uiBufferLength) 41{ 42 ULONG Status = 0; 43 44 45 46 return Status; 47} 48/*this is transmit call-back(BULK OUT)*/ 49static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) 50{ 51 PUSB_TCB pTcb= (PUSB_TCB)urb->context; 52 PS_INTERFACE_ADAPTER psIntfAdapter = pTcb->psIntfAdapter; 53 CONTROL_MESSAGE *pControlMsg = (CONTROL_MESSAGE *)urb->transfer_buffer; 54 PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ; 55 BOOLEAN bpowerDownMsg = FALSE ; 56 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 57#if 0 58 struct timeval tv; 59 UINT time_ms = 0; 60#endif 61 if(urb->status != STATUS_SUCCESS) 62 { 63 if(urb->status == -EPIPE) 64 { 65 psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; 66 wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); 67 } 68 else 69 { 70 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Tx URB has got cancelled. status :%d", urb->status); 71 } 72 } 73 74 pTcb->bUsed = FALSE; 75 atomic_dec(&psIntfAdapter->uNumTcbUsed); 76 77 78 79 if(TRUE == psAdapter->bPreparingForLowPowerMode) 80 { 81 #if 0 82 do_gettimeofday(&tv); 83 time_ms = tv.tv_sec *1000 + tv.tv_usec/1000; 84 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " %s Idle Mode ACK_Sent got from device at time :0x%x", __FUNCTION__, time_ms); 85 #endif 86 87 if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && 88 (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) 89 90 { 91 bpowerDownMsg = TRUE ; 92 //This covers the bus err while Idle Request msg sent down. 93 if(urb->status != STATUS_SUCCESS) 94 { 95 psAdapter->bPreparingForLowPowerMode = FALSE ; 96 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Idle Mode Request msg failed to reach to Modem"); 97 //Signalling the cntrl pkt path in Ioctl 98 wake_up(&psAdapter->lowpower_mode_wait_queue); 99 StartInterruptUrb(psIntfAdapter); 100 goto err_exit; 101 } 102 103 if(psAdapter->bDoSuspend == FALSE) 104 { 105 psAdapter->IdleMode = TRUE; 106 //since going in Idle mode completed hence making this var false; 107 psAdapter->bPreparingForLowPowerMode = FALSE ; 108 109 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State..."); 110 //Signalling the cntrl pkt path in Ioctl 111 wake_up(&psAdapter->lowpower_mode_wait_queue); 112 } 113 114 } 115 else if((pControlMsg->Leader.Status == LINK_UP_CONTROL_REQ) && 116 (pControlMsg->szData[0] == LINK_UP_ACK) && 117 (pControlMsg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) && 118 (pControlMsg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) 119 { 120 //This covers the bus err while shutdown Request msg sent down. 121 if(urb->status != STATUS_SUCCESS) 122 { 123 psAdapter->bPreparingForLowPowerMode = FALSE ; 124 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Shutdown Request Msg failed to reach to Modem"); 125 //Signalling the cntrl pkt path in Ioctl 126 wake_up(&psAdapter->lowpower_mode_wait_queue); 127 StartInterruptUrb(psIntfAdapter); 128 goto err_exit; 129 } 130 131 bpowerDownMsg = TRUE ; 132 if(psAdapter->bDoSuspend == FALSE) 133 { 134 psAdapter->bShutStatus = TRUE; 135 //since going in shutdown mode completed hence making this var false; 136 psAdapter->bPreparingForLowPowerMode = FALSE ; 137 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Host Entered in shutdown Mode State..."); 138 //Signalling the cntrl pkt path in Ioctl 139 wake_up(&psAdapter->lowpower_mode_wait_queue); 140 } 141 } 142 143 if(psAdapter->bDoSuspend && bpowerDownMsg) 144 { 145 //issuing bus suspend request 146 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Issuing the Bus suspend request to USB stack"); 147 psIntfAdapter->bPreparingForBusSuspend = TRUE; 148 schedule_work(&psIntfAdapter->usbSuspendWork); 149 150 } 151 152 } 153 154err_exit : 155#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) 156 usb_buffer_free(urb->dev, urb->transfer_buffer_length, 157 urb->transfer_buffer, urb->transfer_dma); 158#else 159 usb_free_coherent(urb->dev, urb->transfer_buffer_length, 160 urb->transfer_buffer, urb->transfer_dma); 161#endif 162} 163 164 165static __inline PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter) 166{ 167 PUSB_TCB pTcb = NULL; 168 UINT index = 0; 169 170 if((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) && 171 (psIntfAdapter->psAdapter->StopAllXaction ==FALSE)) 172 { 173 index = atomic_read(&psIntfAdapter->uCurrTcb); 174 pTcb = &psIntfAdapter->asUsbTcb[index]; 175 pTcb->bUsed = TRUE; 176 pTcb->psIntfAdapter= psIntfAdapter; 177 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got Tx desc %d used %d", 178 index, atomic_read(&psIntfAdapter->uNumTcbUsed)); 179 index = (index + 1) % MAXIMUM_USB_TCB; 180 atomic_set(&psIntfAdapter->uCurrTcb, index); 181 atomic_inc(&psIntfAdapter->uNumTcbUsed); 182 } 183 return pTcb; 184} 185 186static __inline int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len) 187{ 188 189 struct urb *urb = pTcb->urb; 190 int retval = 0; 191 192#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) 193 urb->transfer_buffer = usb_buffer_alloc(psIntfAdapter->udev, len, 194 GFP_ATOMIC, &urb->transfer_dma); 195#else 196 urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len, 197 GFP_ATOMIC, &urb->transfer_dma); 198#endif 199 200 if (!urb->transfer_buffer) 201 { 202 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n"); 203 return -ENOMEM; 204 } 205 memcpy(urb->transfer_buffer, data, len); 206 urb->transfer_buffer_length = len; 207 208 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending Bulk out packet\n"); 209 //For T3B,INT OUT end point will be used as bulk out end point 210 if((psIntfAdapter->psAdapter->chip_id == T3B) && (psIntfAdapter->bHighSpeedDevice == TRUE)) 211 { 212 usb_fill_int_urb(urb, psIntfAdapter->udev, 213 psIntfAdapter->sBulkOut.bulk_out_pipe, 214 urb->transfer_buffer, len, write_bulk_callback, pTcb, 215 psIntfAdapter->sBulkOut.int_out_interval); 216 } 217 else 218 { 219 usb_fill_bulk_urb(urb, psIntfAdapter->udev, 220 psIntfAdapter->sBulkOut.bulk_out_pipe, 221 urb->transfer_buffer, len, write_bulk_callback, pTcb); 222 } 223 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* For DMA transfer */ 224 225 if(FALSE == psIntfAdapter->psAdapter->device_removed && 226 FALSE == psIntfAdapter->psAdapter->bEndPointHalted && 227 FALSE == psIntfAdapter->bSuspended && 228 FALSE == psIntfAdapter->bPreparingForBusSuspend) 229 { 230 retval = usb_submit_urb(urb, GFP_ATOMIC); 231 if (retval) 232 { 233 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "failed submitting write urb, error %d", retval); 234 if(retval == -EPIPE) 235 { 236 psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; 237 wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); 238 } 239 } 240 } 241 return retval; 242} 243 244int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len) 245{ 246 PUSB_TCB pTcb= NULL; 247 248 PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; 249 pTcb= GetBulkOutTcb(psIntfAdapter); 250 if(pTcb == NULL) 251 { 252 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "No URB to transmit packet, dropping packet"); 253 return -EFAULT; 254 } 255 return TransmitTcb(psIntfAdapter, pTcb, data, len); 256} 257 258#endif 259