blob: 5f25b8e88bd9abc4894a85ca8e5b05dbd658e97f [file] [log] [blame]
Forest Bond5449c682009-04-25 10:30:44 -04001/*
2 * Copyright (c) 1996, 2005 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 *
20 * File: IEEE11h.c
21 *
22 * Purpose:
23 *
24 * Functions:
25 *
26 * Revision History:
27 *
28 * Author: Yiching Chen
29 *
30 * Date: Mar. 31, 2005
31 *
32 */
33
34
35#if !defined(__TTYPE_H__)
36#include "ttype.h"
37#endif
38#if !defined(__UMEM_H__)
39#include "umem.h"
40#endif
41#if !defined(__TMACRO_H__)
42#include "tmacro.h"
43#endif
44#if !defined(__TETHER_H__)
45#include "tether.h"
46#endif
47#if !defined(__IEEE11h_H__)
48#include "IEEE11h.h"
49#endif
50
51#if !defined(__DEVICE_H__)
52#include "device.h"
53#endif
54#if !defined(__WMGR_H__)
55#include "wmgr.h"
56#endif
57#if !defined(__RXTX_H__)
58#include "rxtx.h"
59#endif
60
61
62
63/*--------------------- Static Definitions -------------------------*/
64static int msglevel =MSG_LEVEL_INFO;
65
66#pragma pack(1)
67
68typedef struct _WLAN_FRAME_ACTION {
69 WLAN_80211HDR_A3 Header;
70 BYTE byCategory;
71 BYTE byAction;
72 BYTE abyVars[1];
73} WLAN_FRAME_ACTION, *PWLAN_FRAME_ACTION;
74
75typedef struct _WLAN_FRAME_MSRREQ {
76 WLAN_80211HDR_A3 Header;
77 BYTE byCategory;
78 BYTE byAction;
79 BYTE byDialogToken;
80 WLAN_IE_MEASURE_REQ sMSRReqEIDs[1];
81} WLAN_FRAME_MSRREQ, *PWLAN_FRAME_MSRREQ;
82
83typedef struct _WLAN_FRAME_MSRREP {
84 WLAN_80211HDR_A3 Header;
85 BYTE byCategory;
86 BYTE byAction;
87 BYTE byDialogToken;
88 WLAN_IE_MEASURE_REP sMSRRepEIDs[1];
89} WLAN_FRAME_MSRREP, *PWLAN_FRAME_MSRREP;
90
91typedef struct _WLAN_FRAME_TPCREQ {
92 WLAN_80211HDR_A3 Header;
93 BYTE byCategory;
94 BYTE byAction;
95 BYTE byDialogToken;
96 WLAN_IE_TPC_REQ sTPCReqEIDs;
97} WLAN_FRAME_TPCREQ, *PWLAN_FRAME_TPCREQ;
98
99typedef struct _WLAN_FRAME_TPCREP {
100 WLAN_80211HDR_A3 Header;
101 BYTE byCategory;
102 BYTE byAction;
103 BYTE byDialogToken;
104 WLAN_IE_TPC_REP sTPCRepEIDs;
105} WLAN_FRAME_TPCREP, *PWLAN_FRAME_TPCREP;
106
107#pragma pack()
108
109// action field reference ieee 802.11h Table 20e
110#define ACTION_MSRREQ 0
111#define ACTION_MSRREP 1
112#define ACTION_TPCREQ 2
113#define ACTION_TPCREP 3
114#define ACTION_CHSW 4
115
116/*--------------------- Static Classes ----------------------------*/
117
118/*--------------------- Static Variables --------------------------*/
119
120/*--------------------- Static Functions --------------------------*/
121static BOOL s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq, UINT uLength)
122{
123 UINT uNumOfEIDs = 0;
124 BOOL bResult = TRUE;
125
126 if (uLength <= WLAN_A3FR_MAXLEN) {
127 MEMvCopy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength);
128 }
129 uNumOfEIDs = ((uLength - OFFSET(WLAN_FRAME_MSRREQ, sMSRReqEIDs))/ (sizeof(WLAN_IE_MEASURE_REQ)));
130 pMgmt->pCurrMeasureEIDRep = &(((PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep))->sMSRRepEIDs[0]);
131 pMgmt->uLengthOfRepEIDs = 0;
132 bResult = CARDbStartMeasure(pMgmt->pAdapter,
133 ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->sMSRReqEIDs,
134 uNumOfEIDs
135 );
136 return (bResult);
137}
138
139
140static BOOL s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, BYTE byRate, BYTE byRSSI)
141{
142 PWLAN_FRAME_TPCREP pFrame;
143 PSTxMgmtPacket pTxPacket = NULL;
144
145
146 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
147 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
148 pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
149
150 pFrame = (PWLAN_FRAME_TPCREP)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
151
152 pFrame->Header.wFrameCtl = ( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
153 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
154 );
155
156 MEMvCopy( pFrame->Header.abyAddr1, pTPCReq->Header.abyAddr2, WLAN_ADDR_LEN);
157 MEMvCopy( pFrame->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
158 MEMvCopy( pFrame->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
159
160 pFrame->byCategory = 0;
161 pFrame->byAction = 3;
162 pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken;
163
164 pFrame->sTPCRepEIDs.byElementID = WLAN_EID_TPC_REP;
165 pFrame->sTPCRepEIDs.len = 2;
166 pFrame->sTPCRepEIDs.byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
167 switch (byRate) {
168 case RATE_54M:
169 pFrame->sTPCRepEIDs.byLinkMargin = 65 - byRSSI;
170 break;
171 case RATE_48M:
172 pFrame->sTPCRepEIDs.byLinkMargin = 66 - byRSSI;
173 break;
174 case RATE_36M:
175 pFrame->sTPCRepEIDs.byLinkMargin = 70 - byRSSI;
176 break;
177 case RATE_24M:
178 pFrame->sTPCRepEIDs.byLinkMargin = 74 - byRSSI;
179 break;
180 case RATE_18M:
181 pFrame->sTPCRepEIDs.byLinkMargin = 77 - byRSSI;
182 break;
183 case RATE_12M:
184 pFrame->sTPCRepEIDs.byLinkMargin = 79 - byRSSI;
185 break;
186 case RATE_9M:
187 pFrame->sTPCRepEIDs.byLinkMargin = 81 - byRSSI;
188 break;
189 case RATE_6M:
190 default:
191 pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI;
192 break;
193 }
194
195 pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP);
196 pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) - WLAN_HDR_ADDR3_LEN;
197 if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
198 return (FALSE);
199 return (TRUE);
200// return (CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG, sizeof(WLAN_FRAME_TPCREP)));
201
202}
203
204
205/*--------------------- Export Variables --------------------------*/
206
207/*--------------------- Export Functions --------------------------*/
208
209
210/*+
211 *
212 * Description:
213 * Handles action management frames.
214 *
215 * Parameters:
216 * In:
217 * pMgmt - Management Object structure
218 * pRxPacket - Received packet
219 * Out:
220 * none
221 *
222 * Return Value: None.
223 *
224-*/
225BOOL
226IEEE11hbMgrRxAction (
227 IN PVOID pMgmtHandle,
228 IN PVOID pRxPacket
229 )
230{
231 PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle;
232 PWLAN_FRAME_ACTION pAction = NULL;
233 UINT uLength = 0;
234 PWLAN_IE_CH_SW pChannelSwitch = NULL;
235
236
237 // decode the frame
238 uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen;
239 if (uLength > WLAN_A3FR_MAXLEN) {
240 return (FALSE);
241 }
242
243
244 pAction = (PWLAN_FRAME_ACTION) (((PSRxMgmtPacket)pRxPacket)->p80211Header);
245
246 if (pAction->byCategory == 0) {
247 switch (pAction->byAction) {
248 case ACTION_MSRREQ:
249 return (s_bRxMSRReq(pMgmt, (PWLAN_FRAME_MSRREQ) pAction, uLength));
250 break;
251 case ACTION_MSRREP:
252 break;
253 case ACTION_TPCREQ:
254 return (s_bRxTPCReq(pMgmt,
255 (PWLAN_FRAME_TPCREQ) pAction,
256 ((PSRxMgmtPacket)pRxPacket)->byRxRate,
257 (BYTE) ((PSRxMgmtPacket)pRxPacket)->uRSSI));
258 break;
259 case ACTION_TPCREP:
260 break;
261 case ACTION_CHSW:
262 pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars);
263 if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH) &&
264 (pChannelSwitch->len == 3)) {
265 // valid element id
266 CARDbChannelSwitch( pMgmt->pAdapter,
267 pChannelSwitch->byMode,
268 CARDbyGetChannelMapping(pMgmt->pAdapter, pChannelSwitch->byChannel, pMgmt->eCurrentPHYMode),
269 pChannelSwitch->byCount
270 );
271 }
272 break;
273 default:
274 DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Action = %d\n", pAction->byAction);
275 break;
276 }
277 } else {
278 DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n", pAction->byCategory);
279 pAction->byCategory |= 0x80;
280
281 //return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG, uLength));
282 return (TRUE);
283 }
284 return (TRUE);
285}
286
287
288BOOL IEEE11hbMSRRepTx (
289 IN PVOID pMgmtHandle
290 )
291{
292 PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle;
293 PWLAN_FRAME_MSRREP pMSRRep = (PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket));
294 UINT uLength = 0;
295 PSTxMgmtPacket pTxPacket = NULL;
296
297 pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep;
298 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
299 pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
300
301
302 pMSRRep->Header.wFrameCtl = ( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
303 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
304 );
305
306 MEMvCopy( pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN);
307 MEMvCopy( pMSRRep->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
308 MEMvCopy( pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
309
310 pMSRRep->byCategory = 0;
311 pMSRRep->byAction = 1;
312 pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken;
313
314 uLength = pMgmt->uLengthOfRepEIDs + OFFSET(WLAN_FRAME_MSRREP, sMSRRepEIDs);
315
316 pTxPacket->cbMPDULen = uLength;
317 pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN;
318 if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
319 return (FALSE);
320 return (TRUE);
321// return (CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG, uLength));
322
323}
324