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
REPORT_AMSDU_FRAMES_TO_LLC(struct rt_rtmp_adapter * pAd,u8 * pData,unsigned long DataSize)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 available 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 */
RTUSBFreeDescriptorRequest(struct rt_rtmp_adapter * pAd,u8 BulkOutPipeId,u32 NumberRequired)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
RTUSBFreeDescriptorRelease(struct rt_rtmp_adapter * pAd,u8 BulkOutPipeId)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
RTUSBNeedQueueBackForAgg(struct rt_rtmp_adapter * pAd,u8 BulkOutPipeId)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 */
RTUSBRejectPendingPackets(struct rt_rtmp_adapter * pAd)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
RTMPWriteTxInfo(struct rt_rtmp_adapter * pAd,struct rt_txinfo * pTxInfo,u16 USBDMApktLen,IN BOOLEAN bWiv,u8 QueueSel,u8 NextValid,u8 TxBurst)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 // */
263