3 static int SearchVcid(struct bcm_mini_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;
15 static struct bcm_usb_rcb
*
16 GetBulkInRcb(struct bcm_interface_adapter
*psIntfAdapter
)
18 struct bcm_usb_rcb
*pRcb
= NULL
;
21 if ((atomic_read(&psIntfAdapter
->uNumRcbUsed
) < MAXIMUM_USB_RCB
) &&
22 (psIntfAdapter
->psAdapter
->StopAllXaction
== false)) {
23 index
= atomic_read(&psIntfAdapter
->uCurrRcb
);
24 pRcb
= &psIntfAdapter
->asUsbRcb
[index
];
26 pRcb
->psIntfAdapter
= psIntfAdapter
;
27 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
, DBG_TYPE_RX
, RX_DPC
, DBG_LVL_ALL
, "Got Rx desc %d used %d",
28 index
, atomic_read(&psIntfAdapter
->uNumRcbUsed
));
29 index
= (index
+ 1) % MAXIMUM_USB_RCB
;
30 atomic_set(&psIntfAdapter
->uCurrRcb
, index
);
31 atomic_inc(&psIntfAdapter
->uNumRcbUsed
);
36 /*this is receive call back - when pkt available for receive (BULK IN- end point)*/
37 static void read_bulk_callback(struct urb
*urb
)
39 struct sk_buff
*skb
= NULL
;
40 bool bHeaderSupressionEnabled
= false;
41 int QueueIndex
= NO_OF_QUEUES
+ 1;
44 struct bcm_usb_rcb
*pRcb
= (struct bcm_usb_rcb
*)urb
->context
;
45 struct bcm_interface_adapter
*psIntfAdapter
= pRcb
->psIntfAdapter
;
46 struct bcm_mini_adapter
*Adapter
= psIntfAdapter
->psAdapter
;
47 struct bcm_leader
*pLeader
= urb
->transfer_buffer
;
49 if (unlikely(netif_msg_rx_status(Adapter
)))
50 pr_info(PFX
"%s: rx urb status %d length %d\n",
51 Adapter
->dev
->name
, urb
->status
, urb
->actual_length
);
53 if ((Adapter
->device_removed
== TRUE
) ||
54 (TRUE
== Adapter
->bEndPointHalted
) ||
55 (0 == urb
->actual_length
)) {
57 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
61 if (urb
->status
!= STATUS_SUCCESS
) {
62 if (urb
->status
== -EPIPE
) {
63 Adapter
->bEndPointHalted
= TRUE
;
64 wake_up(&Adapter
->tx_packet_wait_queue
);
66 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_RX
, RX_DPC
, DBG_LVL_ALL
, "Rx URB has got cancelled. status :%d", urb
->status
);
69 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
70 urb
->status
= STATUS_SUCCESS
;
74 if (Adapter
->bDoSuspend
&& (Adapter
->bPreparingForLowPowerMode
)) {
75 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");
79 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_RX
, RX_DPC
, DBG_LVL_ALL
, "Read back done len %d\n", pLeader
->PLength
);
80 if (!pLeader
->PLength
) {
81 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_RX
, RX_DPC
, DBG_LVL_ALL
, "Leader Length 0");
82 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
85 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
);
86 if (MAX_CNTL_PKT_SIZE
< pLeader
->PLength
) {
87 if (netif_msg_rx_err(Adapter
))
88 pr_info(PFX
"%s: corrupted leader length...%d\n",
89 Adapter
->dev
->name
, pLeader
->PLength
);
90 ++Adapter
->dev
->stats
.rx_dropped
;
91 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
95 QueueIndex
= SearchVcid(Adapter
, pLeader
->Vcid
);
96 if (QueueIndex
< NO_OF_QUEUES
) {
97 bHeaderSupressionEnabled
=
98 Adapter
->PackInfo
[QueueIndex
].bHeaderSuppressionEnabled
;
99 bHeaderSupressionEnabled
=
100 bHeaderSupressionEnabled
& Adapter
->bPHSEnabled
;
103 skb
= dev_alloc_skb(pLeader
->PLength
+ SKB_RESERVE_PHS_BYTES
+ SKB_RESERVE_ETHERNET_HEADER
);
105 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_PRINTK
, 0, 0, "NO SKBUFF!!! Dropping the Packet");
106 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
109 /* If it is a control Packet, then call handle_bcm_packet ()*/
110 if ((ntohs(pLeader
->Vcid
) == VCID_CONTROL_PACKET
) ||
111 (!(pLeader
->Status
>= 0x20 && pLeader
->Status
<= 0x3F))) {
112 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
, DBG_TYPE_RX
, RX_CTRL
, DBG_LVL_ALL
, "Received control pkt...");
113 *(PUSHORT
)skb
->data
= pLeader
->Status
;
114 memcpy(skb
->data
+sizeof(USHORT
), urb
->transfer_buffer
+
115 (sizeof(struct bcm_leader
)), pLeader
->PLength
);
116 skb
->len
= pLeader
->PLength
+ sizeof(USHORT
);
118 spin_lock(&Adapter
->control_queue_lock
);
119 ENQUEUEPACKET(Adapter
->RxControlHead
, Adapter
->RxControlTail
, skb
);
120 spin_unlock(&Adapter
->control_queue_lock
);
122 atomic_inc(&Adapter
->cntrlpktCnt
);
123 wake_up(&Adapter
->process_rx_cntrlpkt
);
126 * Data Packet, Format a proper Ethernet Header
127 * and give it to the stack
129 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
, DBG_TYPE_RX
, RX_DATA
, DBG_LVL_ALL
, "Received Data pkt...");
130 skb_reserve(skb
, 2 + SKB_RESERVE_PHS_BYTES
);
131 memcpy(skb
->data
+ETH_HLEN
, (PUCHAR
)urb
->transfer_buffer
+ sizeof(struct bcm_leader
), pLeader
->PLength
);
132 skb
->dev
= Adapter
->dev
;
134 /* currently skb->len has extra ETH_HLEN bytes in the beginning */
135 skb_put(skb
, pLeader
->PLength
+ ETH_HLEN
);
136 Adapter
->PackInfo
[QueueIndex
].uiTotalRxBytes
+= pLeader
->PLength
;
137 Adapter
->PackInfo
[QueueIndex
].uiThisPeriodRxBytes
+= pLeader
->PLength
;
138 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
, DBG_TYPE_RX
, RX_DATA
, DBG_LVL_ALL
, "Received Data pkt of len :0x%X", pLeader
->PLength
);
140 if (netif_running(Adapter
->dev
)) {
141 /* Moving ahead by ETH_HLEN to the data ptr as received from FW */
142 skb_pull(skb
, ETH_HLEN
);
143 PHSReceive(Adapter
, pLeader
->Vcid
, skb
, &skb
->len
,
144 NULL
, bHeaderSupressionEnabled
);
146 if (!Adapter
->PackInfo
[QueueIndex
].bEthCSSupport
) {
147 skb_push(skb
, ETH_HLEN
);
149 memcpy(skb
->data
, skb
->dev
->dev_addr
, 6);
150 memcpy(skb
->data
+6, skb
->dev
->dev_addr
, 6);
152 *(skb
->data
+12) = 0x08;
153 *(skb
->data
+13) = 0x00;
154 pLeader
->PLength
+= ETH_HLEN
;
157 skb
->protocol
= eth_type_trans(skb
, Adapter
->dev
);
158 process_done
= netif_rx(skb
);
160 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
, DBG_TYPE_RX
, RX_DATA
, DBG_LVL_ALL
, "i/f not up hance freeing SKB...");
164 ++Adapter
->dev
->stats
.rx_packets
;
165 Adapter
->dev
->stats
.rx_bytes
+= pLeader
->PLength
;
167 for (uiIndex
= 0; uiIndex
< MIBS_MAX_HIST_ENTRIES
; uiIndex
++) {
168 if ((pLeader
->PLength
<= MIBS_PKTSIZEHIST_RANGE
*(uiIndex
+1)) &&
169 (pLeader
->PLength
> MIBS_PKTSIZEHIST_RANGE
*(uiIndex
)))
170 Adapter
->aRxPktSizeHist
[uiIndex
]++;
173 Adapter
->PrevNumRecvDescs
++;
175 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
178 static int ReceiveRcb(struct bcm_interface_adapter
*psIntfAdapter
, struct bcm_usb_rcb
*pRcb
)
180 struct urb
*urb
= pRcb
->urb
;
183 usb_fill_bulk_urb(urb
, psIntfAdapter
->udev
, usb_rcvbulkpipe(psIntfAdapter
->udev
, psIntfAdapter
->sBulkIn
.bulk_in_endpointAddr
),
184 urb
->transfer_buffer
, BCM_USB_MAX_READ_LENGTH
, read_bulk_callback
, pRcb
);
185 if (false == psIntfAdapter
->psAdapter
->device_removed
&&
186 false == psIntfAdapter
->psAdapter
->bEndPointHalted
&&
187 false == psIntfAdapter
->bSuspended
&&
188 false == psIntfAdapter
->bPreparingForBusSuspend
) {
189 retval
= usb_submit_urb(urb
, GFP_ATOMIC
);
191 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
, DBG_TYPE_RX
, RX_DPC
, DBG_LVL_ALL
, "failed submitting read urb, error %d", retval
);
192 /* if this return value is because of pipe halt. need to clear this. */
193 if (retval
== -EPIPE
) {
194 psIntfAdapter
->psAdapter
->bEndPointHalted
= TRUE
;
195 wake_up(&psIntfAdapter
->psAdapter
->tx_packet_wait_queue
);
204 Function: InterfaceRx
206 Description: This is the hardware specific Function for Receiving
207 data packet/control packets from the device.
209 Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context
213 Return: TRUE - If Rx was successful.
214 Other - If an error occurred.
217 bool InterfaceRx(struct bcm_interface_adapter
*psIntfAdapter
)
219 USHORT RxDescCount
= NUM_RX_DESC
- atomic_read(&psIntfAdapter
->uNumRcbUsed
);
220 struct bcm_usb_rcb
*pRcb
= NULL
;
222 while (RxDescCount
) {
223 pRcb
= GetBulkInRcb(psIntfAdapter
);
225 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
, DBG_TYPE_PRINTK
, 0, 0, "Unable to get Rcb pointer");
228 ReceiveRcb(psIntfAdapter
, pRcb
);