Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh...
[pandora-kernel.git] / 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
40 #ifdef RTMP_MAC_USB
41
42 #include "../rt_config.h"
43
44 extern u8 Phy11BGNextRateUpward[];      /* defined in mlme.c */
45 extern u8 EpToQueue[];
46
47 void REPORT_AMSDU_FRAMES_TO_LLC(struct rt_rtmp_adapter *pAd,
48                                 u8 *pData, unsigned long DataSize)
49 {
50         void *pPacket;
51         u32 nMSDU;
52         struct sk_buff *pSkb;
53
54         nMSDU = 0;
55         /* allocate a rx packet */
56         pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE);
57         pPacket = (void *)OSPKT_TO_RTPKT(pSkb);
58         if (pSkb) {
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         } else {
65                 DBGPRINT(RT_DEBUG_ERROR, ("Can't allocate skb\n"));
66         }
67 }
68
69 /*
70         ========================================================================
71
72         Routine Description:
73                 This subroutine will scan through releative ring descriptor to find
74                 out avaliable free ring descriptor and compare with request size.
75
76         Arguments:
77                 pAd     Pointer to our adapter
78                 RingType        Selected Ring
79
80         Return Value:
81                 NDIS_STATUS_FAILURE             Not enough free descriptor
82                 NDIS_STATUS_SUCCESS             Enough free descriptor
83
84         Note:
85
86         ========================================================================
87 */
88 int RTUSBFreeDescriptorRequest(struct rt_rtmp_adapter *pAd,
89                                        u8 BulkOutPipeId,
90                                        u32 NumberRequired)
91 {
92 /*      u8                   FreeNumber = 0; */
93 /*      u32                    Index; */
94         int Status = NDIS_STATUS_FAILURE;
95         unsigned long IrqFlags;
96         struct rt_ht_tx_context *pHTTXContext;
97
98         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
99         RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
100         if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition)
101             &&
102             ((pHTTXContext->CurWritePosition + NumberRequired +
103               LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)) {
104
105                 RTUSB_SET_BULK_FLAG(pAd,
106                                     (fRTUSB_BULK_OUT_DATA_NORMAL <<
107                                      BulkOutPipeId));
108         } else if ((pHTTXContext->CurWritePosition == 8)
109                    && (pHTTXContext->NextBulkOutPosition <
110                        (NumberRequired + LOCAL_TXBUF_SIZE))) {
111                 RTUSB_SET_BULK_FLAG(pAd,
112                                     (fRTUSB_BULK_OUT_DATA_NORMAL <<
113                                      BulkOutPipeId));
114         } else if (pHTTXContext->bCurWriting == TRUE) {
115                 DBGPRINT(RT_DEBUG_TRACE,
116                          ("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n",
117                           BulkOutPipeId, pHTTXContext->CurWritePosition,
118                           pHTTXContext->NextBulkOutPosition));
119                 RTUSB_SET_BULK_FLAG(pAd,
120                                     (fRTUSB_BULK_OUT_DATA_NORMAL <<
121                                      BulkOutPipeId));
122         } else {
123                 Status = NDIS_STATUS_SUCCESS;
124         }
125         RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
126
127         return Status;
128 }
129
130 int RTUSBFreeDescriptorRelease(struct rt_rtmp_adapter *pAd,
131                                        u8 BulkOutPipeId)
132 {
133         unsigned long IrqFlags;
134         struct rt_ht_tx_context *pHTTXContext;
135
136         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
137         RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
138         pHTTXContext->bCurWriting = FALSE;
139         RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
140
141         return NDIS_STATUS_SUCCESS;
142 }
143
144 BOOLEAN RTUSBNeedQueueBackForAgg(struct rt_rtmp_adapter *pAd, u8 BulkOutPipeId)
145 {
146         unsigned long IrqFlags;
147         struct rt_ht_tx_context *pHTTXContext;
148         BOOLEAN needQueBack = FALSE;
149
150         pHTTXContext = &pAd->TxContext[BulkOutPipeId];
151
152         RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
153         if ((pHTTXContext->IRPPending ==
154              TRUE) /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */) {
155                 if ((pHTTXContext->CurWritePosition <
156                      pHTTXContext->ENextBulkOutPosition)
157                     &&
158                     (((pHTTXContext->ENextBulkOutPosition +
159                        MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT)
160                      || (pHTTXContext->CurWritePosition >
161                          MAX_AGGREGATION_SIZE))) {
162                         needQueBack = TRUE;
163                 } else
164                     if ((pHTTXContext->CurWritePosition >
165                          pHTTXContext->ENextBulkOutPosition)
166                         &&
167                         ((pHTTXContext->ENextBulkOutPosition +
168                           MAX_AGGREGATION_SIZE) <
169                          pHTTXContext->CurWritePosition)) {
170                         needQueBack = TRUE;
171                 }
172         }
173         RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
174
175         return needQueBack;
176
177 }
178
179 /*
180         ========================================================================
181
182         Routine Description:
183
184         Arguments:
185
186         Return Value:
187
188         IRQL =
189
190         Note:
191
192         ========================================================================
193 */
194 void RTUSBRejectPendingPackets(struct rt_rtmp_adapter *pAd)
195 {
196         u8 Index;
197         struct rt_queue_entry *pEntry;
198         void *pPacket;
199         struct rt_queue_header *pQueue;
200
201         for (Index = 0; Index < 4; Index++) {
202                 NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]);
203                 while (pAd->TxSwQueue[Index].Head != NULL) {
204                         pQueue = (struct rt_queue_header *)&(pAd->TxSwQueue[Index]);
205                         pEntry = RemoveHeadQueue(pQueue);
206                         pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
207                         RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
208                 }
209                 NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]);
210
211         }
212
213 }
214
215 /*
216         ========================================================================
217
218         Routine Description:
219                 Calculates the duration which is required to transmit out frames
220         with given size and specified rate.
221
222         Arguments:
223                 pTxD            Pointer to transmit descriptor
224                 Ack                     Setting for Ack requirement bit
225                 Fragment        Setting for Fragment bit
226                 RetryMode       Setting for retry mode
227                 Ifs                     Setting for IFS gap
228                 Rate            Setting for transmit rate
229                 Service         Setting for service
230                 Length          Frame length
231                 TxPreamble  Short or Long preamble when using CCK rates
232                 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
233
234         Return Value:
235                 None
236
237         IRQL = PASSIVE_LEVEL
238         IRQL = DISPATCH_LEVEL
239
240         ========================================================================
241 */
242
243 void RTMPWriteTxInfo(struct rt_rtmp_adapter *pAd,
244                      struct rt_txinfo *pTxInfo,
245                      u16 USBDMApktLen,
246                      IN BOOLEAN bWiv,
247                      u8 QueueSel, u8 NextValid, u8 TxBurst)
248 {
249         pTxInfo->USBDMATxPktLen = USBDMApktLen;
250         pTxInfo->QSEL = QueueSel;
251         if (QueueSel != FIFO_EDCA)
252                 DBGPRINT(RT_DEBUG_TRACE,
253                          ("====> QueueSel != FIFO_EDCA<============\n"));
254         pTxInfo->USBDMANextVLD = FALSE; /*NextValid;  // Need to check with Jan about this. */
255         pTxInfo->USBDMATxburst = TxBurst;
256         pTxInfo->WIV = bWiv;
257         pTxInfo->SwUseLastRound = 0;
258         pTxInfo->rsv = 0;
259         pTxInfo->rsv2 = 0;
260 }
261
262 #endif /* RTMP_MAC_USB // */