4 *Copyright (C) 2010 Beceem Communications, Inc.
6 *This program is free software: you can redistribute it and/or modify
7 *it under the terms of the GNU General Public License version 2 as
8 *published by the Free Software Foundation.
10 *This program is distributed in the hope that it will be useful,but
11 *WITHOUT ANY WARRANTY; without even the implied warranty of
12 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 *See the GNU General Public License for more details.
15 *You should have received a copy of the GNU General Public License
16 *along with this program. If not, write to the Free Software Foundation, Inc.,
17 *51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #ifndef BCM_SHM_INTERFACE
27 Function: InterfaceTxDataPacket
29 Description: This is the hardware specific Function for Transmitting
30 data packet to the device.
32 Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
33 PVOID Packet - Packet Containing the data to be transmitted
34 USHORT usVcid - VCID on which data packet is to be sent
37 Return: BCM_STATUS_SUCCESS - If Tx was successful.
38 Other - If an error occured.
41 ULONG
InterfaceTxDataPacket(PMINI_ADAPTER Adapter
,PVOID Packet
,USHORT usVcid
)
48 Function: InterfaceTxControlPacket
50 Description: This is the hardware specific Function for Transmitting
51 control packet to the device.
53 Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
54 PVOID pvBuffer - Buffer containg control packet
55 UINT uiBufferLength - Buffer Length
57 Return: BCM_STATUS_SUCCESS - If control packet transmit was successful.
58 Other - If an error occured.
61 ULONG
InterfaceTxControlPacket(PMINI_ADAPTER Adapter
,PVOID pvBuffer
,UINT uiBufferLength
)
69 /*this is transmit call-back(BULK OUT)*/
70 static void write_bulk_callback(struct urb
*urb
/*, struct pt_regs *regs*/)
72 PUSB_TCB pTcb
= (PUSB_TCB
)urb
->context
;
73 PS_INTERFACE_ADAPTER psIntfAdapter
= pTcb
->psIntfAdapter
;
74 CONTROL_MESSAGE
*pControlMsg
= (CONTROL_MESSAGE
*)urb
->transfer_buffer
;
75 PMINI_ADAPTER psAdapter
= psIntfAdapter
->psAdapter
;
76 BOOLEAN bpowerDownMsg
= FALSE
;
77 PMINI_ADAPTER Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
82 if(urb
->status
!= STATUS_SUCCESS
)
84 if(urb
->status
== -EPIPE
)
86 psIntfAdapter
->psAdapter
->bEndPointHalted
= TRUE
;
87 wake_up(&psIntfAdapter
->psAdapter
->tx_packet_wait_queue
);
91 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
,"Tx URB has got cancelled. status :%d", urb
->status
);
96 atomic_dec(&psIntfAdapter
->uNumTcbUsed
);
100 if(TRUE
== psAdapter
->bPreparingForLowPowerMode
)
103 do_gettimeofday(&tv
);
104 time_ms
= tv
.tv_sec
*1000 + tv
.tv_usec
/1000;
105 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_PRINTK
, 0, 0, " %s Idle Mode ACK_Sent got from device at time :0x%x", __FUNCTION__
, time_ms
);
108 if(((pControlMsg
->szData
[0] == GO_TO_IDLE_MODE_PAYLOAD
) &&
109 (pControlMsg
->szData
[1] == TARGET_CAN_GO_TO_IDLE_MODE
)))
112 bpowerDownMsg
= TRUE
;
113 //This covers the bus err while Idle Request msg sent down.
114 if(urb
->status
!= STATUS_SUCCESS
)
116 psAdapter
->bPreparingForLowPowerMode
= FALSE
;
117 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
,"Idle Mode Request msg failed to reach to Modem");
118 //Signalling the cntrl pkt path in Ioctl
119 wake_up(&psAdapter
->lowpower_mode_wait_queue
);
120 StartInterruptUrb(psIntfAdapter
);
124 if(psAdapter
->bDoSuspend
== FALSE
)
126 psAdapter
->IdleMode
= TRUE
;
127 //since going in Idle mode completed hence making this var false;
128 psAdapter
->bPreparingForLowPowerMode
= FALSE
;
130 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "Host Entered in Idle Mode State...");
131 //Signalling the cntrl pkt path in Ioctl
132 wake_up(&psAdapter
->lowpower_mode_wait_queue
);
136 else if((pControlMsg
->Leader
.Status
== LINK_UP_CONTROL_REQ
) &&
137 (pControlMsg
->szData
[0] == LINK_UP_ACK
) &&
138 (pControlMsg
->szData
[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE
) &&
139 (pControlMsg
->szData
[2] == SHUTDOWN_ACK_FROM_DRIVER
))
141 //This covers the bus err while shutdown Request msg sent down.
142 if(urb
->status
!= STATUS_SUCCESS
)
144 psAdapter
->bPreparingForLowPowerMode
= FALSE
;
145 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
,"Shutdown Request Msg failed to reach to Modem");
146 //Signalling the cntrl pkt path in Ioctl
147 wake_up(&psAdapter
->lowpower_mode_wait_queue
);
148 StartInterruptUrb(psIntfAdapter
);
152 bpowerDownMsg
= TRUE
;
153 if(psAdapter
->bDoSuspend
== FALSE
)
155 psAdapter
->bShutStatus
= TRUE
;
156 //since going in shutdown mode completed hence making this var false;
157 psAdapter
->bPreparingForLowPowerMode
= FALSE
;
158 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
,"Host Entered in shutdown Mode State...");
159 //Signalling the cntrl pkt path in Ioctl
160 wake_up(&psAdapter
->lowpower_mode_wait_queue
);
164 if(psAdapter
->bDoSuspend
&& bpowerDownMsg
)
166 //issuing bus suspend request
167 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
,"Issuing the Bus suspend request to USB stack");
168 psIntfAdapter
->bPreparingForBusSuspend
= TRUE
;
169 schedule_work(&psIntfAdapter
->usbSuspendWork
);
176 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
177 usb_free_coherent(urb
->dev
, urb
->transfer_buffer_length
, urb
->transfer_buffer
, urb
->transfer_dma
);
179 usb_buffer_free(urb
->dev
, urb
->transfer_buffer_length
, urb
->transfer_buffer
, urb
->transfer_dma
);
184 static __inline PUSB_TCB
GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter
)
186 PUSB_TCB pTcb
= NULL
;
189 if((atomic_read(&psIntfAdapter
->uNumTcbUsed
) < MAXIMUM_USB_TCB
) &&
190 (psIntfAdapter
->psAdapter
->StopAllXaction
==FALSE
))
192 index
= atomic_read(&psIntfAdapter
->uCurrTcb
);
193 pTcb
= &psIntfAdapter
->asUsbTcb
[index
];
195 pTcb
->psIntfAdapter
= psIntfAdapter
;
196 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "Got Tx desc %d used %d",
197 index
, atomic_read(&psIntfAdapter
->uNumTcbUsed
));
198 index
= (index
+ 1) % MAXIMUM_USB_TCB
;
199 atomic_set(&psIntfAdapter
->uCurrTcb
, index
);
200 atomic_inc(&psIntfAdapter
->uNumTcbUsed
);
205 static __inline
int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter
, PUSB_TCB pTcb
, PVOID data
, int len
)
208 struct urb
*urb
= pTcb
->urb
;
211 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
212 urb
->transfer_buffer
= usb_alloc_coherent(psIntfAdapter
->udev
, len
, GFP_ATOMIC
, &urb
->transfer_dma
);
214 urb
->transfer_buffer
= usb_buffer_alloc(psIntfAdapter
->udev
, len
, GFP_ATOMIC
, &urb
->transfer_dma
);
216 if (!urb
->transfer_buffer
)
218 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Error allocating memory\n");
221 memcpy(urb
->transfer_buffer
, data
, len
);
222 urb
->transfer_buffer_length
= len
;
224 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "Sending Bulk out packet\n");
225 //For T3B,INT OUT end point will be used as bulk out end point
226 if((psIntfAdapter
->psAdapter
->chip_id
== T3B
) && (psIntfAdapter
->bHighSpeedDevice
== TRUE
))
228 usb_fill_int_urb(urb
, psIntfAdapter
->udev
,
229 psIntfAdapter
->sBulkOut
.bulk_out_pipe
,
230 urb
->transfer_buffer
, len
, write_bulk_callback
, pTcb
,
231 psIntfAdapter
->sBulkOut
.int_out_interval
);
235 usb_fill_bulk_urb(urb
, psIntfAdapter
->udev
,
236 psIntfAdapter
->sBulkOut
.bulk_out_pipe
,
237 urb
->transfer_buffer
, len
, write_bulk_callback
, pTcb
);
239 urb
->transfer_flags
|= URB_NO_TRANSFER_DMA_MAP
; /* For DMA transfer */
241 if(FALSE
== psIntfAdapter
->psAdapter
->device_removed
&&
242 FALSE
== psIntfAdapter
->psAdapter
->bEndPointHalted
&&
243 FALSE
== psIntfAdapter
->bSuspended
&&
244 FALSE
== psIntfAdapter
->bPreparingForBusSuspend
)
246 retval
= usb_submit_urb(urb
, GFP_ATOMIC
);
249 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "failed submitting write urb, error %d", retval
);
252 psIntfAdapter
->psAdapter
->bEndPointHalted
= TRUE
;
253 wake_up(&psIntfAdapter
->psAdapter
->tx_packet_wait_queue
);
260 int InterfaceTransmitPacket(PVOID arg
, PVOID data
, UINT len
)
264 PS_INTERFACE_ADAPTER psIntfAdapter
= (PS_INTERFACE_ADAPTER
)arg
;
265 pTcb
= GetBulkOutTcb(psIntfAdapter
);
268 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "No URB to transmit packet, dropping packet");
271 return TransmitTcb(psIntfAdapter
, pTcb
, data
, len
);