1 #include "headers.h"
2 
3 /*this is transmit call-back(BULK OUT)*/
write_bulk_callback(struct urb * urb)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 
GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)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 
TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter,PUSB_TCB pTcb,PVOID data,int len)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 
InterfaceTransmitPacket(PVOID arg,PVOID data,UINT len)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 
198