aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/bcm/InterfaceTx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/bcm/InterfaceTx.c')
-rw-r--r--drivers/staging/bcm/InterfaceTx.c259
1 files changed, 259 insertions, 0 deletions
diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c
new file mode 100644
index 00000000000..771f7b34d2e
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceTx.c
@@ -0,0 +1,259 @@
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