beceem: remove ifdef's
[pandora-kernel.git] / drivers / staging / bcm / InterfaceTx.c
1 #include "headers.h"
2
3
4 /*
5 Function:                               InterfaceTxDataPacket
6
7 Description:                    This is the hardware specific Function for Transmitting
8                                                 data packet to the device.
9
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
13
14
15 Return:                         BCM_STATUS_SUCCESS - If Tx was successful.
16                                                 Other           - If an error occured.
17 */
18
19 ULONG InterfaceTxDataPacket(PMINI_ADAPTER Adapter,PVOID Packet,USHORT usVcid)
20 {
21         ULONG   Status = 0;
22         return Status;
23 }
24
25 /*
26 Function:                               InterfaceTxControlPacket
27
28 Description:                    This is the hardware specific Function for Transmitting
29                                                 control packet to the device.
30
31 Input parameters:               IN PMINI_ADAPTER Adapter   - Miniport Adapter Context
32                                                 PVOID pvBuffer                     - Buffer containg control packet
33                                                 UINT uiBufferLength                - Buffer Length
34
35 Return:                         BCM_STATUS_SUCCESS - If control packet transmit was successful.
36                                                 Other           - If an error occured.
37 */
38
39 ULONG InterfaceTxControlPacket(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT uiBufferLength)
40 {
41         ULONG   Status = 0;
42
43
44
45         return Status;
46 }
47 /*this is transmit call-back(BULK OUT)*/
48 static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
49 {
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);
56 #if 0
57         struct timeval tv;
58         UINT time_ms = 0;
59 #endif
60         if(urb->status != STATUS_SUCCESS)
61         {
62                 if(urb->status == -EPIPE)
63                 {
64                         psIntfAdapter->psAdapter->bEndPointHalted = TRUE ;
65                         wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
66                 }
67                 else
68                 {
69                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Tx URB has got cancelled. status :%d", urb->status);
70                 }
71         }
72
73         pTcb->bUsed = FALSE;
74         atomic_dec(&psIntfAdapter->uNumTcbUsed);
75
76
77
78         if(TRUE == psAdapter->bPreparingForLowPowerMode)
79         {
80                 #if 0
81                 do_gettimeofday(&tv);
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);
84                 #endif
85
86                 if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) &&
87                         (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE)))
88
89                 {
90                         bpowerDownMsg = TRUE ;
91                         //This covers the bus err while Idle Request msg sent down.
92                         if(urb->status != STATUS_SUCCESS)
93                         {
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);
99                                 goto err_exit;
100                         }
101
102                         if(psAdapter->bDoSuspend == FALSE)
103                         {
104                                 psAdapter->IdleMode = TRUE;
105                                 //since going in Idle mode completed hence making this var false;
106                                 psAdapter->bPreparingForLowPowerMode = FALSE ;
107
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);
111                         }
112
113                 }
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))
118                 {
119                         //This covers the bus err while shutdown Request msg sent down.
120                         if(urb->status != STATUS_SUCCESS)
121                         {
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);
127                                 goto err_exit;
128                         }
129
130                         bpowerDownMsg = TRUE ;
131                         if(psAdapter->bDoSuspend == FALSE)
132                         {
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);
139                         }
140                 }
141
142                 if(psAdapter->bDoSuspend && bpowerDownMsg)
143                 {
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);
148
149                 }
150
151         }
152
153 err_exit :
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);
157 #else
158         usb_free_coherent(urb->dev, urb->transfer_buffer_length,
159                         urb->transfer_buffer, urb->transfer_dma);
160 #endif
161 }
162
163
164 static __inline PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)
165 {
166         PUSB_TCB pTcb = NULL;
167         UINT index = 0;
168
169         if((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) &&
170                 (psIntfAdapter->psAdapter->StopAllXaction ==FALSE))
171         {
172                 index = atomic_read(&psIntfAdapter->uCurrTcb);
173                 pTcb = &psIntfAdapter->asUsbTcb[index];
174                 pTcb->bUsed = TRUE;
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);
181         }
182         return pTcb;
183 }
184
185 static __inline int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len)
186 {
187
188         struct urb *urb = pTcb->urb;
189         int retval = 0;
190
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);
194 #else
195         urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len,
196                                                 GFP_ATOMIC, &urb->transfer_dma);
197 #endif
198
199         if (!urb->transfer_buffer)
200         {
201                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n");
202                 return  -ENOMEM;
203         }
204         memcpy(urb->transfer_buffer, data, len);
205         urb->transfer_buffer_length = len;
206
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))
210         {
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);
215         }
216         else
217         {
218         usb_fill_bulk_urb(urb, psIntfAdapter->udev,
219                   psIntfAdapter->sBulkOut.bulk_out_pipe,
220                   urb->transfer_buffer, len, write_bulk_callback, pTcb);
221         }
222         urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* For DMA transfer */
223
224         if(FALSE == psIntfAdapter->psAdapter->device_removed &&
225            FALSE == psIntfAdapter->psAdapter->bEndPointHalted &&
226            FALSE == psIntfAdapter->bSuspended &&
227            FALSE == psIntfAdapter->bPreparingForBusSuspend)
228         {
229                 retval = usb_submit_urb(urb, GFP_ATOMIC);
230                 if (retval)
231                 {
232                         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "failed submitting write urb, error %d", retval);
233                         if(retval == -EPIPE)
234                         {
235                                 psIntfAdapter->psAdapter->bEndPointHalted = TRUE ;
236                                 wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
237                         }
238                 }
239         }
240         return retval;
241 }
242
243 int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len)
244 {
245         PUSB_TCB pTcb= NULL;
246
247         PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
248         pTcb= GetBulkOutTcb(psIntfAdapter);
249         if(pTcb == NULL)
250         {
251                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "No URB to transmit packet, dropping packet");
252                 return -EFAULT;
253         }
254         return TransmitTcb(psIntfAdapter, pTcb, data, len);
255 }
256
257