Commit | Line | Data |
---|---|---|
c55519ff GKH |
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 | */ | |
ca97b838 BZ |
39 | |
40 | #ifdef RTMP_MAC_USB | |
41 | ||
c55519ff GKH |
42 | #include "../rt_config.h" |
43 | ||
51126deb BZ |
44 | extern u8 Phy11BGNextRateUpward[]; /* defined in mlme.c */ |
45 | extern u8 EpToQueue[]; | |
c55519ff | 46 | |
62eb734b | 47 | void REPORT_AMSDU_FRAMES_TO_LLC(struct rt_rtmp_adapter *pAd, |
51126deb | 48 | u8 *pData, unsigned long DataSize) |
c55519ff | 49 | { |
8a10a546 | 50 | void *pPacket; |
51126deb | 51 | u32 nMSDU; |
66cd8d6e | 52 | struct sk_buff *pSkb; |
c55519ff GKH |
53 | |
54 | nMSDU = 0; | |
55 | /* allocate a rx packet */ | |
56 | pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE); | |
8a10a546 | 57 | pPacket = (void *)OSPKT_TO_RTPKT(pSkb); |
66cd8d6e | 58 | if (pSkb) { |
c55519ff GKH |
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); | |
66cd8d6e BZ |
64 | } else { |
65 | DBGPRINT(RT_DEBUG_ERROR, ("Can't allocate skb\n")); | |
c55519ff GKH |
66 | } |
67 | } | |
68 | ||
ca97b838 BZ |
69 | /* |
70 | ======================================================================== | |
71 | ||
72 | Routine Description: | |
73 | This subroutine will scan through releative ring descriptor to find | |
25985edc | 74 | out available free ring descriptor and compare with request size. |
ca97b838 BZ |
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 | */ | |
62eb734b | 88 | int RTUSBFreeDescriptorRequest(struct rt_rtmp_adapter *pAd, |
51126deb BZ |
89 | u8 BulkOutPipeId, |
90 | u32 NumberRequired) | |
c55519ff | 91 | { |
51126deb BZ |
92 | /* u8 FreeNumber = 0; */ |
93 | /* u32 Index; */ | |
94 | int Status = NDIS_STATUS_FAILURE; | |
66cd8d6e | 95 | unsigned long IrqFlags; |
62eb734b | 96 | struct rt_ht_tx_context *pHTTXContext; |
c55519ff GKH |
97 | |
98 | pHTTXContext = &pAd->TxContext[BulkOutPipeId]; | |
99 | RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); | |
66cd8d6e BZ |
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 { | |
c55519ff GKH |
123 | Status = NDIS_STATUS_SUCCESS; |
124 | } | |
125 | RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); | |
126 | ||
f681d552 | 127 | return Status; |
c55519ff GKH |
128 | } |
129 | ||
62eb734b | 130 | int RTUSBFreeDescriptorRelease(struct rt_rtmp_adapter *pAd, |
51126deb | 131 | u8 BulkOutPipeId) |
c55519ff | 132 | { |
66cd8d6e | 133 | unsigned long IrqFlags; |
62eb734b | 134 | struct rt_ht_tx_context *pHTTXContext; |
c55519ff GKH |
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 | ||
f681d552 | 141 | return NDIS_STATUS_SUCCESS; |
c55519ff GKH |
142 | } |
143 | ||
62eb734b | 144 | BOOLEAN RTUSBNeedQueueBackForAgg(struct rt_rtmp_adapter *pAd, u8 BulkOutPipeId) |
c55519ff | 145 | { |
66cd8d6e | 146 | unsigned long IrqFlags; |
62eb734b | 147 | struct rt_ht_tx_context *pHTTXContext; |
66cd8d6e | 148 | BOOLEAN needQueBack = FALSE; |
c55519ff GKH |
149 | |
150 | pHTTXContext = &pAd->TxContext[BulkOutPipeId]; | |
151 | ||
152 | RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); | |
66cd8d6e | 153 | if ((pHTTXContext->IRPPending == |
f681d552 | 154 | TRUE) /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */) { |
66cd8d6e BZ |
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))) { | |
c55519ff | 162 | needQueBack = TRUE; |
66cd8d6e BZ |
163 | } else |
164 | if ((pHTTXContext->CurWritePosition > | |
165 | pHTTXContext->ENextBulkOutPosition) | |
166 | && | |
167 | ((pHTTXContext->ENextBulkOutPosition + | |
168 | MAX_AGGREGATION_SIZE) < | |
169 | pHTTXContext->CurWritePosition)) { | |
c55519ff GKH |
170 | needQueBack = TRUE; |
171 | } | |
172 | } | |
173 | RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); | |
174 | ||
175 | return needQueBack; | |
176 | ||
177 | } | |
178 | ||
c55519ff GKH |
179 | /* |
180 | ======================================================================== | |
181 | ||
182 | Routine Description: | |
183 | ||
184 | Arguments: | |
185 | ||
186 | Return Value: | |
187 | ||
188 | IRQL = | |
189 | ||
190 | Note: | |
191 | ||
192 | ======================================================================== | |
193 | */ | |
62eb734b | 194 | void RTUSBRejectPendingPackets(struct rt_rtmp_adapter *pAd) |
c55519ff | 195 | { |
51126deb | 196 | u8 Index; |
62eb734b | 197 | struct rt_queue_entry *pEntry; |
8a10a546 | 198 | void *pPacket; |
62eb734b | 199 | struct rt_queue_header *pQueue; |
c55519ff | 200 | |
66cd8d6e | 201 | for (Index = 0; Index < 4; Index++) { |
c55519ff | 202 | NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]); |
66cd8d6e | 203 | while (pAd->TxSwQueue[Index].Head != NULL) { |
f681d552 | 204 | pQueue = (struct rt_queue_header *)&(pAd->TxSwQueue[Index]); |
c55519ff GKH |
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 | ||
ca97b838 BZ |
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 | ||
62eb734b BZ |
243 | void RTMPWriteTxInfo(struct rt_rtmp_adapter *pAd, |
244 | struct rt_txinfo *pTxInfo, | |
51126deb | 245 | u16 USBDMApktLen, |
66cd8d6e | 246 | IN BOOLEAN bWiv, |
51126deb | 247 | u8 QueueSel, u8 NextValid, u8 TxBurst) |
c55519ff GKH |
248 | { |
249 | pTxInfo->USBDMATxPktLen = USBDMApktLen; | |
250 | pTxInfo->QSEL = QueueSel; | |
251 | if (QueueSel != FIFO_EDCA) | |
66cd8d6e BZ |
252 | DBGPRINT(RT_DEBUG_TRACE, |
253 | ("====> QueueSel != FIFO_EDCA<============\n")); | |
9f548a2a | 254 | pTxInfo->USBDMANextVLD = FALSE; /*NextValid; // Need to check with Jan about this. */ |
c55519ff GKH |
255 | pTxInfo->USBDMATxburst = TxBurst; |
256 | pTxInfo->WIV = bWiv; | |
257 | pTxInfo->SwUseLastRound = 0; | |
258 | pTxInfo->rsv = 0; | |
259 | pTxInfo->rsv2 = 0; | |
260 | } | |
261 | ||
9f548a2a | 262 | #endif /* RTMP_MAC_USB // */ |