GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / usb / Beceem_driver / src / Interface / usb / InterfaceRx.c
blob3ab055bc8896036e047bc4c86e40a4b0cf11b127
1 /*
2 * InterfaceRx.c
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.
22 #include <headers.h>
23 extern int SearchVcid(PMINI_ADAPTER , unsigned short);
26 static PUSB_RCB
27 GetBulkInRcb(PS_INTERFACE_ADAPTER psIntfAdapter)
29 PUSB_RCB pRcb = NULL;
30 UINT index = 0;
32 if((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) &&
33 (psIntfAdapter->psAdapter->StopAllXaction == FALSE))
35 index = atomic_read(&psIntfAdapter->uCurrRcb);
36 pRcb = &psIntfAdapter->asUsbRcb[index];
37 pRcb->bUsed = TRUE;
38 pRcb->psIntfAdapter= psIntfAdapter;
39 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Got Rx desc %d used %d",
40 index, atomic_read(&psIntfAdapter->uNumRcbUsed));
41 index = (index + 1) % MAXIMUM_USB_RCB;
42 atomic_set(&psIntfAdapter->uCurrRcb, index);
43 atomic_inc(&psIntfAdapter->uNumRcbUsed);
45 return pRcb;
48 /*this is receive call back - when pkt avilable for receive (BULK IN- end point)*/
49 static void read_bulk_callback(struct urb *urb)
51 struct sk_buff *skb = NULL;
52 BOOLEAN bHeaderSupressionEnabled = FALSE;
53 int QueueIndex = NO_OF_QUEUES + 1;
54 UINT uiIndex=0;
55 int process_done = 1;
56 //int idleflag = 0 ;
57 PUSB_RCB pRcb = (PUSB_RCB)urb->context;
58 PS_INTERFACE_ADAPTER psIntfAdapter = pRcb->psIntfAdapter;
59 PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
60 PLEADER pLeader = urb->transfer_buffer;
63 #if 0
64 int *puiBuffer = NULL;
65 struct timeval tv;
66 memset(&tv, 0, sizeof(tv));
67 do_gettimeofday(&tv);
68 #endif
70 if((Adapter->device_removed == TRUE) ||
71 (TRUE == Adapter->bEndPointHalted) ||
72 (0 == urb->actual_length)
75 pRcb->bUsed = FALSE;
76 atomic_dec(&psIntfAdapter->uNumRcbUsed);
77 return;
80 if(urb->status != STATUS_SUCCESS)
82 if(urb->status == -EPIPE)
84 Adapter->bEndPointHalted = TRUE ;
85 wake_up(&Adapter->tx_packet_wait_queue);
87 else
89 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"Rx URB has got cancelled. status :%d", urb->status);
91 pRcb->bUsed = FALSE;
92 atomic_dec(&psIntfAdapter->uNumRcbUsed);
93 urb->status = STATUS_SUCCESS ;
94 return ;
97 if(Adapter->bDoSuspend && (Adapter->bPreparingForLowPowerMode))
99 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"device is going in low power mode while PMU option selected..hence rx packet should not be process");
100 return ;
103 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Read back done len %d\n", pLeader->PLength);
104 if(!pLeader->PLength)
106 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Length 0");
107 atomic_dec(&psIntfAdapter->uNumRcbUsed);
108 return;
110 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", pLeader->Status,pLeader->PLength,pLeader->Vcid);
111 if(MAX_CNTL_PKT_SIZE < pLeader->PLength)
113 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Corrupted leader length...%d\n",
114 pLeader->PLength);
115 atomic_inc(&Adapter->RxPacketDroppedCount);
116 atomic_add(pLeader->PLength, &Adapter->BadRxByteCount);
117 atomic_dec(&psIntfAdapter->uNumRcbUsed);
118 return;
121 QueueIndex = SearchVcid( Adapter,pLeader->Vcid);
122 if(QueueIndex < NO_OF_QUEUES)
124 bHeaderSupressionEnabled =
125 Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled;
126 bHeaderSupressionEnabled =
127 bHeaderSupressionEnabled & Adapter->bPHSEnabled;
130 skb = dev_alloc_skb (pLeader->PLength + SKB_RESERVE_PHS_BYTES + SKB_RESERVE_ETHERNET_HEADER);//2 //2 for allignment
131 if(!skb)
133 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "NO SKBUFF!!! Dropping the Packet");
134 atomic_dec(&psIntfAdapter->uNumRcbUsed);
135 return;
137 /* If it is a control Packet, then call handle_bcm_packet ()*/
138 if((ntohs(pLeader->Vcid) == VCID_CONTROL_PACKET) ||
139 (!(pLeader->Status >= 0x20 && pLeader->Status <= 0x3F)))
141 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, "Recived control pkt...");
142 *(PUSHORT)skb->data = pLeader->Status;
143 memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer +
144 (sizeof(LEADER)), pLeader->PLength);
145 skb->len = pLeader->PLength + sizeof(USHORT);
147 spin_lock(&Adapter->control_queue_lock);
148 ENQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail,skb);
149 spin_unlock(&Adapter->control_queue_lock);
151 atomic_inc(&Adapter->cntrlpktCnt);
152 wake_up(&Adapter->process_rx_cntrlpkt);
154 else
157 * Data Packet, Format a proper Ethernet Header
158 * and give it to the stack
160 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Recived Data pkt...");
161 skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES);
162 memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer + sizeof(LEADER), pLeader->PLength);
163 skb->dev = Adapter->dev;
165 /* currently skb->len has extra ETH_HLEN bytes in the beginning */
166 skb_put (skb, pLeader->PLength + ETH_HLEN);
167 Adapter->PackInfo[QueueIndex].uiTotalRxBytes+=pLeader->PLength;
168 Adapter->PackInfo[QueueIndex].uiThisPeriodRxBytes+= pLeader->PLength;
169 atomic_add(pLeader->PLength, &Adapter->GoodRxByteCount);
170 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Recived Data pkt of len :0x%X", pLeader->PLength);
172 if(Adapter->if_up)
174 /* Moving ahead by ETH_HLEN to the data ptr as received from FW */
175 skb_pull(skb, ETH_HLEN);
176 PHSRecieve(Adapter, pLeader->Vcid, skb, &skb->len,
177 NULL,bHeaderSupressionEnabled);
179 if(!Adapter->PackInfo[QueueIndex].bEthCSSupport)
181 skb_push(skb, ETH_HLEN);
183 memcpy(skb->data, skb->dev->dev_addr, 6);
184 memcpy(skb->data+6, skb->dev->dev_addr, 6);
185 (*(skb->data+11))++;
186 *(skb->data+12) = 0x08;
187 *(skb->data+13) = 0x00;
188 pLeader->PLength+=ETH_HLEN;
191 skb->protocol = eth_type_trans(skb, Adapter->dev);
192 process_done = netif_rx(skb);
194 else
196 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB...");
197 bcm_kfree_skb(skb);
199 atomic_inc(&Adapter->GoodRxPktCount);
200 for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++)
202 if((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1))
203 && (pLeader->PLength > MIBS_PKTSIZEHIST_RANGE*(uiIndex)))
204 Adapter->aRxPktSizeHist[uiIndex]++;
207 Adapter->PrevNumRecvDescs++;
208 pRcb->bUsed = FALSE;
209 atomic_dec(&psIntfAdapter->uNumRcbUsed);
212 static int ReceiveRcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_RCB pRcb)
214 struct urb *urb = pRcb->urb;
215 int retval = 0;
217 usb_fill_bulk_urb(urb, psIntfAdapter->udev, usb_rcvbulkpipe(
218 psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_endpointAddr),
219 urb->transfer_buffer, BCM_USB_MAX_READ_LENGTH, read_bulk_callback,
220 pRcb);
221 if(FALSE == psIntfAdapter->psAdapter->device_removed &&
222 FALSE == psIntfAdapter->psAdapter->bEndPointHalted &&
223 FALSE == psIntfAdapter->bSuspended &&
224 FALSE == psIntfAdapter->bPreparingForBusSuspend)
226 retval = usb_submit_urb(urb, GFP_ATOMIC);
227 if (retval)
229 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "failed submitting read urb, error %d", retval);
230 //if this return value is because of pipe halt. need to clear this.
231 if(retval == -EPIPE)
233 psIntfAdapter->psAdapter->bEndPointHalted = TRUE ;
234 wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
239 return retval;
243 Function: InterfaceRx
245 Description: This is the hardware specific Function for Recieveing
246 data packet/control packets from the device.
248 Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
252 Return: TRUE - If Rx was successful.
253 Other - If an error occured.
256 BOOLEAN InterfaceRx (PS_INTERFACE_ADAPTER psIntfAdapter)
258 USHORT RxDescCount = NUM_RX_DESC - atomic_read(&psIntfAdapter->uNumRcbUsed);
259 PUSB_RCB pRcb = NULL;
261 // RxDescCount = psIntfAdapter->psAdapter->CurrNumRecvDescs -
262 // psIntfAdapter->psAdapter->PrevNumRecvDescs;
263 while(RxDescCount)
265 pRcb = GetBulkInRcb(psIntfAdapter);
266 if(pRcb == NULL)
268 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Unable to get Rcb pointer");
269 return FALSE;
271 //atomic_inc(&psIntfAdapter->uNumRcbUsed);
272 ReceiveRcb(psIntfAdapter, pRcb);
273 RxDescCount--;
275 return TRUE;