3
static int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid)
7
for(iIndex=(NO_OF_QUEUES-1);iIndex>=0;iIndex--)
8
if(Adapter->PackInfo[iIndex].usVCID_Value == usVcid)
10
return NO_OF_QUEUES+1;
16
GetBulkInRcb(PS_INTERFACE_ADAPTER psIntfAdapter)
21
if((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) &&
22
(psIntfAdapter->psAdapter->StopAllXaction == FALSE))
24
index = atomic_read(&psIntfAdapter->uCurrRcb);
25
pRcb = &psIntfAdapter->asUsbRcb[index];
27
pRcb->psIntfAdapter= psIntfAdapter;
28
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Got Rx desc %d used %d",
29
index, atomic_read(&psIntfAdapter->uNumRcbUsed));
30
index = (index + 1) % MAXIMUM_USB_RCB;
31
atomic_set(&psIntfAdapter->uCurrRcb, index);
32
atomic_inc(&psIntfAdapter->uNumRcbUsed);
37
/*this is receive call back - when pkt available for receive (BULK IN- end point)*/
38
static void read_bulk_callback(struct urb *urb)
40
struct sk_buff *skb = NULL;
41
BOOLEAN bHeaderSupressionEnabled = FALSE;
42
int QueueIndex = NO_OF_QUEUES + 1;
46
PUSB_RCB pRcb = (PUSB_RCB)urb->context;
47
PS_INTERFACE_ADAPTER psIntfAdapter = pRcb->psIntfAdapter;
48
PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
49
PLEADER pLeader = urb->transfer_buffer;
51
if (unlikely(netif_msg_rx_status(Adapter)))
52
pr_info(PFX "%s: rx urb status %d length %d\n",
53
Adapter->dev->name, urb->status, urb->actual_length);
55
if((Adapter->device_removed == TRUE) ||
56
(TRUE == Adapter->bEndPointHalted) ||
57
(0 == urb->actual_length)
61
atomic_dec(&psIntfAdapter->uNumRcbUsed);
65
if(urb->status != STATUS_SUCCESS)
67
if(urb->status == -EPIPE)
69
Adapter->bEndPointHalted = TRUE ;
70
wake_up(&Adapter->tx_packet_wait_queue);
74
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"Rx URB has got cancelled. status :%d", urb->status);
77
atomic_dec(&psIntfAdapter->uNumRcbUsed);
78
urb->status = STATUS_SUCCESS ;
82
if(Adapter->bDoSuspend && (Adapter->bPreparingForLowPowerMode))
84
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");
88
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Read back done len %d\n", pLeader->PLength);
91
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Length 0");
92
atomic_dec(&psIntfAdapter->uNumRcbUsed);
95
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);
96
if(MAX_CNTL_PKT_SIZE < pLeader->PLength)
98
if (netif_msg_rx_err(Adapter))
99
pr_info(PFX "%s: corrupted leader length...%d\n",
100
Adapter->dev->name, pLeader->PLength);
101
++Adapter->dev->stats.rx_dropped;
102
atomic_dec(&psIntfAdapter->uNumRcbUsed);
106
QueueIndex = SearchVcid( Adapter,pLeader->Vcid);
107
if(QueueIndex < NO_OF_QUEUES)
109
bHeaderSupressionEnabled =
110
Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled;
111
bHeaderSupressionEnabled =
112
bHeaderSupressionEnabled & Adapter->bPHSEnabled;
115
skb = dev_alloc_skb (pLeader->PLength + SKB_RESERVE_PHS_BYTES + SKB_RESERVE_ETHERNET_HEADER);//2 //2 for allignment
118
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "NO SKBUFF!!! Dropping the Packet");
119
atomic_dec(&psIntfAdapter->uNumRcbUsed);
122
/* If it is a control Packet, then call handle_bcm_packet ()*/
123
if((ntohs(pLeader->Vcid) == VCID_CONTROL_PACKET) ||
124
(!(pLeader->Status >= 0x20 && pLeader->Status <= 0x3F)))
126
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, "Received control pkt...");
127
*(PUSHORT)skb->data = pLeader->Status;
128
memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer +
129
(sizeof(LEADER)), pLeader->PLength);
130
skb->len = pLeader->PLength + sizeof(USHORT);
132
spin_lock(&Adapter->control_queue_lock);
133
ENQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail,skb);
134
spin_unlock(&Adapter->control_queue_lock);
136
atomic_inc(&Adapter->cntrlpktCnt);
137
wake_up(&Adapter->process_rx_cntrlpkt);
142
* Data Packet, Format a proper Ethernet Header
143
* and give it to the stack
145
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Received Data pkt...");
146
skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES);
147
memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer + sizeof(LEADER), pLeader->PLength);
148
skb->dev = Adapter->dev;
150
/* currently skb->len has extra ETH_HLEN bytes in the beginning */
151
skb_put (skb, pLeader->PLength + ETH_HLEN);
152
Adapter->PackInfo[QueueIndex].uiTotalRxBytes+=pLeader->PLength;
153
Adapter->PackInfo[QueueIndex].uiThisPeriodRxBytes+= pLeader->PLength;
154
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Received Data pkt of len :0x%X", pLeader->PLength);
156
if(netif_running(Adapter->dev))
158
/* Moving ahead by ETH_HLEN to the data ptr as received from FW */
159
skb_pull(skb, ETH_HLEN);
160
PHSReceive(Adapter, pLeader->Vcid, skb, &skb->len,
161
NULL,bHeaderSupressionEnabled);
163
if(!Adapter->PackInfo[QueueIndex].bEthCSSupport)
165
skb_push(skb, ETH_HLEN);
167
memcpy(skb->data, skb->dev->dev_addr, 6);
168
memcpy(skb->data+6, skb->dev->dev_addr, 6);
170
*(skb->data+12) = 0x08;
171
*(skb->data+13) = 0x00;
172
pLeader->PLength+=ETH_HLEN;
175
skb->protocol = eth_type_trans(skb, Adapter->dev);
176
process_done = netif_rx(skb);
180
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB...");
184
++Adapter->dev->stats.rx_packets;
185
Adapter->dev->stats.rx_bytes += pLeader->PLength;
187
for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++)
189
if((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1))
190
&& (pLeader->PLength > MIBS_PKTSIZEHIST_RANGE*(uiIndex)))
191
Adapter->aRxPktSizeHist[uiIndex]++;
194
Adapter->PrevNumRecvDescs++;
196
atomic_dec(&psIntfAdapter->uNumRcbUsed);
199
static int ReceiveRcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_RCB pRcb)
201
struct urb *urb = pRcb->urb;
204
usb_fill_bulk_urb(urb, psIntfAdapter->udev, usb_rcvbulkpipe(
205
psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_endpointAddr),
206
urb->transfer_buffer, BCM_USB_MAX_READ_LENGTH, read_bulk_callback,
208
if(FALSE == psIntfAdapter->psAdapter->device_removed &&
209
FALSE == psIntfAdapter->psAdapter->bEndPointHalted &&
210
FALSE == psIntfAdapter->bSuspended &&
211
FALSE == psIntfAdapter->bPreparingForBusSuspend)
213
retval = usb_submit_urb(urb, GFP_ATOMIC);
216
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "failed submitting read urb, error %d", retval);
217
//if this return value is because of pipe halt. need to clear this.
220
psIntfAdapter->psAdapter->bEndPointHalted = TRUE ;
221
wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
230
Function: InterfaceRx
232
Description: This is the hardware specific Function for Receiving
233
data packet/control packets from the device.
235
Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
239
Return: TRUE - If Rx was successful.
240
Other - If an error occurred.
243
BOOLEAN InterfaceRx (PS_INTERFACE_ADAPTER psIntfAdapter)
245
USHORT RxDescCount = NUM_RX_DESC - atomic_read(&psIntfAdapter->uNumRcbUsed);
246
PUSB_RCB pRcb = NULL;
248
// RxDescCount = psIntfAdapter->psAdapter->CurrNumRecvDescs -
249
// psIntfAdapter->psAdapter->PrevNumRecvDescs;
252
pRcb = GetBulkInRcb(psIntfAdapter);
255
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Unable to get Rcb pointer");
258
//atomic_inc(&psIntfAdapter->uNumRcbUsed);
259
ReceiveRcb(psIntfAdapter, pRcb);