diff options
Diffstat (limited to 'drivers/staging/rt3070/common/action.c')
-rw-r--r-- | drivers/staging/rt3070/common/action.c | 1038 |
1 files changed, 1038 insertions, 0 deletions
diff --git a/drivers/staging/rt3070/common/action.c b/drivers/staging/rt3070/common/action.c new file mode 100644 index 00000000000..b8ae5363366 --- /dev/null +++ b/drivers/staging/rt3070/common/action.c | |||
@@ -0,0 +1,1038 @@ | |||
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 | action.c | ||
29 | |||
30 | Abstract: | ||
31 | Handle association related requests either from WSTA or from local MLME | ||
32 | |||
33 | Revision History: | ||
34 | Who When What | ||
35 | -------- ---------- ---------------------------------------------- | ||
36 | Jan Lee 2006 created for rt2860 | ||
37 | */ | ||
38 | |||
39 | #include "../rt_config.h" | ||
40 | #include "../action.h" | ||
41 | |||
42 | |||
43 | static VOID ReservedAction( | ||
44 | IN PRTMP_ADAPTER pAd, | ||
45 | IN MLME_QUEUE_ELEM *Elem); | ||
46 | |||
47 | /* | ||
48 | ========================================================================== | ||
49 | Description: | ||
50 | association state machine init, including state transition and timer init | ||
51 | Parameters: | ||
52 | S - pointer to the association state machine | ||
53 | Note: | ||
54 | The state machine looks like the following | ||
55 | |||
56 | ASSOC_IDLE | ||
57 | MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action | ||
58 | MT2_PEER_DISASSOC_REQ peer_disassoc_action | ||
59 | MT2_PEER_ASSOC_REQ drop | ||
60 | MT2_PEER_REASSOC_REQ drop | ||
61 | MT2_CLS3ERR cls3err_action | ||
62 | ========================================================================== | ||
63 | */ | ||
64 | VOID ActionStateMachineInit( | ||
65 | IN PRTMP_ADAPTER pAd, | ||
66 | IN STATE_MACHINE *S, | ||
67 | OUT STATE_MACHINE_FUNC Trans[]) | ||
68 | { | ||
69 | StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_ACT_STATE, MAX_ACT_MSG, (STATE_MACHINE_FUNC)Drop, ACT_IDLE, ACT_MACHINE_BASE); | ||
70 | |||
71 | StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, (STATE_MACHINE_FUNC)PeerSpectrumAction); | ||
72 | StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, (STATE_MACHINE_FUNC)PeerQOSAction); | ||
73 | |||
74 | StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)ReservedAction); | ||
75 | #ifdef QOS_DLS_SUPPORT | ||
76 | StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)PeerDLSAction); | ||
77 | #endif // QOS_DLS_SUPPORT // | ||
78 | |||
79 | #ifdef DOT11_N_SUPPORT | ||
80 | StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, (STATE_MACHINE_FUNC)PeerBAAction); | ||
81 | StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, (STATE_MACHINE_FUNC)PeerHTAction); | ||
82 | StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, (STATE_MACHINE_FUNC)MlmeADDBAAction); | ||
83 | StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction); | ||
84 | StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction); | ||
85 | #endif // DOT11_N_SUPPORT // | ||
86 | |||
87 | StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, (STATE_MACHINE_FUNC)PeerPublicAction); | ||
88 | StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, (STATE_MACHINE_FUNC)PeerRMAction); | ||
89 | |||
90 | StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, (STATE_MACHINE_FUNC)MlmeQOSAction); | ||
91 | StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, (STATE_MACHINE_FUNC)MlmeDLSAction); | ||
92 | StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, (STATE_MACHINE_FUNC)MlmeInvalidAction); | ||
93 | } | ||
94 | |||
95 | #ifdef DOT11_N_SUPPORT | ||
96 | VOID MlmeADDBAAction( | ||
97 | IN PRTMP_ADAPTER pAd, | ||
98 | IN MLME_QUEUE_ELEM *Elem) | ||
99 | |||
100 | { | ||
101 | MLME_ADDBA_REQ_STRUCT *pInfo; | ||
102 | UCHAR Addr[6]; | ||
103 | PUCHAR pOutBuffer = NULL; | ||
104 | NDIS_STATUS NStatus; | ||
105 | ULONG Idx; | ||
106 | FRAME_ADDBA_REQ Frame; | ||
107 | ULONG FrameLen; | ||
108 | BA_ORI_ENTRY *pBAEntry = NULL; | ||
109 | |||
110 | pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg; | ||
111 | NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ)); | ||
112 | |||
113 | if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr)) | ||
114 | { | ||
115 | NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory | ||
116 | if(NStatus != NDIS_STATUS_SUCCESS) | ||
117 | { | ||
118 | DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n")); | ||
119 | return; | ||
120 | } | ||
121 | // 1. find entry | ||
122 | Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID]; | ||
123 | if (Idx == 0) | ||
124 | { | ||
125 | MlmeFreeMemory(pAd, pOutBuffer); | ||
126 | DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n")); | ||
127 | return; | ||
128 | } | ||
129 | else | ||
130 | { | ||
131 | pBAEntry =&pAd->BATable.BAOriEntry[Idx]; | ||
132 | } | ||
133 | |||
134 | #ifdef CONFIG_STA_SUPPORT | ||
135 | IF_DEV_CONFIG_OPMODE_ON_STA(pAd) | ||
136 | { | ||
137 | if (ADHOC_ON(pAd)) | ||
138 | ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); | ||
139 | else | ||
140 | ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr); | ||
141 | |||
142 | } | ||
143 | #endif // CONFIG_STA_SUPPORT // | ||
144 | |||
145 | Frame.Category = CATEGORY_BA; | ||
146 | Frame.Action = ADDBA_REQ; | ||
147 | Frame.BaParm.AMSDUSupported = 0; | ||
148 | Frame.BaParm.BAPolicy = IMMED_BA; | ||
149 | Frame.BaParm.TID = pInfo->TID; | ||
150 | Frame.BaParm.BufSize = pInfo->BaBufSize; | ||
151 | Frame.Token = pInfo->Token; | ||
152 | Frame.TimeOutValue = pInfo->TimeOutValue; | ||
153 | Frame.BaStartSeq.field.FragNum = 0; | ||
154 | Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; | ||
155 | |||
156 | *(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm)); | ||
157 | Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue); | ||
158 | Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word); | ||
159 | |||
160 | MakeOutgoingFrame(pOutBuffer, &FrameLen, | ||
161 | sizeof(FRAME_ADDBA_REQ), &Frame, | ||
162 | END_OF_ARGS); | ||
163 | MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); | ||
164 | //MiniportDataMMRequest(pAd, MapUserPriorityToAccessCategory[pInfo->TID], pOutBuffer, FrameLen); | ||
165 | MlmeFreeMemory(pAd, pOutBuffer); | ||
166 | |||
167 | DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize)); | ||
168 | } | ||
169 | } | ||
170 | |||
171 | /* | ||
172 | ========================================================================== | ||
173 | Description: | ||
174 | send DELBA and delete BaEntry if any | ||
175 | Parametrs: | ||
176 | Elem - MLME message MLME_DELBA_REQ_STRUCT | ||
177 | |||
178 | IRQL = DISPATCH_LEVEL | ||
179 | |||
180 | ========================================================================== | ||
181 | */ | ||
182 | VOID MlmeDELBAAction( | ||
183 | IN PRTMP_ADAPTER pAd, | ||
184 | IN MLME_QUEUE_ELEM *Elem) | ||
185 | { | ||
186 | MLME_DELBA_REQ_STRUCT *pInfo; | ||
187 | PUCHAR pOutBuffer = NULL; | ||
188 | PUCHAR pOutBuffer2 = NULL; | ||
189 | NDIS_STATUS NStatus; | ||
190 | ULONG Idx; | ||
191 | FRAME_DELBA_REQ Frame; | ||
192 | ULONG FrameLen; | ||
193 | FRAME_BAR FrameBar; | ||
194 | |||
195 | pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg; | ||
196 | // must send back DELBA | ||
197 | NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ)); | ||
198 | DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator)); | ||
199 | |||
200 | if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen)) | ||
201 | { | ||
202 | NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory | ||
203 | if(NStatus != NDIS_STATUS_SUCCESS) | ||
204 | { | ||
205 | DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n")); | ||
206 | return; | ||
207 | } | ||
208 | |||
209 | NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory | ||
210 | if(NStatus != NDIS_STATUS_SUCCESS) | ||
211 | { | ||
212 | MlmeFreeMemory(pAd, pOutBuffer); | ||
213 | DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n")); | ||
214 | return; | ||
215 | } | ||
216 | |||
217 | // SEND BAR (Send BAR to refresh peer reordering buffer.) | ||
218 | Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID]; | ||
219 | |||
220 | #ifdef CONFIG_STA_SUPPORT | ||
221 | IF_DEV_CONFIG_OPMODE_ON_STA(pAd) | ||
222 | BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress); | ||
223 | #endif // CONFIG_STA_SUPPORT // | ||
224 | |||
225 | FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL funciton. | ||
226 | FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; // make sure sequence not clear in DEL funciton. | ||
227 | FrameBar.BarControl.TID = pInfo->TID; // make sure sequence not clear in DEL funciton. | ||
228 | FrameBar.BarControl.ACKPolicy = IMMED_BA; // make sure sequence not clear in DEL funciton. | ||
229 | FrameBar.BarControl.Compressed = 1; // make sure sequence not clear in DEL funciton. | ||
230 | FrameBar.BarControl.MTID = 0; // make sure sequence not clear in DEL funciton. | ||
231 | |||
232 | MakeOutgoingFrame(pOutBuffer2, &FrameLen, | ||
233 | sizeof(FRAME_BAR), &FrameBar, | ||
234 | END_OF_ARGS); | ||
235 | MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen); | ||
236 | MlmeFreeMemory(pAd, pOutBuffer2); | ||
237 | DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n")); | ||
238 | |||
239 | // SEND DELBA FRAME | ||
240 | FrameLen = 0; | ||
241 | #ifdef CONFIG_STA_SUPPORT | ||
242 | IF_DEV_CONFIG_OPMODE_ON_STA(pAd) | ||
243 | { | ||
244 | if (ADHOC_ON(pAd)) | ||
245 | ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); | ||
246 | else | ||
247 | ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr); | ||
248 | } | ||
249 | #endif // CONFIG_STA_SUPPORT // | ||
250 | Frame.Category = CATEGORY_BA; | ||
251 | Frame.Action = DELBA; | ||
252 | Frame.DelbaParm.Initiator = pInfo->Initiator; | ||
253 | Frame.DelbaParm.TID = pInfo->TID; | ||
254 | Frame.ReasonCode = 39; // Time Out | ||
255 | *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm)); | ||
256 | Frame.ReasonCode = cpu2le16(Frame.ReasonCode); | ||
257 | |||
258 | MakeOutgoingFrame(pOutBuffer, &FrameLen, | ||
259 | sizeof(FRAME_DELBA_REQ), &Frame, | ||
260 | END_OF_ARGS); | ||
261 | MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); | ||
262 | MlmeFreeMemory(pAd, pOutBuffer); | ||
263 | DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator)); | ||
264 | } | ||
265 | } | ||
266 | #endif // DOT11_N_SUPPORT // | ||
267 | |||
268 | VOID MlmeQOSAction( | ||
269 | IN PRTMP_ADAPTER pAd, | ||
270 | IN MLME_QUEUE_ELEM *Elem) | ||
271 | { | ||
272 | } | ||
273 | |||
274 | VOID MlmeDLSAction( | ||
275 | IN PRTMP_ADAPTER pAd, | ||
276 | IN MLME_QUEUE_ELEM *Elem) | ||
277 | { | ||
278 | } | ||
279 | |||
280 | VOID MlmeInvalidAction( | ||
281 | IN PRTMP_ADAPTER pAd, | ||
282 | IN MLME_QUEUE_ELEM *Elem) | ||
283 | { | ||
284 | //PUCHAR pOutBuffer = NULL; | ||
285 | //Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11 | ||
286 | } | ||
287 | |||
288 | VOID PeerQOSAction( | ||
289 | IN PRTMP_ADAPTER pAd, | ||
290 | IN MLME_QUEUE_ELEM *Elem) | ||
291 | { | ||
292 | } | ||
293 | |||
294 | #ifdef QOS_DLS_SUPPORT | ||
295 | VOID PeerDLSAction( | ||
296 | IN PRTMP_ADAPTER pAd, | ||
297 | IN MLME_QUEUE_ELEM *Elem) | ||
298 | { | ||
299 | UCHAR Action = Elem->Msg[LENGTH_802_11+1]; | ||
300 | |||
301 | switch(Action) | ||
302 | { | ||
303 | case ACTION_DLS_REQUEST: | ||
304 | #ifdef CONFIG_STA_SUPPORT | ||
305 | IF_DEV_CONFIG_OPMODE_ON_STA(pAd) | ||
306 | PeerDlsReqAction(pAd, Elem); | ||
307 | #endif // CONFIG_STA_SUPPORT // | ||
308 | break; | ||
309 | |||
310 | case ACTION_DLS_RESPONSE: | ||
311 | #ifdef CONFIG_STA_SUPPORT | ||
312 | IF_DEV_CONFIG_OPMODE_ON_STA(pAd) | ||
313 | PeerDlsRspAction(pAd, Elem); | ||
314 | #endif // CONFIG_STA_SUPPORT // | ||
315 | break; | ||
316 | |||
317 | case ACTION_DLS_TEARDOWN: | ||
318 | #ifdef CONFIG_STA_SUPPORT | ||
319 | IF_DEV_CONFIG_OPMODE_ON_STA(pAd) | ||
320 | PeerDlsTearDownAction(pAd, Elem); | ||
321 | #endif // CONFIG_STA_SUPPORT // | ||
322 | break; | ||
323 | } | ||
324 | } | ||
325 | #endif // QOS_DLS_SUPPORT // | ||
326 | |||
327 | #ifdef DOT11_N_SUPPORT | ||
328 | VOID PeerBAAction( | ||
329 | IN PRTMP_ADAPTER pAd, | ||
330 | IN MLME_QUEUE_ELEM *Elem) | ||
331 | { | ||
332 | UCHAR Action = Elem->Msg[LENGTH_802_11+1]; | ||
333 | |||
334 | switch(Action) | ||
335 | { | ||
336 | case ADDBA_REQ: | ||
337 | PeerAddBAReqAction(pAd,Elem); | ||
338 | break; | ||
339 | case ADDBA_RESP: | ||
340 | PeerAddBARspAction(pAd,Elem); | ||
341 | break; | ||
342 | case DELBA: | ||
343 | PeerDelBAAction(pAd,Elem); | ||
344 | break; | ||
345 | } | ||
346 | } | ||
347 | |||
348 | |||
349 | #ifdef DOT11N_DRAFT3 | ||
350 | |||
351 | #ifdef CONFIG_STA_SUPPORT | ||
352 | VOID StaPublicAction( | ||
353 | IN PRTMP_ADAPTER pAd, | ||
354 | IN UCHAR Bss2040Coexist) | ||
355 | { | ||
356 | BSS_2040_COEXIST_IE BssCoexist; | ||
357 | MLME_SCAN_REQ_STRUCT ScanReq; | ||
358 | |||
359 | BssCoexist.word = Bss2040Coexist; | ||
360 | // AP asks Station to return a 20/40 BSS Coexistence mgmt frame. So we first starts a scan, then send back 20/40 BSS Coexistence mgmt frame | ||
361 | if ((BssCoexist.field.InfoReq == 1) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040))) | ||
362 | { | ||
363 | // Clear record first. After scan , will update those bit and send back to transmiter. | ||
364 | pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1; | ||
365 | pAd->CommonCfg.BSSCoexist2040.field.Intolerant40 = 0; | ||
366 | pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 0; | ||
367 | // Fill out stuff for scan request | ||
368 | ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST); | ||
369 | MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq); | ||
370 | pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; | ||
371 | } | ||
372 | } | ||
373 | |||
374 | |||
375 | /* | ||
376 | Description : Build Intolerant Channel Rerpot from Trigger event table. | ||
377 | return : how many bytes copied. | ||
378 | */ | ||
379 | ULONG BuildIntolerantChannelRep( | ||
380 | IN PRTMP_ADAPTER pAd, | ||
381 | IN PUCHAR pDest) | ||
382 | { | ||
383 | ULONG FrameLen = 0; | ||
384 | ULONG ReadOffset = 0; | ||
385 | UCHAR i; | ||
386 | UCHAR LastRegClass = 0xff; | ||
387 | PUCHAR pLen; | ||
388 | |||
389 | for ( i = 0;i < MAX_TRIGGER_EVENT;i++) | ||
390 | { | ||
391 | if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid == TRUE) | ||
392 | { | ||
393 | if (pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass == LastRegClass) | ||
394 | { | ||
395 | *(pDest + ReadOffset) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel; | ||
396 | *pLen++; | ||
397 | ReadOffset++; | ||
398 | FrameLen++; | ||
399 | } | ||
400 | else | ||
401 | { | ||
402 | *(pDest + ReadOffset) = IE_2040_BSS_INTOLERANT_REPORT; // IE | ||
403 | *(pDest + ReadOffset + 1) = 2; // Len = RegClass byte + channel byte. | ||
404 | pLen = pDest + ReadOffset + 1; | ||
405 | LastRegClass = pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass; | ||
406 | *(pDest + ReadOffset + 2) = LastRegClass; // Len = RegClass byte + channel byte. | ||
407 | *(pDest + ReadOffset + 3) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel; | ||
408 | FrameLen += 4; | ||
409 | ReadOffset += 4; | ||
410 | } | ||
411 | |||
412 | } | ||
413 | } | ||
414 | return FrameLen; | ||
415 | } | ||
416 | |||
417 | |||
418 | /* | ||
419 | Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered. | ||
420 | */ | ||
421 | VOID Send2040CoexistAction( | ||
422 | IN PRTMP_ADAPTER pAd, | ||
423 | IN UCHAR Wcid, | ||
424 | IN BOOLEAN bAddIntolerantCha) | ||
425 | { | ||
426 | PUCHAR pOutBuffer = NULL; | ||
427 | NDIS_STATUS NStatus; | ||
428 | FRAME_ACTION_HDR Frame; | ||
429 | ULONG FrameLen; | ||
430 | ULONG IntolerantChaRepLen; | ||
431 | |||
432 | IntolerantChaRepLen = 0; | ||
433 | NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory | ||
434 | if(NStatus != NDIS_STATUS_SUCCESS) | ||
435 | { | ||
436 | DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n")); | ||
437 | return; | ||
438 | } | ||
439 | ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->CommonCfg.Bssid); | ||
440 | Frame.Category = CATEGORY_PUBLIC; | ||
441 | Frame.Action = ACTION_BSS_2040_COEXIST; | ||
442 | |||
443 | MakeOutgoingFrame(pOutBuffer, &FrameLen, | ||
444 | sizeof(FRAME_ACTION_HDR), &Frame, | ||
445 | END_OF_ARGS); | ||
446 | |||
447 | *(pOutBuffer + FrameLen) = pAd->CommonCfg.BSSCoexist2040.word; | ||
448 | FrameLen++; | ||
449 | |||
450 | if (bAddIntolerantCha == TRUE) | ||
451 | IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen); | ||
452 | |||
453 | MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen); | ||
454 | DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x ) \n", pAd->CommonCfg.BSSCoexist2040.word)); | ||
455 | |||
456 | } | ||
457 | |||
458 | |||
459 | /* | ||
460 | ========================================================================== | ||
461 | Description: | ||
462 | After scan, Update 20/40 BSS Coexistence IE and send out. | ||
463 | According to 802.11n D3.03 11.14.10 | ||
464 | |||
465 | Parameters: | ||
466 | ========================================================================== | ||
467 | */ | ||
468 | VOID Update2040CoexistFrameAndNotify( | ||
469 | IN PRTMP_ADAPTER pAd, | ||
470 | IN UCHAR Wcid, | ||
471 | IN BOOLEAN bAddIntolerantCha) | ||
472 | { | ||
473 | BSS_2040_COEXIST_IE OldValue; | ||
474 | |||
475 | OldValue.word = pAd->CommonCfg.BSSCoexist2040.word; | ||
476 | if ((pAd->CommonCfg.TriggerEventTab.EventANo > 0) || (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0)) | ||
477 | pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 1; | ||
478 | |||
479 | // Need to check !!!! | ||
480 | // How STA will set Intolerant40 if implementation dependent. Now we don't set this bit first.!!!!! | ||
481 | // So Only check BSS20WidthReq change. | ||
482 | if (OldValue.field.BSS20WidthReq != pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq) | ||
483 | { | ||
484 | Send2040CoexistAction(pAd, Wcid, bAddIntolerantCha); | ||
485 | } | ||
486 | } | ||
487 | #endif // CONFIG_STA_SUPPORT // | ||
488 | |||
489 | |||
490 | BOOLEAN ChannelSwitchSanityCheck( | ||
491 | IN PRTMP_ADAPTER pAd, | ||
492 | IN UCHAR Wcid, | ||
493 | IN UCHAR NewChannel, | ||
494 | IN UCHAR Secondary) | ||
495 | { | ||
496 | UCHAR i; | ||
497 | |||
498 | if (Wcid >= MAX_LEN_OF_MAC_TABLE) | ||
499 | return FALSE; | ||
500 | |||
501 | if ((NewChannel > 7) && (Secondary == 1)) | ||
502 | return FALSE; | ||
503 | |||
504 | if ((NewChannel < 5) && (Secondary == 3)) | ||
505 | return FALSE; | ||
506 | |||
507 | // 0. Check if new channel is in the channellist. | ||
508 | for (i = 0;i < pAd->ChannelListNum;i++) | ||
509 | { | ||
510 | if (pAd->ChannelList[i].Channel == NewChannel) | ||
511 | { | ||
512 | break; | ||
513 | } | ||
514 | } | ||
515 | |||
516 | if (i == pAd->ChannelListNum) | ||
517 | return FALSE; | ||
518 | |||
519 | return TRUE; | ||
520 | } | ||
521 | |||
522 | |||
523 | VOID ChannelSwitchAction( | ||
524 | IN PRTMP_ADAPTER pAd, | ||
525 | IN UCHAR Wcid, | ||
526 | IN UCHAR NewChannel, | ||
527 | IN UCHAR Secondary) | ||
528 | { | ||
529 | UCHAR BBPValue = 0; | ||
530 | ULONG MACValue; | ||
531 | |||
532 | DBGPRINT(RT_DEBUG_TRACE,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d) \n", NewChannel, Secondary)); | ||
533 | |||
534 | if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE) | ||
535 | return; | ||
536 | |||
537 | // 1. Switches to BW = 20. | ||
538 | if (Secondary == 0) | ||
539 | { | ||
540 | RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); | ||
541 | BBPValue&= (~0x18); | ||
542 | RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); | ||
543 | if (pAd->MACVersion == 0x28600100) | ||
544 | { | ||
545 | RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); | ||
546 | RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08); | ||
547 | RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11); | ||
548 | DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); | ||
549 | } | ||
550 | pAd->CommonCfg.BBPCurrentBW = BW_20; | ||
551 | pAd->CommonCfg.Channel = NewChannel; | ||
552 | pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; | ||
553 | AsicSwitchChannel(pAd, pAd->CommonCfg.Channel,FALSE); | ||
554 | AsicLockChannel(pAd, pAd->CommonCfg.Channel); | ||
555 | pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 0; | ||
556 | DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz !!! \n" )); | ||
557 | } | ||
558 | // 1. Switches to BW = 40 And Station supports BW = 40. | ||
559 | else if (((Secondary == 1) || (Secondary == 3)) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1)) | ||
560 | { | ||
561 | pAd->CommonCfg.Channel = NewChannel; | ||
562 | |||
563 | if (Secondary == 1) | ||
564 | { | ||
565 | // Secondary above. | ||
566 | pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2; | ||
567 | RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue); | ||
568 | MACValue &= 0xfe; | ||
569 | RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue); | ||
570 | RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); | ||
571 | BBPValue&= (~0x18); | ||
572 | BBPValue|= (0x10); | ||
573 | RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); | ||
574 | RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue); | ||
575 | BBPValue&= (~0x20); | ||
576 | RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue); | ||
577 | DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel )); | ||
578 | } | ||
579 | else | ||
580 | { | ||
581 | // Secondary below. | ||
582 | pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2; | ||
583 | RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue); | ||
584 | MACValue &= 0xfe; | ||
585 | MACValue |= 0x1; | ||
586 | RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue); | ||
587 | RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); | ||
588 | BBPValue&= (~0x18); | ||
589 | BBPValue|= (0x10); | ||
590 | RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); | ||
591 | RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue); | ||
592 | BBPValue&= (~0x20); | ||
593 | BBPValue|= (0x20); | ||
594 | RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue); | ||
595 | DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel )); | ||
596 | } | ||
597 | pAd->CommonCfg.BBPCurrentBW = BW_40; | ||
598 | AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); | ||
599 | AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); | ||
600 | pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 1; | ||
601 | } | ||
602 | } | ||
603 | #endif // DOT11N_DRAFT3 // | ||
604 | #endif // DOT11_N_SUPPORT // | ||
605 | |||
606 | VOID PeerPublicAction( | ||
607 | IN PRTMP_ADAPTER pAd, | ||
608 | IN MLME_QUEUE_ELEM *Elem) | ||
609 | { | ||
610 | #ifdef DOT11N_DRAFT3 | ||
611 | UCHAR Action = Elem->Msg[LENGTH_802_11+1]; | ||
612 | #endif // DOT11N_DRAFT3 // | ||
613 | |||
614 | if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) | ||
615 | return; | ||
616 | |||
617 | #ifdef DOT11N_DRAFT3 | ||
618 | switch(Action) | ||
619 | { | ||
620 | case ACTION_BSS_2040_COEXIST: // Format defined in IEEE 7.4.7a.1 in 11n Draf3.03 | ||
621 | { | ||
622 | //UCHAR BssCoexist; | ||
623 | BSS_2040_COEXIST_ELEMENT *pCoexistInfo; | ||
624 | BSS_2040_COEXIST_IE *pBssCoexistIe; | ||
625 | BSS_2040_INTOLERANT_CH_REPORT *pIntolerantReport = NULL; | ||
626 | |||
627 | if (Elem->MsgLen <= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT)) ) | ||
628 | { | ||
629 | DBGPRINT(RT_DEBUG_ERROR, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem->MsgLen)); | ||
630 | break; | ||
631 | } | ||
632 | DBGPRINT(RT_DEBUG_TRACE, ("ACTION - 20/40 BSS Coexistence Management action----> \n")); | ||
633 | hex_dump("CoexistenceMgmtFrame", Elem->Msg, Elem->MsgLen); | ||
634 | |||
635 | |||
636 | pCoexistInfo = (BSS_2040_COEXIST_ELEMENT *) &Elem->Msg[LENGTH_802_11+2]; | ||
637 | //hex_dump("CoexistInfo", (PUCHAR)pCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT)); | ||
638 | if (Elem->MsgLen >= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT) + sizeof(BSS_2040_INTOLERANT_CH_REPORT))) | ||
639 | { | ||
640 | pIntolerantReport = (BSS_2040_INTOLERANT_CH_REPORT *)((PUCHAR)pCoexistInfo + sizeof(BSS_2040_COEXIST_ELEMENT)); | ||
641 | } | ||
642 | //hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT)); | ||
643 | |||
644 | pBssCoexistIe = (BSS_2040_COEXIST_IE *)(&pCoexistInfo->BssCoexistIe); | ||
645 | |||
646 | #ifdef CONFIG_STA_SUPPORT | ||
647 | IF_DEV_CONFIG_OPMODE_ON_STA(pAd) | ||
648 | { | ||
649 | if (INFRA_ON(pAd)) | ||
650 | { | ||
651 | StaPublicAction(pAd, pCoexistInfo); | ||
652 | } | ||
653 | } | ||
654 | #endif // CONFIG_STA_SUPPORT // | ||
655 | |||
656 | } | ||
657 | break; | ||
658 | } | ||
659 | |||
660 | #endif // DOT11N_DRAFT3 // | ||
661 | |||
662 | } | ||
663 | |||
664 | |||
665 | static VOID ReservedAction( | ||
666 | IN PRTMP_ADAPTER pAd, | ||
667 | IN MLME_QUEUE_ELEM *Elem) | ||
668 | { | ||
669 | UCHAR Category; | ||
670 | |||
671 | if (Elem->MsgLen <= LENGTH_802_11) | ||
672 | { | ||
673 | return; | ||
674 | } | ||
675 | |||
676 | Category = Elem->Msg[LENGTH_802_11]; | ||
677 | DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category)); | ||
678 | hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen); | ||
679 | } | ||
680 | |||
681 | VOID PeerRMAction( | ||
682 | IN PRTMP_ADAPTER pAd, | ||
683 | IN MLME_QUEUE_ELEM *Elem) | ||
684 | |||
685 | { | ||
686 | return; | ||
687 | } | ||
688 | |||
689 | #ifdef DOT11_N_SUPPORT | ||
690 | static VOID respond_ht_information_exchange_action( | ||
691 | IN PRTMP_ADAPTER pAd, | ||
692 | IN MLME_QUEUE_ELEM *Elem) | ||
693 | { | ||
694 | PUCHAR pOutBuffer = NULL; | ||
695 | NDIS_STATUS NStatus; | ||
696 | ULONG FrameLen; | ||
697 | FRAME_HT_INFO HTINFOframe, *pFrame; | ||
698 | UCHAR *pAddr; | ||
699 | |||
700 | |||
701 | // 2. Always send back ADDBA Response | ||
702 | NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory | ||
703 | |||
704 | if (NStatus != NDIS_STATUS_SUCCESS) | ||
705 | { | ||
706 | DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n")); | ||
707 | return; | ||
708 | } | ||
709 | |||
710 | // get RA | ||
711 | pFrame = (FRAME_HT_INFO *) &Elem->Msg[0]; | ||
712 | pAddr = pFrame->Hdr.Addr2; | ||
713 | |||
714 | NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO)); | ||
715 | // 2-1. Prepare ADDBA Response frame. | ||
716 | #ifdef CONFIG_STA_SUPPORT | ||
717 | IF_DEV_CONFIG_OPMODE_ON_STA(pAd) | ||
718 | { | ||
719 | if (ADHOC_ON(pAd)) | ||
720 | ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); | ||
721 | else | ||
722 | ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr); | ||
723 | } | ||
724 | #endif // CONFIG_STA_SUPPORT // | ||
725 | |||
726 | HTINFOframe.Category = CATEGORY_HT; | ||
727 | HTINFOframe.Action = HT_INFO_EXCHANGE; | ||
728 | HTINFOframe.HT_Info.Request = 0; | ||
729 | HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant; | ||
730 | HTINFOframe.HT_Info.STA_Channel_Width = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth; | ||
731 | |||
732 | MakeOutgoingFrame(pOutBuffer, &FrameLen, | ||
733 | sizeof(FRAME_HT_INFO), &HTINFOframe, | ||
734 | END_OF_ARGS); | ||
735 | |||
736 | MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); | ||
737 | MlmeFreeMemory(pAd, pOutBuffer); | ||
738 | } | ||
739 | |||
740 | |||
741 | #ifdef DOT11N_DRAFT3 | ||
742 | VOID SendNotifyBWActionFrame( | ||
743 | IN PRTMP_ADAPTER pAd, | ||
744 | IN UCHAR Wcid, | ||
745 | IN UCHAR apidx) | ||
746 | { | ||
747 | PUCHAR pOutBuffer = NULL; | ||
748 | NDIS_STATUS NStatus; | ||
749 | FRAME_ACTION_HDR Frame; | ||
750 | ULONG FrameLen; | ||
751 | PUCHAR pAddr1; | ||
752 | |||
753 | |||
754 | NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory | ||
755 | if(NStatus != NDIS_STATUS_SUCCESS) | ||
756 | { | ||
757 | DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n")); | ||
758 | return; | ||
759 | } | ||
760 | |||
761 | if (Wcid == MCAST_WCID) | ||
762 | pAddr1 = &BROADCAST_ADDR[0]; | ||
763 | else | ||
764 | pAddr1 = pAd->MacTab.Content[Wcid].Addr; | ||
765 | ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid); | ||
766 | |||
767 | Frame.Category = CATEGORY_HT; | ||
768 | Frame.Action = NOTIFY_BW_ACTION; | ||
769 | |||
770 | MakeOutgoingFrame(pOutBuffer, &FrameLen, | ||
771 | sizeof(FRAME_ACTION_HDR), &Frame, | ||
772 | END_OF_ARGS); | ||
773 | |||
774 | *(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth; | ||
775 | FrameLen++; | ||
776 | |||
777 | |||
778 | MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); | ||
779 | DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth)); | ||
780 | |||
781 | } | ||
782 | #endif // DOT11N_DRAFT3 // | ||
783 | |||
784 | |||
785 | VOID PeerHTAction( | ||
786 | IN PRTMP_ADAPTER pAd, | ||
787 | IN MLME_QUEUE_ELEM *Elem) | ||
788 | { | ||
789 | UCHAR Action = Elem->Msg[LENGTH_802_11+1]; | ||
790 | |||
791 | if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) | ||
792 | return; | ||
793 | |||
794 | switch(Action) | ||
795 | { | ||
796 | case NOTIFY_BW_ACTION: | ||
797 | DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n")); | ||
798 | #ifdef CONFIG_STA_SUPPORT | ||
799 | if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) | ||
800 | { | ||
801 | // Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps | ||
802 | // sending BW_Notify Action frame, and cause us to linkup and linkdown. | ||
803 | // In legacy mode, don't need to parse HT action frame. | ||
804 | DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n", | ||
805 | Elem->Msg[LENGTH_802_11+2] )); | ||
806 | break; | ||
807 | } | ||
808 | #endif // CONFIG_STA_SUPPORT // | ||
809 | |||
810 | if (Elem->Msg[LENGTH_802_11+2] == 0) // 7.4.8.2. if value is 1, keep the same as supported channel bandwidth. | ||
811 | pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0; | ||
812 | |||
813 | break; | ||
814 | |||
815 | case SMPS_ACTION: | ||
816 | // 7.3.1.25 | ||
817 | DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n")); | ||
818 | if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0)) | ||
819 | { | ||
820 | pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE; | ||
821 | } | ||
822 | else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0)) | ||
823 | { | ||
824 | pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC; | ||
825 | } | ||
826 | else | ||
827 | { | ||
828 | pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC; | ||
829 | } | ||
830 | |||
831 | DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode)); | ||
832 | // rt2860c : add something for smps change. | ||
833 | break; | ||
834 | |||
835 | case SETPCO_ACTION: | ||
836 | break; | ||
837 | |||
838 | case MIMO_CHA_MEASURE_ACTION: | ||
839 | break; | ||
840 | |||
841 | case HT_INFO_EXCHANGE: | ||
842 | { | ||
843 | HT_INFORMATION_OCTET *pHT_info; | ||
844 | |||
845 | pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2]; | ||
846 | // 7.4.8.10 | ||
847 | DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n")); | ||
848 | if (pHT_info->Request) | ||
849 | { | ||
850 | respond_ht_information_exchange_action(pAd, Elem); | ||
851 | } | ||
852 | } | ||
853 | break; | ||
854 | } | ||
855 | } | ||
856 | |||
857 | |||
858 | /* | ||
859 | ========================================================================== | ||
860 | Description: | ||
861 | Retry sending ADDBA Reqest. | ||
862 | |||
863 | IRQL = DISPATCH_LEVEL | ||
864 | |||
865 | Parametrs: | ||
866 | p8023Header: if this is already 802.3 format, p8023Header is NULL | ||
867 | |||
868 | Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere. | ||
869 | FALSE , then continue indicaterx at this moment. | ||
870 | ========================================================================== | ||
871 | */ | ||
872 | VOID ORIBATimerTimeout( | ||
873 | IN PRTMP_ADAPTER pAd) | ||
874 | { | ||
875 | MAC_TABLE_ENTRY *pEntry; | ||
876 | INT i, total; | ||
877 | // FRAME_BAR FrameBar; | ||
878 | // ULONG FrameLen; | ||
879 | // NDIS_STATUS NStatus; | ||
880 | // PUCHAR pOutBuffer = NULL; | ||
881 | // USHORT Sequence; | ||
882 | UCHAR TID; | ||
883 | |||
884 | #ifdef RALINK_ATE | ||
885 | if (ATE_ON(pAd)) | ||
886 | return; | ||
887 | #endif // RALINK_ATE // | ||
888 | |||
889 | total = pAd->MacTab.Size * NUM_OF_TID; | ||
890 | |||
891 | for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++) | ||
892 | { | ||
893 | if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done) | ||
894 | { | ||
895 | pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid]; | ||
896 | TID = pAd->BATable.BAOriEntry[i].TID; | ||
897 | |||
898 | ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE); | ||
899 | } | ||
900 | total --; | ||
901 | } | ||
902 | } | ||
903 | |||
904 | |||
905 | VOID SendRefreshBAR( | ||
906 | IN PRTMP_ADAPTER pAd, | ||
907 | IN MAC_TABLE_ENTRY *pEntry) | ||
908 | { | ||
909 | FRAME_BAR FrameBar; | ||
910 | ULONG FrameLen; | ||
911 | NDIS_STATUS NStatus; | ||
912 | PUCHAR pOutBuffer = NULL; | ||
913 | USHORT Sequence; | ||
914 | UCHAR i, TID; | ||
915 | USHORT idx; | ||
916 | BA_ORI_ENTRY *pBAEntry; | ||
917 | |||
918 | for (i = 0; i <NUM_OF_TID; i++) | ||
919 | { | ||
920 | idx = pEntry->BAOriWcidArray[i]; | ||
921 | if (idx == 0) | ||
922 | { | ||
923 | continue; | ||
924 | } | ||
925 | pBAEntry = &pAd->BATable.BAOriEntry[idx]; | ||
926 | |||
927 | if (pBAEntry->ORI_BA_Status == Originator_Done) | ||
928 | { | ||
929 | TID = pBAEntry->TID; | ||
930 | |||
931 | ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE); | ||
932 | |||
933 | NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory | ||
934 | if(NStatus != NDIS_STATUS_SUCCESS) | ||
935 | { | ||
936 | DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n")); | ||
937 | return; | ||
938 | } | ||
939 | |||
940 | Sequence = pEntry->TxSeq[TID]; | ||
941 | |||
942 | |||
943 | #ifdef CONFIG_STA_SUPPORT | ||
944 | IF_DEV_CONFIG_OPMODE_ON_STA(pAd) | ||
945 | BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress); | ||
946 | #endif // CONFIG_STA_SUPPORT // | ||
947 | |||
948 | FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function. | ||
949 | FrameBar.StartingSeq.field.StartSeq = Sequence; // make sure sequence not clear in DEL funciton. | ||
950 | FrameBar.BarControl.TID = TID; // make sure sequence not clear in DEL funciton. | ||
951 | |||
952 | MakeOutgoingFrame(pOutBuffer, &FrameLen, | ||
953 | sizeof(FRAME_BAR), &FrameBar, | ||
954 | END_OF_ARGS); | ||
955 | //if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET))) | ||
956 | if (1) // Now we always send BAR. | ||
957 | { | ||
958 | //MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen); | ||
959 | MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); | ||
960 | //MiniportDataMMRequest(pAd, MapUserPriorityToAccessCategory[TID], pOutBuffer, FrameLen); | ||
961 | } | ||
962 | MlmeFreeMemory(pAd, pOutBuffer); | ||
963 | } | ||
964 | } | ||
965 | } | ||
966 | #endif // DOT11_N_SUPPORT // | ||
967 | |||
968 | VOID ActHeaderInit( | ||
969 | IN PRTMP_ADAPTER pAd, | ||
970 | IN OUT PHEADER_802_11 pHdr80211, | ||
971 | IN PUCHAR Addr1, | ||
972 | IN PUCHAR Addr2, | ||
973 | IN PUCHAR Addr3) | ||
974 | { | ||
975 | NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11)); | ||
976 | pHdr80211->FC.Type = BTYPE_MGMT; | ||
977 | pHdr80211->FC.SubType = SUBTYPE_ACTION; | ||
978 | |||
979 | COPY_MAC_ADDR(pHdr80211->Addr1, Addr1); | ||
980 | COPY_MAC_ADDR(pHdr80211->Addr2, Addr2); | ||
981 | COPY_MAC_ADDR(pHdr80211->Addr3, Addr3); | ||
982 | } | ||
983 | |||
984 | VOID BarHeaderInit( | ||
985 | IN PRTMP_ADAPTER pAd, | ||
986 | IN OUT PFRAME_BAR pCntlBar, | ||
987 | IN PUCHAR pDA, | ||
988 | IN PUCHAR pSA) | ||
989 | { | ||
990 | // USHORT Duration; | ||
991 | |||
992 | NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR)); | ||
993 | pCntlBar->FC.Type = BTYPE_CNTL; | ||
994 | pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ; | ||
995 | pCntlBar->BarControl.MTID = 0; | ||
996 | pCntlBar->BarControl.Compressed = 1; | ||
997 | pCntlBar->BarControl.ACKPolicy = 0; | ||
998 | |||
999 | |||
1000 | pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA)); | ||
1001 | |||
1002 | COPY_MAC_ADDR(pCntlBar->Addr1, pDA); | ||
1003 | COPY_MAC_ADDR(pCntlBar->Addr2, pSA); | ||
1004 | } | ||
1005 | |||
1006 | |||
1007 | /* | ||
1008 | ========================================================================== | ||
1009 | Description: | ||
1010 | Insert Category and action code into the action frame. | ||
1011 | |||
1012 | Parametrs: | ||
1013 | 1. frame buffer pointer. | ||
1014 | 2. frame length. | ||
1015 | 3. category code of the frame. | ||
1016 | 4. action code of the frame. | ||
1017 | |||
1018 | Return : None. | ||
1019 | ========================================================================== | ||
1020 | */ | ||
1021 | VOID InsertActField( | ||
1022 | IN PRTMP_ADAPTER pAd, | ||
1023 | OUT PUCHAR pFrameBuf, | ||
1024 | OUT PULONG pFrameLen, | ||
1025 | IN UINT8 Category, | ||
1026 | IN UINT8 ActCode) | ||
1027 | { | ||
1028 | ULONG TempLen; | ||
1029 | |||
1030 | MakeOutgoingFrame( pFrameBuf, &TempLen, | ||
1031 | 1, &Category, | ||
1032 | 1, &ActCode, | ||
1033 | END_OF_ARGS); | ||
1034 | |||
1035 | *pFrameLen = *pFrameLen + TempLen; | ||
1036 | |||
1037 | return; | ||
1038 | } | ||