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.
23 extern int SearchVcid(PMINI_ADAPTER
, unsigned short);
27 GetBulkInRcb(PS_INTERFACE_ADAPTER psIntfAdapter
)
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
];
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
);
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;
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
;
64 int *puiBuffer
= NULL
;
66 memset(&tv
, 0, sizeof(tv
));
70 if((Adapter
->device_removed
== TRUE
) ||
71 (TRUE
== Adapter
->bEndPointHalted
) ||
72 (0 == urb
->actual_length
)
76 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
80 if(urb
->status
!= STATUS_SUCCESS
)
82 if(urb
->status
== -EPIPE
)
84 Adapter
->bEndPointHalted
= TRUE
;
85 wake_up(&Adapter
->tx_packet_wait_queue
);
89 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_RX
, RX_DPC
, DBG_LVL_ALL
,"Rx URB has got cancelled. status :%d", urb
->status
);
92 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
93 urb
->status
= STATUS_SUCCESS
;
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");
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
);
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",
115 atomic_inc(&Adapter
->RxPacketDroppedCount
);
116 atomic_add(pLeader
->PLength
, &Adapter
->BadRxByteCount
);
117 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
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
133 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_PRINTK
, 0, 0, "NO SKBUFF!!! Dropping the Packet");
134 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
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
);
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
);
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);
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
);
196 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_RX
, RX_DATA
, DBG_LVL_ALL
, "i/f not up hance freeing 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
++;
209 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
212 static int ReceiveRcb(PS_INTERFACE_ADAPTER psIntfAdapter
, PUSB_RCB pRcb
)
214 struct urb
*urb
= pRcb
->urb
;
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
,
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
);
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.
233 psIntfAdapter
->psAdapter
->bEndPointHalted
= TRUE
;
234 wake_up(&psIntfAdapter
->psAdapter
->tx_packet_wait_queue
);
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;
265 pRcb
= GetBulkInRcb(psIntfAdapter
);
268 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Unable to get Rcb pointer");
271 //atomic_inc(&psIntfAdapter->uNumRcbUsed);
272 ReceiveRcb(psIntfAdapter
, pRcb
);