Commit | Line | Data |
---|---|---|
f8942e07 SH |
1 | #include "headers.h" |
2 | ||
f8942e07 SH |
3 | /*this is transmit call-back(BULK OUT)*/ |
4 | static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) | |
5 | { | |
e8355aa3 | 6 | struct bcm_usb_tcb *pTcb= (struct bcm_usb_tcb *)urb->context; |
d6861cfe | 7 | struct bcm_interface_adapter *psIntfAdapter = pTcb->psIntfAdapter; |
2610c7a8 | 8 | struct bcm_link_request *pControlMsg = (struct bcm_link_request *)urb->transfer_buffer; |
2979460d | 9 | struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter ; |
f8942e07 | 10 | BOOLEAN bpowerDownMsg = FALSE ; |
2979460d | 11 | struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); |
9ec4475b SH |
12 | |
13 | if (unlikely(netif_msg_tx_done(Adapter))) | |
14 | pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, urb->status); | |
15 | ||
f8942e07 SH |
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 | { | |
f8942e07 SH |
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 : | |
f8942e07 SH |
105 | usb_free_coherent(urb->dev, urb->transfer_buffer_length, |
106 | urb->transfer_buffer, urb->transfer_dma); | |
f8942e07 SH |
107 | } |
108 | ||
109 | ||
e8355aa3 | 110 | static struct bcm_usb_tcb *GetBulkOutTcb(struct bcm_interface_adapter *psIntfAdapter) |
f8942e07 | 111 | { |
e8355aa3 | 112 | struct bcm_usb_tcb *pTcb = NULL; |
f8942e07 SH |
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 | ||
e8355aa3 | 131 | static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_usb_tcb *pTcb, PVOID data, int len) |
f8942e07 SH |
132 | { |
133 | ||
134 | struct urb *urb = pTcb->urb; | |
135 | int retval = 0; | |
136 | ||
f8942e07 SH |
137 | urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len, |
138 | GFP_ATOMIC, &urb->transfer_dma); | |
f8942e07 SH |
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 | { | |
e8355aa3 | 185 | struct bcm_usb_tcb *pTcb= NULL; |
f8942e07 | 186 | |
d6861cfe | 187 | struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg; |
f8942e07 SH |
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 | ||
f8942e07 | 197 |