Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx
[linux-2.6] / drivers / staging / rt2870 / common / rtusb_data.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26
27         Module Name:
28         rtusb_data.c
29
30         Abstract:
31         Ralink USB driver Tx/Rx functions.
32
33         Revision History:
34         Who         When          What
35         --------    ----------    ----------------------------------------------
36         Jan            03-25-2006    created
37
38 */
39 #include "../rt_config.h"
40
41 extern  UCHAR Phy11BGNextRateUpward[]; // defined in mlme.c
42 extern UCHAR    EpToQueue[];
43
44 VOID REPORT_AMSDU_FRAMES_TO_LLC(
45         IN      PRTMP_ADAPTER   pAd,
46         IN      PUCHAR                  pData,
47         IN      ULONG                   DataSize)
48 {
49         PNDIS_PACKET    pPacket;
50         UINT                    nMSDU;
51         struct                  sk_buff *pSkb;
52
53         nMSDU = 0;
54         /* allocate a rx packet */
55         pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE);
56         pPacket = (PNDIS_PACKET)OSPKT_TO_RTPKT(pSkb);
57         if (pSkb)
58         {
59
60                 /* convert 802.11 to 802.3 packet */
61                 pSkb->dev = get_netdev_from_bssid(pAd, BSS0);
62                 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
63                 deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
64         }
65         else
66         {
67                 DBGPRINT(RT_DEBUG_ERROR,("Can't allocate skb\n"));
68         }
69 }
70
71 NDIS_STATUS     RTUSBFreeDescriptorRequest(
72         IN      PRTMP_ADAPTER   pAd,
73         IN      UCHAR                   BulkOutPipeId,
74         IN      UINT32                  NumberRequired)
75 {
76 //      UCHAR                   FreeNumber = 0;
77 //      UINT                    Index;
78         NDIS_STATUS             Status = NDIS_STATUS_FAILURE;
79         unsigned long   IrqFlags;
80         HT_TX_CONTEXT   *pHTTXContext;
81
82
83         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
84         RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
85         if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition) && ((pHTTXContext->CurWritePosition + NumberRequired + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition))
86         {
87
88                 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
89         }
90         else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < (NumberRequired + LOCAL_TXBUF_SIZE)))
91         {
92                 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
93         }
94         else if (pHTTXContext->bCurWriting == TRUE)
95         {
96                 DBGPRINT(RT_DEBUG_TRACE,("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n", BulkOutPipeId, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
97                 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
98         }
99         else
100         {
101                 Status = NDIS_STATUS_SUCCESS;
102         }
103         RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
104
105
106         return (Status);
107 }
108
109 NDIS_STATUS RTUSBFreeDescriptorRelease(
110         IN RTMP_ADAPTER *pAd,
111         IN UCHAR                BulkOutPipeId)
112 {
113         unsigned long   IrqFlags;
114         HT_TX_CONTEXT   *pHTTXContext;
115
116         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
117         RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
118         pHTTXContext->bCurWriting = FALSE;
119         RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
120
121         return (NDIS_STATUS_SUCCESS);
122 }
123
124
125 BOOLEAN RTUSBNeedQueueBackForAgg(
126         IN RTMP_ADAPTER *pAd,
127         IN UCHAR                BulkOutPipeId)
128 {
129         unsigned long   IrqFlags;
130         HT_TX_CONTEXT   *pHTTXContext;
131         BOOLEAN                 needQueBack = FALSE;
132
133         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
134
135         RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
136         if ((pHTTXContext->IRPPending == TRUE)  /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */)
137         {
138 #if 0
139                 if ((pHTTXContext->CurWritePosition <= 8) &&
140                         (pHTTXContext->NextBulkOutPosition > 8 && (pHTTXContext->NextBulkOutPosition+MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT))
141                 {
142                         needQueBack = TRUE;
143                 }
144                 else if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition) &&
145                                  ((pHTTXContext->NextBulkOutPosition + MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT))
146                 {
147                         needQueBack = TRUE;
148                 }
149 #else
150                 if ((pHTTXContext->CurWritePosition < pHTTXContext->ENextBulkOutPosition) &&
151                         (((pHTTXContext->ENextBulkOutPosition+MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT) || (pHTTXContext->CurWritePosition > MAX_AGGREGATION_SIZE)))
152                 {
153                         needQueBack = TRUE;
154                 }
155 #endif
156                 else if ((pHTTXContext->CurWritePosition > pHTTXContext->ENextBulkOutPosition) &&
157                                  ((pHTTXContext->ENextBulkOutPosition + MAX_AGGREGATION_SIZE) < pHTTXContext->CurWritePosition))
158                 {
159                         needQueBack = TRUE;
160                 }
161         }
162         RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
163
164         return needQueBack;
165
166 }
167
168
169 /*
170         ========================================================================
171
172         Routine Description:
173
174         Arguments:
175
176         Return Value:
177
178         IRQL =
179
180         Note:
181
182         ========================================================================
183 */
184 VOID    RTUSBRejectPendingPackets(
185         IN      PRTMP_ADAPTER   pAd)
186 {
187         UCHAR                   Index;
188         PQUEUE_ENTRY    pEntry;
189         PNDIS_PACKET    pPacket;
190         PQUEUE_HEADER   pQueue;
191
192
193         for (Index = 0; Index < 4; Index++)
194         {
195                 NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]);
196                 while (pAd->TxSwQueue[Index].Head != NULL)
197                 {
198                         pQueue = (PQUEUE_HEADER) &(pAd->TxSwQueue[Index]);
199                         pEntry = RemoveHeadQueue(pQueue);
200                         pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
201                         RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
202                 }
203                 NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]);
204
205         }
206
207 }
208
209 VOID RTMPWriteTxInfo(
210         IN      PRTMP_ADAPTER   pAd,
211         IN      PTXINFO_STRUC   pTxInfo,
212         IN        USHORT                USBDMApktLen,
213         IN        BOOLEAN               bWiv,
214         IN        UCHAR                 QueueSel,
215         IN        UCHAR                 NextValid,
216         IN        UCHAR                 TxBurst)
217 {
218         pTxInfo->USBDMATxPktLen = USBDMApktLen;
219         pTxInfo->QSEL = QueueSel;
220         if (QueueSel != FIFO_EDCA)
221                 DBGPRINT(RT_DEBUG_TRACE, ("====> QueueSel != FIFO_EDCA<============\n"));
222         pTxInfo->USBDMANextVLD = FALSE; //NextValid;  // Need to check with Jan about this.
223         pTxInfo->USBDMATxburst = TxBurst;
224         pTxInfo->WIV = bWiv;
225         pTxInfo->SwUseLastRound = 0;
226         pTxInfo->rsv = 0;
227         pTxInfo->rsv2 = 0;
228 }
229