5 Function: InterfaceTxDataPacket
7 Description: This is the hardware specific Function for Transmitting
8 data packet to the device.
10 Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
11 PVOID Packet - Packet Containing the data to be transmitted
12 USHORT usVcid - VCID on which data packet is to be sent
15 Return: BCM_STATUS_SUCCESS - If Tx was successful.
16 Other - If an error occured.
19 ULONG InterfaceTxDataPacket(PMINI_ADAPTER Adapter,PVOID Packet,USHORT usVcid)
26 Function: InterfaceTxControlPacket
28 Description: This is the hardware specific Function for Transmitting
29 control packet to the device.
31 Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
32 PVOID pvBuffer - Buffer containg control packet
33 UINT uiBufferLength - Buffer Length
35 Return: BCM_STATUS_SUCCESS - If control packet transmit was successful.
36 Other - If an error occured.
39 ULONG InterfaceTxControlPacket(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT uiBufferLength)
47 /*this is transmit call-back(BULK OUT)*/
48 static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
50 PUSB_TCB pTcb= (PUSB_TCB)urb->context;
51 PS_INTERFACE_ADAPTER psIntfAdapter = pTcb->psIntfAdapter;
52 CONTROL_MESSAGE *pControlMsg = (CONTROL_MESSAGE *)urb->transfer_buffer;
53 PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ;
54 BOOLEAN bpowerDownMsg = FALSE ;
55 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
60 if(urb->status != STATUS_SUCCESS)
62 if(urb->status == -EPIPE)
64 psIntfAdapter->psAdapter->bEndPointHalted = TRUE ;
65 wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
69 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Tx URB has got cancelled. status :%d", urb->status);
74 atomic_dec(&psIntfAdapter->uNumTcbUsed);
78 if(TRUE == psAdapter->bPreparingForLowPowerMode)
82 time_ms = tv.tv_sec *1000 + tv.tv_usec/1000;
83 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " %s Idle Mode ACK_Sent got from device at time :0x%x", __FUNCTION__, time_ms);
86 if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) &&
87 (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE)))
90 bpowerDownMsg = TRUE ;
91 //This covers the bus err while Idle Request msg sent down.
92 if(urb->status != STATUS_SUCCESS)
94 psAdapter->bPreparingForLowPowerMode = FALSE ;
95 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Idle Mode Request msg failed to reach to Modem");
96 //Signalling the cntrl pkt path in Ioctl
97 wake_up(&psAdapter->lowpower_mode_wait_queue);
98 StartInterruptUrb(psIntfAdapter);
102 if(psAdapter->bDoSuspend == FALSE)
104 psAdapter->IdleMode = TRUE;
105 //since going in Idle mode completed hence making this var false;
106 psAdapter->bPreparingForLowPowerMode = FALSE ;
108 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State...");
109 //Signalling the cntrl pkt path in Ioctl
110 wake_up(&psAdapter->lowpower_mode_wait_queue);
114 else if((pControlMsg->Leader.Status == LINK_UP_CONTROL_REQ) &&
115 (pControlMsg->szData[0] == LINK_UP_ACK) &&
116 (pControlMsg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) &&
117 (pControlMsg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER))
119 //This covers the bus err while shutdown Request msg sent down.
120 if(urb->status != STATUS_SUCCESS)
122 psAdapter->bPreparingForLowPowerMode = FALSE ;
123 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Shutdown Request Msg failed to reach to Modem");
124 //Signalling the cntrl pkt path in Ioctl
125 wake_up(&psAdapter->lowpower_mode_wait_queue);
126 StartInterruptUrb(psIntfAdapter);
130 bpowerDownMsg = TRUE ;
131 if(psAdapter->bDoSuspend == FALSE)
133 psAdapter->bShutStatus = TRUE;
134 //since going in shutdown mode completed hence making this var false;
135 psAdapter->bPreparingForLowPowerMode = FALSE ;
136 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Host Entered in shutdown Mode State...");
137 //Signalling the cntrl pkt path in Ioctl
138 wake_up(&psAdapter->lowpower_mode_wait_queue);
142 if(psAdapter->bDoSuspend && bpowerDownMsg)
144 //issuing bus suspend request
145 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Issuing the Bus suspend request to USB stack");
146 psIntfAdapter->bPreparingForBusSuspend = TRUE;
147 schedule_work(&psIntfAdapter->usbSuspendWork);
154 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
155 usb_buffer_free(urb->dev, urb->transfer_buffer_length,
156 urb->transfer_buffer, urb->transfer_dma);
158 usb_free_coherent(urb->dev, urb->transfer_buffer_length,
159 urb->transfer_buffer, urb->transfer_dma);
164 static __inline PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)
166 PUSB_TCB pTcb = NULL;
169 if((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) &&
170 (psIntfAdapter->psAdapter->StopAllXaction ==FALSE))
172 index = atomic_read(&psIntfAdapter->uCurrTcb);
173 pTcb = &psIntfAdapter->asUsbTcb[index];
175 pTcb->psIntfAdapter= psIntfAdapter;
176 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got Tx desc %d used %d",
177 index, atomic_read(&psIntfAdapter->uNumTcbUsed));
178 index = (index + 1) % MAXIMUM_USB_TCB;
179 atomic_set(&psIntfAdapter->uCurrTcb, index);
180 atomic_inc(&psIntfAdapter->uNumTcbUsed);
185 static __inline int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len)
188 struct urb *urb = pTcb->urb;
191 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
192 urb->transfer_buffer = usb_buffer_alloc(psIntfAdapter->udev, len,
193 GFP_ATOMIC, &urb->transfer_dma);
195 urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len,
196 GFP_ATOMIC, &urb->transfer_dma);
199 if (!urb->transfer_buffer)
201 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n");
204 memcpy(urb->transfer_buffer, data, len);
205 urb->transfer_buffer_length = len;
207 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending Bulk out packet\n");
208 //For T3B,INT OUT end point will be used as bulk out end point
209 if((psIntfAdapter->psAdapter->chip_id == T3B) && (psIntfAdapter->bHighSpeedDevice == TRUE))
211 usb_fill_int_urb(urb, psIntfAdapter->udev,
212 psIntfAdapter->sBulkOut.bulk_out_pipe,
213 urb->transfer_buffer, len, write_bulk_callback, pTcb,
214 psIntfAdapter->sBulkOut.int_out_interval);
218 usb_fill_bulk_urb(urb, psIntfAdapter->udev,
219 psIntfAdapter->sBulkOut.bulk_out_pipe,
220 urb->transfer_buffer, len, write_bulk_callback, pTcb);
222 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* For DMA transfer */
224 if(FALSE == psIntfAdapter->psAdapter->device_removed &&
225 FALSE == psIntfAdapter->psAdapter->bEndPointHalted &&
226 FALSE == psIntfAdapter->bSuspended &&
227 FALSE == psIntfAdapter->bPreparingForBusSuspend)
229 retval = usb_submit_urb(urb, GFP_ATOMIC);
232 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "failed submitting write urb, error %d", retval);
235 psIntfAdapter->psAdapter->bEndPointHalted = TRUE ;
236 wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
243 int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len)
247 PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
248 pTcb= GetBulkOutTcb(psIntfAdapter);
251 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "No URB to transmit packet, dropping packet");
254 return TransmitTcb(psIntfAdapter, pTcb, data, len);