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
);