1#include "headers.h" 2 3static int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid) 4{ 5 int iIndex=0; 6 7 for(iIndex=(NO_OF_QUEUES-1);iIndex>=0;iIndex--) 8 if(Adapter->PackInfo[iIndex].usVCID_Value == usVcid) 9 return iIndex; 10 return NO_OF_QUEUES+1; 11 12} 13 14 15static PUSB_RCB 16GetBulkInRcb(PS_INTERFACE_ADAPTER psIntfAdapter) 17{ 18 PUSB_RCB pRcb = NULL; 19 UINT index = 0; 20 21 if((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) && 22 (psIntfAdapter->psAdapter->StopAllXaction == FALSE)) 23 { 24 index = atomic_read(&psIntfAdapter->uCurrRcb); 25 pRcb = &psIntfAdapter->asUsbRcb[index]; 26 pRcb->bUsed = TRUE; 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); 33 } 34 return pRcb; 35} 36 37/*this is receive call back - when pkt available for receive (BULK IN- end point)*/ 38static void read_bulk_callback(struct urb *urb) 39{ 40 struct sk_buff *skb = NULL; 41 BOOLEAN bHeaderSupressionEnabled = FALSE; 42 int QueueIndex = NO_OF_QUEUES + 1; 43 UINT uiIndex=0; 44 int process_done = 1; 45 //int idleflag = 0 ; 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; 50 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); 54 55 if((Adapter->device_removed == TRUE) || 56 (TRUE == Adapter->bEndPointHalted) || 57 (0 == urb->actual_length) 58 ) 59 { 60 pRcb->bUsed = FALSE; 61 atomic_dec(&psIntfAdapter->uNumRcbUsed); 62 return; 63 } 64 65 if(urb->status != STATUS_SUCCESS) 66 { 67 if(urb->status == -EPIPE) 68 { 69 Adapter->bEndPointHalted = TRUE ; 70 wake_up(&Adapter->tx_packet_wait_queue); 71 } 72 else 73 { 74 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"Rx URB has got cancelled. status :%d", urb->status); 75 } 76 pRcb->bUsed = FALSE; 77 atomic_dec(&psIntfAdapter->uNumRcbUsed); 78 urb->status = STATUS_SUCCESS ; 79 return ; 80 } 81 82 if(Adapter->bDoSuspend && (Adapter->bPreparingForLowPowerMode)) 83 { 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"); 85 return ; 86 } 87 88 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Read back done len %d\n", pLeader->PLength); 89 if(!pLeader->PLength) 90 { 91 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Length 0"); 92 atomic_dec(&psIntfAdapter->uNumRcbUsed); 93 return; 94 } 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) 97 { 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); 103 return; 104 } 105 106 QueueIndex = SearchVcid( Adapter,pLeader->Vcid); 107 if(QueueIndex < NO_OF_QUEUES) 108 { 109 bHeaderSupressionEnabled = 110 Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled; 111 bHeaderSupressionEnabled = 112 bHeaderSupressionEnabled & Adapter->bPHSEnabled; 113 } 114 115 skb = dev_alloc_skb (pLeader->PLength + SKB_RESERVE_PHS_BYTES + SKB_RESERVE_ETHERNET_HEADER);//2 //2 for allignment 116 if(!skb) 117 { 118 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "NO SKBUFF!!! Dropping the Packet"); 119 atomic_dec(&psIntfAdapter->uNumRcbUsed); 120 return; 121 } 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))) 125 { 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); 131 132 spin_lock(&Adapter->control_queue_lock); 133 ENQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail,skb); 134 spin_unlock(&Adapter->control_queue_lock); 135 136 atomic_inc(&Adapter->cntrlpktCnt); 137 wake_up(&Adapter->process_rx_cntrlpkt); 138 } 139 else 140 { 141 /* 142 * Data Packet, Format a proper Ethernet Header 143 * and give it to the stack 144 */ 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; 149 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); 155 156 if(netif_running(Adapter->dev)) 157 { 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); 162 163 if(!Adapter->PackInfo[QueueIndex].bEthCSSupport) 164 { 165 skb_push(skb, ETH_HLEN); 166 167 memcpy(skb->data, skb->dev->dev_addr, 6); 168 memcpy(skb->data+6, skb->dev->dev_addr, 6); 169 (*(skb->data+11))++; 170 *(skb->data+12) = 0x08; 171 *(skb->data+13) = 0x00; 172 pLeader->PLength+=ETH_HLEN; 173 } 174 175 skb->protocol = eth_type_trans(skb, Adapter->dev); 176 process_done = netif_rx(skb); 177 } 178 else 179 { 180 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB..."); 181 dev_kfree_skb(skb); 182 } 183 184 ++Adapter->dev->stats.rx_packets; 185 Adapter->dev->stats.rx_bytes += pLeader->PLength; 186 187 for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++) 188 { 189 if((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) 190 && (pLeader->PLength > MIBS_PKTSIZEHIST_RANGE*(uiIndex))) 191 Adapter->aRxPktSizeHist[uiIndex]++; 192 } 193 } 194 Adapter->PrevNumRecvDescs++; 195 pRcb->bUsed = FALSE; 196 atomic_dec(&psIntfAdapter->uNumRcbUsed); 197} 198 199static int ReceiveRcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_RCB pRcb) 200{ 201 struct urb *urb = pRcb->urb; 202 int retval = 0; 203 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, 207 pRcb); 208 if(FALSE == psIntfAdapter->psAdapter->device_removed && 209 FALSE == psIntfAdapter->psAdapter->bEndPointHalted && 210 FALSE == psIntfAdapter->bSuspended && 211 FALSE == psIntfAdapter->bPreparingForBusSuspend) 212 { 213 retval = usb_submit_urb(urb, GFP_ATOMIC); 214 if (retval) 215 { 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. 218 if(retval == -EPIPE) 219 { 220 psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; 221 wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); 222 } 223 224 } 225 } 226 return retval; 227} 228 229/* 230Function: InterfaceRx 231 232Description: This is the hardware specific Function for Receiving 233 data packet/control packets from the device. 234 235Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context 236 237 238 239Return: TRUE - If Rx was successful. 240 Other - If an error occurred. 241*/ 242 243BOOLEAN InterfaceRx (PS_INTERFACE_ADAPTER psIntfAdapter) 244{ 245 USHORT RxDescCount = NUM_RX_DESC - atomic_read(&psIntfAdapter->uNumRcbUsed); 246 PUSB_RCB pRcb = NULL; 247 248// RxDescCount = psIntfAdapter->psAdapter->CurrNumRecvDescs - 249// psIntfAdapter->psAdapter->PrevNumRecvDescs; 250 while(RxDescCount) 251 { 252 pRcb = GetBulkInRcb(psIntfAdapter); 253 if(pRcb == NULL) 254 { 255 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Unable to get Rcb pointer"); 256 return FALSE; 257 } 258 //atomic_inc(&psIntfAdapter->uNumRcbUsed); 259 ReceiveRcb(psIntfAdapter, pRcb); 260 RxDescCount--; 261 } 262 return TRUE; 263} 264 265