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