3 /*this is transmit call-back(BULK OUT)*/
4 static void write_bulk_callback(struct urb
*urb
/*, struct pt_regs *regs*/)
6 struct bcm_usb_tcb
*pTcb
= (struct bcm_usb_tcb
*)urb
->context
;
7 struct bcm_interface_adapter
*psIntfAdapter
= pTcb
->psIntfAdapter
;
8 struct bcm_link_request
*pControlMsg
= (struct bcm_link_request
*)urb
->transfer_buffer
;
9 struct bcm_mini_adapter
*psAdapter
= psIntfAdapter
->psAdapter
;
10 bool bpowerDownMsg
= false;
11 struct bcm_mini_adapter
*Adapter
= GET_BCM_ADAPTER(gblpnetdev
);
13 if (unlikely(netif_msg_tx_done(Adapter
)))
14 pr_info(PFX
"%s: transmit status %d\n", Adapter
->dev
->name
, urb
->status
);
16 if (urb
->status
!= STATUS_SUCCESS
) {
17 if (urb
->status
== -EPIPE
) {
18 psIntfAdapter
->psAdapter
->bEndPointHalted
= TRUE
;
19 wake_up(&psIntfAdapter
->psAdapter
->tx_packet_wait_queue
);
21 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "Tx URB has got cancelled. status :%d", urb
->status
);
26 atomic_dec(&psIntfAdapter
->uNumTcbUsed
);
30 if (TRUE
== psAdapter
->bPreparingForLowPowerMode
) {
32 if (((pControlMsg
->szData
[0] == GO_TO_IDLE_MODE_PAYLOAD
) &&
33 (pControlMsg
->szData
[1] == TARGET_CAN_GO_TO_IDLE_MODE
))) {
35 /* This covers the bus err while Idle Request msg sent down. */
36 if (urb
->status
!= STATUS_SUCCESS
) {
37 psAdapter
->bPreparingForLowPowerMode
= false;
38 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "Idle Mode Request msg failed to reach to Modem");
39 /* Signalling the cntrl pkt path in Ioctl */
40 wake_up(&psAdapter
->lowpower_mode_wait_queue
);
41 StartInterruptUrb(psIntfAdapter
);
45 if (psAdapter
->bDoSuspend
== false) {
46 psAdapter
->IdleMode
= TRUE
;
47 /* since going in Idle mode completed hence making this var false */
48 psAdapter
->bPreparingForLowPowerMode
= false;
50 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "Host Entered in Idle Mode State...");
51 /* Signalling the cntrl pkt path in Ioctl*/
52 wake_up(&psAdapter
->lowpower_mode_wait_queue
);
55 } else if ((pControlMsg
->Leader
.Status
== LINK_UP_CONTROL_REQ
) &&
56 (pControlMsg
->szData
[0] == LINK_UP_ACK
) &&
57 (pControlMsg
->szData
[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE
) &&
58 (pControlMsg
->szData
[2] == SHUTDOWN_ACK_FROM_DRIVER
)) {
59 /* This covers the bus err while shutdown Request msg sent down. */
60 if (urb
->status
!= STATUS_SUCCESS
) {
61 psAdapter
->bPreparingForLowPowerMode
= false;
62 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "Shutdown Request Msg failed to reach to Modem");
63 /* Signalling the cntrl pkt path in Ioctl */
64 wake_up(&psAdapter
->lowpower_mode_wait_queue
);
65 StartInterruptUrb(psIntfAdapter
);
70 if (psAdapter
->bDoSuspend
== false) {
71 psAdapter
->bShutStatus
= TRUE
;
72 /* since going in shutdown mode completed hence making this var false */
73 psAdapter
->bPreparingForLowPowerMode
= false;
74 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "Host Entered in shutdown Mode State...");
75 /* Signalling the cntrl pkt path in Ioctl */
76 wake_up(&psAdapter
->lowpower_mode_wait_queue
);
80 if (psAdapter
->bDoSuspend
&& bpowerDownMsg
) {
81 /* issuing bus suspend request */
82 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "Issuing the Bus suspend request to USB stack");
83 psIntfAdapter
->bPreparingForBusSuspend
= TRUE
;
84 schedule_work(&psIntfAdapter
->usbSuspendWork
);
91 usb_free_coherent(urb
->dev
, urb
->transfer_buffer_length
,
92 urb
->transfer_buffer
, urb
->transfer_dma
);
96 static struct bcm_usb_tcb
*GetBulkOutTcb(struct bcm_interface_adapter
*psIntfAdapter
)
98 struct bcm_usb_tcb
*pTcb
= NULL
;
101 if ((atomic_read(&psIntfAdapter
->uNumTcbUsed
) < MAXIMUM_USB_TCB
) &&
102 (psIntfAdapter
->psAdapter
->StopAllXaction
== false)) {
103 index
= atomic_read(&psIntfAdapter
->uCurrTcb
);
104 pTcb
= &psIntfAdapter
->asUsbTcb
[index
];
106 pTcb
->psIntfAdapter
= psIntfAdapter
;
107 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
, DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "Got Tx desc %d used %d",
108 index
, atomic_read(&psIntfAdapter
->uNumTcbUsed
));
109 index
= (index
+ 1) % MAXIMUM_USB_TCB
;
110 atomic_set(&psIntfAdapter
->uCurrTcb
, index
);
111 atomic_inc(&psIntfAdapter
->uNumTcbUsed
);
116 static int TransmitTcb(struct bcm_interface_adapter
*psIntfAdapter
, struct bcm_usb_tcb
*pTcb
, PVOID data
, int len
)
119 struct urb
*urb
= pTcb
->urb
;
122 urb
->transfer_buffer
= usb_alloc_coherent(psIntfAdapter
->udev
, len
,
123 GFP_ATOMIC
, &urb
->transfer_dma
);
124 if (!urb
->transfer_buffer
) {
125 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
, DBG_TYPE_PRINTK
, 0, 0, "Error allocating memory\n");
128 memcpy(urb
->transfer_buffer
, data
, len
);
129 urb
->transfer_buffer_length
= len
;
131 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
, DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "Sending Bulk out packet\n");
132 /* For T3B,INT OUT end point will be used as bulk out end point */
133 if ((psIntfAdapter
->psAdapter
->chip_id
== T3B
) && (psIntfAdapter
->bHighSpeedDevice
== TRUE
)) {
134 usb_fill_int_urb(urb
, psIntfAdapter
->udev
,
135 psIntfAdapter
->sBulkOut
.bulk_out_pipe
,
136 urb
->transfer_buffer
, len
, write_bulk_callback
, pTcb
,
137 psIntfAdapter
->sBulkOut
.int_out_interval
);
139 usb_fill_bulk_urb(urb
, psIntfAdapter
->udev
,
140 psIntfAdapter
->sBulkOut
.bulk_out_pipe
,
141 urb
->transfer_buffer
, len
, write_bulk_callback
, pTcb
);
143 urb
->transfer_flags
|= URB_NO_TRANSFER_DMA_MAP
; /* For DMA transfer */
145 if (false == psIntfAdapter
->psAdapter
->device_removed
&&
146 false == psIntfAdapter
->psAdapter
->bEndPointHalted
&&
147 false == psIntfAdapter
->bSuspended
&&
148 false == psIntfAdapter
->bPreparingForBusSuspend
) {
149 retval
= usb_submit_urb(urb
, GFP_ATOMIC
);
151 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
, DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "failed submitting write urb, error %d", retval
);
152 if (retval
== -EPIPE
) {
153 psIntfAdapter
->psAdapter
->bEndPointHalted
= TRUE
;
154 wake_up(&psIntfAdapter
->psAdapter
->tx_packet_wait_queue
);
161 int InterfaceTransmitPacket(PVOID arg
, PVOID data
, UINT len
)
163 struct bcm_usb_tcb
*pTcb
= NULL
;
165 struct bcm_interface_adapter
*psIntfAdapter
= arg
;
166 pTcb
= GetBulkOutTcb(psIntfAdapter
);
168 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
, DBG_TYPE_PRINTK
, 0, 0, "No URB to transmit packet, dropping packet");
171 return TransmitTcb(psIntfAdapter
, pTcb
, data
, len
);