ALSA: hda - Add static_hdmi_pcm option to HDMI codec parser
[linux-2.6/next.git] / drivers / staging / bcm / InterfaceRx.c
blob6fee9684f2efd7805aa0aa94635ad76e8fd6f2b8
1 #include "headers.h"
2 extern int SearchVcid(PMINI_ADAPTER , unsigned short);
5 static PUSB_RCB
6 GetBulkInRcb(PS_INTERFACE_ADAPTER psIntfAdapter)
8 PUSB_RCB pRcb = NULL;
9 UINT index = 0;
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];
16 pRcb->bUsed = TRUE;
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);
24 return pRcb;
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;
33 UINT uiIndex=0;
34 int process_done = 1;
35 //int idleflag = 0 ;
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;
42 #if 0
43 int *puiBuffer = NULL;
44 struct timeval tv;
45 memset(&tv, 0, sizeof(tv));
46 do_gettimeofday(&tv);
47 #endif
49 if((Adapter->device_removed == TRUE) ||
50 (TRUE == Adapter->bEndPointHalted) ||
51 (0 == urb->actual_length)
54 pRcb->bUsed = FALSE;
55 atomic_dec(&psIntfAdapter->uNumRcbUsed);
56 return;
59 if(urb->status != STATUS_SUCCESS)
61 if(urb->status == -EPIPE)
63 Adapter->bEndPointHalted = TRUE ;
64 wake_up(&Adapter->tx_packet_wait_queue);
66 else
68 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"Rx URB has got cancelled. status :%d", urb->status);
70 pRcb->bUsed = FALSE;
71 atomic_dec(&psIntfAdapter->uNumRcbUsed);
72 urb->status = STATUS_SUCCESS ;
73 return ;
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");
79 return ;
82 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Read back done len %d\n", pLeader->PLength);
83 if(!pLeader->PLength)
85 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Length 0");
86 atomic_dec(&psIntfAdapter->uNumRcbUsed);
87 return;
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",
93 pLeader->PLength);
94 atomic_inc(&Adapter->RxPacketDroppedCount);
95 atomic_add(pLeader->PLength, &Adapter->BadRxByteCount);
96 atomic_dec(&psIntfAdapter->uNumRcbUsed);
97 return;
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
110 if(!skb)
112 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "NO SKBUFF!!! Dropping the Packet");
113 atomic_dec(&psIntfAdapter->uNumRcbUsed);
114 return;
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);
133 else
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);
151 if(Adapter->if_up)
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);
164 (*(skb->data+11))++;
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);
173 else
175 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB...");
176 bcm_kfree_skb(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++;
187 pRcb->bUsed = FALSE;
188 atomic_dec(&psIntfAdapter->uNumRcbUsed);
191 static int ReceiveRcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_RCB pRcb)
193 struct urb *urb = pRcb->urb;
194 int retval = 0;
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,
199 pRcb);
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);
206 if (retval)
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.
210 if(retval == -EPIPE)
212 psIntfAdapter->psAdapter->bEndPointHalted = TRUE ;
213 wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
218 return retval;
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;
242 while(RxDescCount)
244 pRcb = GetBulkInRcb(psIntfAdapter);
245 if(pRcb == NULL)
247 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Unable to get Rcb pointer");
248 return FALSE;
250 //atomic_inc(&psIntfAdapter->uNumRcbUsed);
251 ReceiveRcb(psIntfAdapter, pRcb);
252 RxDescCount--;
254 return TRUE;