2 extern int SearchVcid(PMINI_ADAPTER
, unsigned short);
6 GetBulkInRcb(PS_INTERFACE_ADAPTER psIntfAdapter
)
11 if((atomic_read(&psIntfAdapter
->uNumRcbUsed
) < MAXIMUM_USB_RCB
) &&
12 (psIntfAdapter
->psAdapter
->StopAllXaction
== FALSE
))
14 index
= atomic_read(&psIntfAdapter
->uCurrRcb
);
15 pRcb
= &psIntfAdapter
->asUsbRcb
[index
];
17 pRcb
->psIntfAdapter
= psIntfAdapter
;
18 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_RX
, RX_DPC
, DBG_LVL_ALL
, "Got Rx desc %d used %d",
19 index
, atomic_read(&psIntfAdapter
->uNumRcbUsed
));
20 index
= (index
+ 1) % MAXIMUM_USB_RCB
;
21 atomic_set(&psIntfAdapter
->uCurrRcb
, index
);
22 atomic_inc(&psIntfAdapter
->uNumRcbUsed
);
27 /*this is receive call back - when pkt avilable for receive (BULK IN- end point)*/
28 static void read_bulk_callback(struct urb
*urb
)
30 struct sk_buff
*skb
= NULL
;
31 BOOLEAN bHeaderSupressionEnabled
= FALSE
;
32 int QueueIndex
= NO_OF_QUEUES
+ 1;
36 PUSB_RCB pRcb
= (PUSB_RCB
)urb
->context
;
37 PS_INTERFACE_ADAPTER psIntfAdapter
= pRcb
->psIntfAdapter
;
38 PMINI_ADAPTER Adapter
= psIntfAdapter
->psAdapter
;
39 PLEADER pLeader
= urb
->transfer_buffer
;
43 int *puiBuffer
= NULL
;
45 memset(&tv
, 0, sizeof(tv
));
49 if((Adapter
->device_removed
== TRUE
) ||
50 (TRUE
== Adapter
->bEndPointHalted
) ||
51 (0 == urb
->actual_length
)
55 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
59 if(urb
->status
!= STATUS_SUCCESS
)
61 if(urb
->status
== -EPIPE
)
63 Adapter
->bEndPointHalted
= TRUE
;
64 wake_up(&Adapter
->tx_packet_wait_queue
);
68 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_RX
, RX_DPC
, DBG_LVL_ALL
,"Rx URB has got cancelled. status :%d", urb
->status
);
71 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
72 urb
->status
= STATUS_SUCCESS
;
76 if(Adapter
->bDoSuspend
&& (Adapter
->bPreparingForLowPowerMode
))
78 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");
82 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_RX
, RX_DPC
, DBG_LVL_ALL
, "Read back done len %d\n", pLeader
->PLength
);
85 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_RX
, RX_DPC
, DBG_LVL_ALL
, "Leader Length 0");
86 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
89 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
);
90 if(MAX_CNTL_PKT_SIZE
< pLeader
->PLength
)
92 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_PRINTK
, 0, 0, "Corrupted leader length...%d\n",
94 atomic_inc(&Adapter
->RxPacketDroppedCount
);
95 atomic_add(pLeader
->PLength
, &Adapter
->BadRxByteCount
);
96 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
100 QueueIndex
= SearchVcid( Adapter
,pLeader
->Vcid
);
101 if(QueueIndex
< NO_OF_QUEUES
)
103 bHeaderSupressionEnabled
=
104 Adapter
->PackInfo
[QueueIndex
].bHeaderSuppressionEnabled
;
105 bHeaderSupressionEnabled
=
106 bHeaderSupressionEnabled
& Adapter
->bPHSEnabled
;
109 skb
= dev_alloc_skb (pLeader
->PLength
+ SKB_RESERVE_PHS_BYTES
+ SKB_RESERVE_ETHERNET_HEADER
);//2 //2 for allignment
112 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_PRINTK
, 0, 0, "NO SKBUFF!!! Dropping the Packet");
113 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
116 /* If it is a control Packet, then call handle_bcm_packet ()*/
117 if((ntohs(pLeader
->Vcid
) == VCID_CONTROL_PACKET
) ||
118 (!(pLeader
->Status
>= 0x20 && pLeader
->Status
<= 0x3F)))
120 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_RX
, RX_CTRL
, DBG_LVL_ALL
, "Recived control pkt...");
121 *(PUSHORT
)skb
->data
= pLeader
->Status
;
122 memcpy(skb
->data
+sizeof(USHORT
), urb
->transfer_buffer
+
123 (sizeof(LEADER
)), pLeader
->PLength
);
124 skb
->len
= pLeader
->PLength
+ sizeof(USHORT
);
126 spin_lock(&Adapter
->control_queue_lock
);
127 ENQUEUEPACKET(Adapter
->RxControlHead
,Adapter
->RxControlTail
,skb
);
128 spin_unlock(&Adapter
->control_queue_lock
);
130 atomic_inc(&Adapter
->cntrlpktCnt
);
131 wake_up(&Adapter
->process_rx_cntrlpkt
);
136 * Data Packet, Format a proper Ethernet Header
137 * and give it to the stack
139 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_RX
, RX_DATA
, DBG_LVL_ALL
, "Recived Data pkt...");
140 skb_reserve(skb
, 2 + SKB_RESERVE_PHS_BYTES
);
141 memcpy(skb
->data
+ETH_HLEN
, (PUCHAR
)urb
->transfer_buffer
+ sizeof(LEADER
), pLeader
->PLength
);
142 skb
->dev
= Adapter
->dev
;
144 /* currently skb->len has extra ETH_HLEN bytes in the beginning */
145 skb_put (skb
, pLeader
->PLength
+ ETH_HLEN
);
146 Adapter
->PackInfo
[QueueIndex
].uiTotalRxBytes
+=pLeader
->PLength
;
147 Adapter
->PackInfo
[QueueIndex
].uiThisPeriodRxBytes
+= pLeader
->PLength
;
148 atomic_add(pLeader
->PLength
, &Adapter
->GoodRxByteCount
);
149 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_RX
, RX_DATA
, DBG_LVL_ALL
, "Recived Data pkt of len :0x%X", pLeader
->PLength
);
153 /* Moving ahead by ETH_HLEN to the data ptr as received from FW */
154 skb_pull(skb
, ETH_HLEN
);
155 PHSRecieve(Adapter
, pLeader
->Vcid
, skb
, &skb
->len
,
156 NULL
,bHeaderSupressionEnabled
);
158 if(!Adapter
->PackInfo
[QueueIndex
].bEthCSSupport
)
160 skb_push(skb
, ETH_HLEN
);
162 memcpy(skb
->data
, skb
->dev
->dev_addr
, 6);
163 memcpy(skb
->data
+6, skb
->dev
->dev_addr
, 6);
165 *(skb
->data
+12) = 0x08;
166 *(skb
->data
+13) = 0x00;
167 pLeader
->PLength
+=ETH_HLEN
;
170 skb
->protocol
= eth_type_trans(skb
, Adapter
->dev
);
171 process_done
= netif_rx(skb
);
175 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_RX
, RX_DATA
, DBG_LVL_ALL
, "i/f not up hance freeing SKB...");
178 atomic_inc(&Adapter
->GoodRxPktCount
);
179 for(uiIndex
= 0 ; uiIndex
< MIBS_MAX_HIST_ENTRIES
; uiIndex
++)
181 if((pLeader
->PLength
<= MIBS_PKTSIZEHIST_RANGE
*(uiIndex
+1))
182 && (pLeader
->PLength
> MIBS_PKTSIZEHIST_RANGE
*(uiIndex
)))
183 Adapter
->aRxPktSizeHist
[uiIndex
]++;
186 Adapter
->PrevNumRecvDescs
++;
188 atomic_dec(&psIntfAdapter
->uNumRcbUsed
);
191 static int ReceiveRcb(PS_INTERFACE_ADAPTER psIntfAdapter
, PUSB_RCB pRcb
)
193 struct urb
*urb
= pRcb
->urb
;
196 usb_fill_bulk_urb(urb
, psIntfAdapter
->udev
, usb_rcvbulkpipe(
197 psIntfAdapter
->udev
, psIntfAdapter
->sBulkIn
.bulk_in_endpointAddr
),
198 urb
->transfer_buffer
, BCM_USB_MAX_READ_LENGTH
, read_bulk_callback
,
200 if(FALSE
== psIntfAdapter
->psAdapter
->device_removed
&&
201 FALSE
== psIntfAdapter
->psAdapter
->bEndPointHalted
&&
202 FALSE
== psIntfAdapter
->bSuspended
&&
203 FALSE
== psIntfAdapter
->bPreparingForBusSuspend
)
205 retval
= usb_submit_urb(urb
, GFP_ATOMIC
);
208 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_RX
, RX_DPC
, DBG_LVL_ALL
, "failed submitting read urb, error %d", retval
);
209 //if this return value is because of pipe halt. need to clear this.
212 psIntfAdapter
->psAdapter
->bEndPointHalted
= TRUE
;
213 wake_up(&psIntfAdapter
->psAdapter
->tx_packet_wait_queue
);
222 Function: InterfaceRx
224 Description: This is the hardware specific Function for Recieveing
225 data packet/control packets from the device.
227 Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
231 Return: TRUE - If Rx was successful.
232 Other - If an error occured.
235 BOOLEAN
InterfaceRx (PS_INTERFACE_ADAPTER psIntfAdapter
)
237 USHORT RxDescCount
= NUM_RX_DESC
- atomic_read(&psIntfAdapter
->uNumRcbUsed
);
238 PUSB_RCB pRcb
= NULL
;
240 // RxDescCount = psIntfAdapter->psAdapter->CurrNumRecvDescs -
241 // psIntfAdapter->psAdapter->PrevNumRecvDescs;
244 pRcb
= GetBulkInRcb(psIntfAdapter
);
247 BCM_DEBUG_PRINT(psIntfAdapter
->psAdapter
,DBG_TYPE_PRINTK
, 0, 0, "Unable to get Rcb pointer");
250 //atomic_inc(&psIntfAdapter->uNumRcbUsed);
251 ReceiveRcb(psIntfAdapter
, pRcb
);