Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 1 | #include "headers.h" |
Stephen Hemminger | cacd922 | 2010-11-01 13:34:35 -0400 | [diff] [blame] | 2 | |
Matthias Beyer | c6346fa | 2014-06-30 10:10:02 +0200 | [diff] [blame] | 3 | static void handle_control_packet(struct bcm_interface_adapter *interface, |
| 4 | struct bcm_mini_adapter *ad, |
| 5 | struct bcm_leader *leader, |
| 6 | struct sk_buff *skb, |
| 7 | struct urb *urb) |
| 8 | { |
| 9 | BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, |
| 10 | "Received control pkt..."); |
| 11 | *(PUSHORT)skb->data = leader->Status; |
| 12 | memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer + |
| 13 | (sizeof(struct bcm_leader)), leader->PLength); |
| 14 | skb->len = leader->PLength + sizeof(USHORT); |
| 15 | |
| 16 | spin_lock(&ad->control_queue_lock); |
| 17 | ENQUEUEPACKET(ad->RxControlHead, ad->RxControlTail, skb); |
| 18 | spin_unlock(&ad->control_queue_lock); |
| 19 | |
| 20 | atomic_inc(&ad->cntrlpktCnt); |
| 21 | wake_up(&ad->process_rx_cntrlpkt); |
| 22 | } |
| 23 | |
Matthias Beyer | 3a162b1 | 2014-06-30 10:10:03 +0200 | [diff] [blame] | 24 | static void format_eth_hdr_to_stack(struct bcm_interface_adapter *interface, |
| 25 | struct bcm_mini_adapter *ad, |
| 26 | struct bcm_leader *p_leader, |
| 27 | struct sk_buff *skb, |
| 28 | struct urb *urb, |
| 29 | UINT ui_index, |
| 30 | int queue_index, |
Matthias Beyer | 8139b8d | 2014-06-30 10:10:04 +0200 | [diff] [blame] | 31 | bool b_header_supression_endabled) |
Matthias Beyer | 3a162b1 | 2014-06-30 10:10:03 +0200 | [diff] [blame] | 32 | { |
| 33 | /* |
| 34 | * Data Packet, Format a proper Ethernet Header |
| 35 | * and give it to the stack |
| 36 | */ |
| 37 | BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_DATA, |
| 38 | DBG_LVL_ALL, "Received Data pkt..."); |
| 39 | skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES); |
| 40 | memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer + |
| 41 | sizeof(struct bcm_leader), p_leader->PLength); |
| 42 | skb->dev = ad->dev; |
| 43 | |
| 44 | /* currently skb->len has extra ETH_HLEN bytes in the beginning */ |
| 45 | skb_put(skb, p_leader->PLength + ETH_HLEN); |
| 46 | ad->PackInfo[queue_index].uiTotalRxBytes += p_leader->PLength; |
| 47 | ad->PackInfo[queue_index].uiThisPeriodRxBytes += p_leader->PLength; |
| 48 | BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_DATA, |
| 49 | DBG_LVL_ALL, "Received Data pkt of len :0x%X", |
| 50 | p_leader->PLength); |
| 51 | |
| 52 | if (netif_running(ad->dev)) { |
| 53 | /* Moving ahead by ETH_HLEN to the data ptr as received from FW */ |
| 54 | skb_pull(skb, ETH_HLEN); |
| 55 | PHSReceive(ad, p_leader->Vcid, skb, &skb->len, |
| 56 | NULL, b_header_supression_endabled); |
| 57 | |
| 58 | if (!ad->PackInfo[queue_index].bEthCSSupport) { |
| 59 | skb_push(skb, ETH_HLEN); |
| 60 | |
| 61 | memcpy(skb->data, skb->dev->dev_addr, 6); |
| 62 | memcpy(skb->data+6, skb->dev->dev_addr, 6); |
| 63 | (*(skb->data+11))++; |
| 64 | *(skb->data+12) = 0x08; |
| 65 | *(skb->data+13) = 0x00; |
| 66 | p_leader->PLength += ETH_HLEN; |
| 67 | } |
| 68 | |
| 69 | skb->protocol = eth_type_trans(skb, ad->dev); |
Matthias Beyer | 8139b8d | 2014-06-30 10:10:04 +0200 | [diff] [blame] | 70 | netif_rx(skb); |
Matthias Beyer | 3a162b1 | 2014-06-30 10:10:03 +0200 | [diff] [blame] | 71 | } else { |
| 72 | BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, |
| 73 | RX_DATA, DBG_LVL_ALL, |
| 74 | "i/f not up hance freeing SKB..."); |
| 75 | dev_kfree_skb(skb); |
| 76 | } |
| 77 | |
| 78 | ++ad->dev->stats.rx_packets; |
| 79 | ad->dev->stats.rx_bytes += p_leader->PLength; |
| 80 | |
| 81 | for (ui_index = 0; ui_index < MIBS_MAX_HIST_ENTRIES; ui_index++) { |
| 82 | if ((p_leader->PLength <= |
| 83 | MIBS_PKTSIZEHIST_RANGE*(ui_index+1)) && |
| 84 | (p_leader->PLength > MIBS_PKTSIZEHIST_RANGE*(ui_index))) |
| 85 | |
| 86 | ad->aRxPktSizeHist[ui_index]++; |
| 87 | } |
| 88 | } |
| 89 | |
Matthias Oefelein | d38eca9 | 2014-01-08 23:15:06 +0100 | [diff] [blame] | 90 | static int SearchVcid(struct bcm_mini_adapter *Adapter, unsigned short usVcid) |
Stephen Hemminger | cacd922 | 2010-11-01 13:34:35 -0400 | [diff] [blame] | 91 | { |
Matthias Oefelein | 1b42f1d | 2014-01-08 23:15:05 +0100 | [diff] [blame] | 92 | int iIndex = 0; |
Stephen Hemminger | cacd922 | 2010-11-01 13:34:35 -0400 | [diff] [blame] | 93 | |
Matthias Oefelein | 7d774a5 | 2014-01-08 23:15:08 +0100 | [diff] [blame] | 94 | for (iIndex = (NO_OF_QUEUES-1); iIndex >= 0; iIndex--) |
| 95 | if (Adapter->PackInfo[iIndex].usVCID_Value == usVcid) |
Stephen Hemminger | cacd922 | 2010-11-01 13:34:35 -0400 | [diff] [blame] | 96 | return iIndex; |
| 97 | return NO_OF_QUEUES+1; |
| 98 | |
| 99 | } |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 100 | |
| 101 | |
Kevin McKinney | 71dd092 | 2012-11-01 23:42:22 -0400 | [diff] [blame] | 102 | static struct bcm_usb_rcb * |
Kevin McKinney | d6861cf | 2012-11-01 23:42:21 -0400 | [diff] [blame] | 103 | GetBulkInRcb(struct bcm_interface_adapter *psIntfAdapter) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 104 | { |
Kevin McKinney | 71dd092 | 2012-11-01 23:42:22 -0400 | [diff] [blame] | 105 | struct bcm_usb_rcb *pRcb = NULL; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 106 | UINT index = 0; |
| 107 | |
Matthias Oefelein | 7d774a5 | 2014-01-08 23:15:08 +0100 | [diff] [blame] | 108 | if ((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) && |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 109 | (psIntfAdapter->psAdapter->StopAllXaction == false)) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 110 | index = atomic_read(&psIntfAdapter->uCurrRcb); |
| 111 | pRcb = &psIntfAdapter->asUsbRcb[index]; |
| 112 | pRcb->bUsed = TRUE; |
Matthias Oefelein | 1b42f1d | 2014-01-08 23:15:05 +0100 | [diff] [blame] | 113 | pRcb->psIntfAdapter = psIntfAdapter; |
Matthias Beyer | f5c86ab | 2014-06-30 10:10:01 +0200 | [diff] [blame] | 114 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DPC, |
| 115 | DBG_LVL_ALL, "Got Rx desc %d used %d", index, |
| 116 | atomic_read(&psIntfAdapter->uNumRcbUsed)); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 117 | index = (index + 1) % MAXIMUM_USB_RCB; |
| 118 | atomic_set(&psIntfAdapter->uCurrRcb, index); |
| 119 | atomic_inc(&psIntfAdapter->uNumRcbUsed); |
| 120 | } |
| 121 | return pRcb; |
| 122 | } |
| 123 | |
Lucas De Marchi | 25985ed | 2011-03-30 22:57:33 -0300 | [diff] [blame] | 124 | /*this is receive call back - when pkt available for receive (BULK IN- end point)*/ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 125 | static void read_bulk_callback(struct urb *urb) |
| 126 | { |
| 127 | struct sk_buff *skb = NULL; |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 128 | bool bHeaderSupressionEnabled = false; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 129 | int QueueIndex = NO_OF_QUEUES + 1; |
Matthias Oefelein | 1b42f1d | 2014-01-08 23:15:05 +0100 | [diff] [blame] | 130 | UINT uiIndex = 0; |
Kevin McKinney | 71dd092 | 2012-11-01 23:42:22 -0400 | [diff] [blame] | 131 | struct bcm_usb_rcb *pRcb = (struct bcm_usb_rcb *)urb->context; |
Kevin McKinney | d6861cf | 2012-11-01 23:42:21 -0400 | [diff] [blame] | 132 | struct bcm_interface_adapter *psIntfAdapter = pRcb->psIntfAdapter; |
Kevin McKinney | 2979460 | 2012-05-26 12:05:12 -0400 | [diff] [blame] | 133 | struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; |
Kevin McKinney | ff35204 | 2012-05-26 12:05:11 -0400 | [diff] [blame] | 134 | struct bcm_leader *pLeader = urb->transfer_buffer; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 135 | |
Stephen Hemminger | 9ec4475 | 2010-11-01 12:18:36 -0400 | [diff] [blame] | 136 | if (unlikely(netif_msg_rx_status(Adapter))) |
| 137 | pr_info(PFX "%s: rx urb status %d length %d\n", |
| 138 | Adapter->dev->name, urb->status, urb->actual_length); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 139 | |
Matthias Oefelein | 7d774a5 | 2014-01-08 23:15:08 +0100 | [diff] [blame] | 140 | if ((Adapter->device_removed == TRUE) || |
| 141 | (TRUE == Adapter->bEndPointHalted) || |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 142 | (0 == urb->actual_length)) { |
Matthias Oefelein | 26ac5b4 | 2014-01-08 23:15:07 +0100 | [diff] [blame] | 143 | pRcb->bUsed = false; |
| 144 | atomic_dec(&psIntfAdapter->uNumRcbUsed); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 145 | return; |
| 146 | } |
| 147 | |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 148 | if (urb->status != STATUS_SUCCESS) { |
| 149 | if (urb->status == -EPIPE) { |
Matthias Oefelein | 1b42f1d | 2014-01-08 23:15:05 +0100 | [diff] [blame] | 150 | Adapter->bEndPointHalted = TRUE; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 151 | wake_up(&Adapter->tx_packet_wait_queue); |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 152 | } else { |
Matthias Beyer | f5c86ab | 2014-06-30 10:10:01 +0200 | [diff] [blame] | 153 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, |
| 154 | DBG_LVL_ALL, |
| 155 | "Rx URB has got cancelled. status :%d", |
| 156 | urb->status); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 157 | } |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 158 | pRcb->bUsed = false; |
Matthias Oefelein | 26ac5b4 | 2014-01-08 23:15:07 +0100 | [diff] [blame] | 159 | atomic_dec(&psIntfAdapter->uNumRcbUsed); |
Matthias Oefelein | 1b42f1d | 2014-01-08 23:15:05 +0100 | [diff] [blame] | 160 | urb->status = STATUS_SUCCESS; |
| 161 | return; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 162 | } |
| 163 | |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 164 | if (Adapter->bDoSuspend && (Adapter->bPreparingForLowPowerMode)) { |
Matthias Beyer | f5c86ab | 2014-06-30 10:10:01 +0200 | [diff] [blame] | 165 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, |
| 166 | "device is going in low power mode while PMU option selected..hence rx packet should not be process"); |
Matthias Oefelein | 1b42f1d | 2014-01-08 23:15:05 +0100 | [diff] [blame] | 167 | return; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 168 | } |
| 169 | |
Matthias Beyer | f5c86ab | 2014-06-30 10:10:01 +0200 | [diff] [blame] | 170 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, |
| 171 | "Read back done len %d\n", pLeader->PLength); |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 172 | if (!pLeader->PLength) { |
Matthias Beyer | f5c86ab | 2014-06-30 10:10:01 +0200 | [diff] [blame] | 173 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, |
| 174 | "Leader Length 0"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 175 | atomic_dec(&psIntfAdapter->uNumRcbUsed); |
| 176 | return; |
| 177 | } |
Matthias Beyer | f5c86ab | 2014-06-30 10:10:01 +0200 | [diff] [blame] | 178 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, |
| 179 | "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", |
| 180 | pLeader->Status, pLeader->PLength, pLeader->Vcid); |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 181 | if (MAX_CNTL_PKT_SIZE < pLeader->PLength) { |
Stephen Hemminger | 9ec4475 | 2010-11-01 12:18:36 -0400 | [diff] [blame] | 182 | if (netif_msg_rx_err(Adapter)) |
| 183 | pr_info(PFX "%s: corrupted leader length...%d\n", |
| 184 | Adapter->dev->name, pLeader->PLength); |
Stephen Hemminger | cacd922 | 2010-11-01 13:34:35 -0400 | [diff] [blame] | 185 | ++Adapter->dev->stats.rx_dropped; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 186 | atomic_dec(&psIntfAdapter->uNumRcbUsed); |
| 187 | return; |
| 188 | } |
| 189 | |
Matthias Oefelein | 7d774a5 | 2014-01-08 23:15:08 +0100 | [diff] [blame] | 190 | QueueIndex = SearchVcid(Adapter, pLeader->Vcid); |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 191 | if (QueueIndex < NO_OF_QUEUES) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 192 | bHeaderSupressionEnabled = |
| 193 | Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled; |
| 194 | bHeaderSupressionEnabled = |
| 195 | bHeaderSupressionEnabled & Adapter->bPHSEnabled; |
| 196 | } |
| 197 | |
Matthias Beyer | f5c86ab | 2014-06-30 10:10:01 +0200 | [diff] [blame] | 198 | skb = dev_alloc_skb(pLeader->PLength + SKB_RESERVE_PHS_BYTES + |
| 199 | SKB_RESERVE_ETHERNET_HEADER); |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 200 | if (!skb) { |
Matthias Beyer | f5c86ab | 2014-06-30 10:10:01 +0200 | [diff] [blame] | 201 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, |
| 202 | "NO SKBUFF!!! Dropping the Packet"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 203 | atomic_dec(&psIntfAdapter->uNumRcbUsed); |
| 204 | return; |
| 205 | } |
Matthias Oefelein | 26ac5b4 | 2014-01-08 23:15:07 +0100 | [diff] [blame] | 206 | /* If it is a control Packet, then call handle_bcm_packet ()*/ |
Matthias Oefelein | 7d774a5 | 2014-01-08 23:15:08 +0100 | [diff] [blame] | 207 | if ((ntohs(pLeader->Vcid) == VCID_CONTROL_PACKET) || |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 208 | (!(pLeader->Status >= 0x20 && pLeader->Status <= 0x3F))) { |
Matthias Beyer | c6346fa | 2014-06-30 10:10:02 +0200 | [diff] [blame] | 209 | handle_control_packet(psIntfAdapter, Adapter, pLeader, skb, |
| 210 | urb); |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 211 | } else { |
Matthias Beyer | 3a162b1 | 2014-06-30 10:10:03 +0200 | [diff] [blame] | 212 | format_eth_hdr_to_stack(psIntfAdapter, Adapter, pLeader, skb, |
| 213 | urb, uiIndex, QueueIndex, |
Matthias Beyer | 8139b8d | 2014-06-30 10:10:04 +0200 | [diff] [blame] | 214 | bHeaderSupressionEnabled); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 215 | } |
Matthias Oefelein | 26ac5b4 | 2014-01-08 23:15:07 +0100 | [diff] [blame] | 216 | Adapter->PrevNumRecvDescs++; |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 217 | pRcb->bUsed = false; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 218 | atomic_dec(&psIntfAdapter->uNumRcbUsed); |
| 219 | } |
| 220 | |
Matthias Beyer | f5c86ab | 2014-06-30 10:10:01 +0200 | [diff] [blame] | 221 | static int ReceiveRcb(struct bcm_interface_adapter *psIntfAdapter, |
| 222 | struct bcm_usb_rcb *pRcb) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 223 | { |
| 224 | struct urb *urb = pRcb->urb; |
| 225 | int retval = 0; |
| 226 | |
Matthias Beyer | f5c86ab | 2014-06-30 10:10:01 +0200 | [diff] [blame] | 227 | usb_fill_bulk_urb(urb, psIntfAdapter->udev, |
| 228 | usb_rcvbulkpipe(psIntfAdapter->udev, |
| 229 | psIntfAdapter->sBulkIn.bulk_in_endpointAddr), |
| 230 | urb->transfer_buffer, |
| 231 | BCM_USB_MAX_READ_LENGTH, |
| 232 | read_bulk_callback, pRcb); |
| 233 | |
Matthias Oefelein | 7d774a5 | 2014-01-08 23:15:08 +0100 | [diff] [blame] | 234 | if (false == psIntfAdapter->psAdapter->device_removed && |
| 235 | false == psIntfAdapter->psAdapter->bEndPointHalted && |
| 236 | false == psIntfAdapter->bSuspended && |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 237 | false == psIntfAdapter->bPreparingForBusSuspend) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 238 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 239 | if (retval) { |
Matthias Beyer | f5c86ab | 2014-06-30 10:10:01 +0200 | [diff] [blame] | 240 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, |
| 241 | RX_DPC, DBG_LVL_ALL, |
| 242 | "failed submitting read urb, error %d", |
| 243 | retval); |
Matthias Oefelein | 69cb4a8 | 2014-01-08 23:15:10 +0100 | [diff] [blame] | 244 | /* if this return value is because of pipe halt. need to clear this. */ |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 245 | if (retval == -EPIPE) { |
Matthias Oefelein | 1b42f1d | 2014-01-08 23:15:05 +0100 | [diff] [blame] | 246 | psIntfAdapter->psAdapter->bEndPointHalted = TRUE; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 247 | wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); |
| 248 | } |
| 249 | |
| 250 | } |
| 251 | } |
| 252 | return retval; |
| 253 | } |
| 254 | |
| 255 | /* |
| 256 | Function: InterfaceRx |
| 257 | |
Joe Perches | ceeb6fe | 2011-06-23 11:40:18 -0700 | [diff] [blame] | 258 | Description: This is the hardware specific Function for Receiving |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 259 | data packet/control packets from the device. |
| 260 | |
Kevin McKinney | 2979460 | 2012-05-26 12:05:12 -0400 | [diff] [blame] | 261 | Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 262 | |
| 263 | |
| 264 | |
| 265 | Return: TRUE - If Rx was successful. |
Lucas De Marchi | 25985ed | 2011-03-30 22:57:33 -0300 | [diff] [blame] | 266 | Other - If an error occurred. |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 267 | */ |
| 268 | |
Matthias Oefelein | 7d774a5 | 2014-01-08 23:15:08 +0100 | [diff] [blame] | 269 | bool InterfaceRx(struct bcm_interface_adapter *psIntfAdapter) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 270 | { |
Matthias Beyer | f5c86ab | 2014-06-30 10:10:01 +0200 | [diff] [blame] | 271 | USHORT RxDescCount = NUM_RX_DESC - |
| 272 | atomic_read(&psIntfAdapter->uNumRcbUsed); |
| 273 | |
Kevin McKinney | 71dd092 | 2012-11-01 23:42:22 -0400 | [diff] [blame] | 274 | struct bcm_usb_rcb *pRcb = NULL; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 275 | |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 276 | while (RxDescCount) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 277 | pRcb = GetBulkInRcb(psIntfAdapter); |
Matthias Oefelein | b0303a8 | 2014-01-08 23:15:09 +0100 | [diff] [blame] | 278 | if (pRcb == NULL) { |
Matthias Beyer | f5c86ab | 2014-06-30 10:10:01 +0200 | [diff] [blame] | 279 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, |
| 280 | DBG_TYPE_PRINTK, 0, 0, |
| 281 | "Unable to get Rcb pointer"); |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 282 | return false; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 283 | } |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 284 | ReceiveRcb(psIntfAdapter, pRcb); |
| 285 | RxDescCount--; |
Matthias Oefelein | 26ac5b4 | 2014-01-08 23:15:07 +0100 | [diff] [blame] | 286 | } |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 287 | return TRUE; |
| 288 | } |
| 289 | |