2 * Copyright (c) 1996, 2005 VIA Networking Technologies, Inc.
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.
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.
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.
28 * Author: Yiching Chen
43 /*--------------------- Static Definitions -------------------------*/
44 static int msglevel
= MSG_LEVEL_INFO
;
48 typedef struct _WLAN_FRAME_ACTION
{
49 WLAN_80211HDR_A3 Header
;
50 unsigned char byCategory
;
51 unsigned char byAction
;
52 unsigned char abyVars
[1];
53 } WLAN_FRAME_ACTION
, *PWLAN_FRAME_ACTION
;
55 typedef struct _WLAN_FRAME_MSRREQ
{
56 WLAN_80211HDR_A3 Header
;
57 unsigned char byCategory
;
58 unsigned char byAction
;
59 unsigned char byDialogToken
;
60 WLAN_IE_MEASURE_REQ sMSRReqEIDs
[1];
61 } WLAN_FRAME_MSRREQ
, *PWLAN_FRAME_MSRREQ
;
63 typedef struct _WLAN_FRAME_MSRREP
{
64 WLAN_80211HDR_A3 Header
;
65 unsigned char byCategory
;
66 unsigned char byAction
;
67 unsigned char byDialogToken
;
68 WLAN_IE_MEASURE_REP sMSRRepEIDs
[1];
69 } WLAN_FRAME_MSRREP
, *PWLAN_FRAME_MSRREP
;
71 typedef struct _WLAN_FRAME_TPCREQ
{
72 WLAN_80211HDR_A3 Header
;
73 unsigned char byCategory
;
74 unsigned char byAction
;
75 unsigned char byDialogToken
;
76 WLAN_IE_TPC_REQ sTPCReqEIDs
;
77 } WLAN_FRAME_TPCREQ
, *PWLAN_FRAME_TPCREQ
;
79 typedef struct _WLAN_FRAME_TPCREP
{
80 WLAN_80211HDR_A3 Header
;
81 unsigned char byCategory
;
82 unsigned char byAction
;
83 unsigned char byDialogToken
;
84 WLAN_IE_TPC_REP sTPCRepEIDs
;
85 } WLAN_FRAME_TPCREP
, *PWLAN_FRAME_TPCREP
;
89 /* action field reference ieee 802.11h Table 20e */
90 #define ACTION_MSRREQ 0
91 #define ACTION_MSRREP 1
92 #define ACTION_TPCREQ 2
93 #define ACTION_TPCREP 3
96 /*--------------------- Static Classes ----------------------------*/
98 /*--------------------- Static Variables --------------------------*/
100 /*--------------------- Static Functions --------------------------*/
101 static bool s_bRxMSRReq(PSMgmtObject pMgmt
, PWLAN_FRAME_MSRREQ pMSRReq
,
102 unsigned int uLength
)
104 size_t uNumOfEIDs
= 0;
107 if (uLength
<= WLAN_A3FR_MAXLEN
)
108 memcpy(pMgmt
->abyCurrentMSRReq
, pMSRReq
, uLength
);
109 uNumOfEIDs
= ((uLength
- offsetof(WLAN_FRAME_MSRREQ
,
111 (sizeof(WLAN_IE_MEASURE_REQ
)));
112 pMgmt
->pCurrMeasureEIDRep
= &(((PWLAN_FRAME_MSRREP
)
113 (pMgmt
->abyCurrentMSRRep
))->sMSRRepEIDs
[0]);
114 pMgmt
->uLengthOfRepEIDs
= 0;
115 bResult
= CARDbStartMeasure(pMgmt
->pAdapter
,
116 ((PWLAN_FRAME_MSRREQ
)
117 (pMgmt
->abyCurrentMSRReq
))->sMSRReqEIDs
,
124 static bool s_bRxTPCReq(PSMgmtObject pMgmt
,
125 PWLAN_FRAME_TPCREQ pTPCReq
,
126 unsigned char byRate
,
127 unsigned char byRSSI
)
129 PWLAN_FRAME_TPCREP pFrame
;
130 PSTxMgmtPacket pTxPacket
= NULL
;
132 pTxPacket
= (PSTxMgmtPacket
)pMgmt
->pbyMgmtPacketPool
;
133 memset(pTxPacket
, 0, sizeof(STxMgmtPacket
) + WLAN_A3FR_MAXLEN
);
134 pTxPacket
->p80211Header
= (PUWLAN_80211HDR
)((unsigned char *)pTxPacket
+
135 sizeof(STxMgmtPacket
));
137 pFrame
= (PWLAN_FRAME_TPCREP
)((unsigned char *)pTxPacket
+
138 sizeof(STxMgmtPacket
));
140 pFrame
->Header
.wFrameCtl
= (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT
) |
141 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION
)
144 memcpy(pFrame
->Header
.abyAddr1
,
145 pTPCReq
->Header
.abyAddr2
,
147 memcpy(pFrame
->Header
.abyAddr2
,
148 CARDpGetCurrentAddress(pMgmt
->pAdapter
),
150 memcpy(pFrame
->Header
.abyAddr3
,
154 pFrame
->byCategory
= 0;
155 pFrame
->byAction
= 3;
156 pFrame
->byDialogToken
= ((PWLAN_FRAME_MSRREQ
)
157 (pMgmt
->abyCurrentMSRReq
))->byDialogToken
;
159 pFrame
->sTPCRepEIDs
.byElementID
= WLAN_EID_TPC_REP
;
160 pFrame
->sTPCRepEIDs
.len
= 2;
161 pFrame
->sTPCRepEIDs
.byTxPower
= CARDbyGetTransmitPower(pMgmt
->pAdapter
);
164 pFrame
->sTPCRepEIDs
.byLinkMargin
= 65 - byRSSI
;
167 pFrame
->sTPCRepEIDs
.byLinkMargin
= 66 - byRSSI
;
170 pFrame
->sTPCRepEIDs
.byLinkMargin
= 70 - byRSSI
;
173 pFrame
->sTPCRepEIDs
.byLinkMargin
= 74 - byRSSI
;
176 pFrame
->sTPCRepEIDs
.byLinkMargin
= 77 - byRSSI
;
179 pFrame
->sTPCRepEIDs
.byLinkMargin
= 79 - byRSSI
;
182 pFrame
->sTPCRepEIDs
.byLinkMargin
= 81 - byRSSI
;
186 pFrame
->sTPCRepEIDs
.byLinkMargin
= 82 - byRSSI
;
190 pTxPacket
->cbMPDULen
= sizeof(WLAN_FRAME_TPCREP
);
191 pTxPacket
->cbPayloadLen
= sizeof(WLAN_FRAME_TPCREP
) -
193 if (csMgmt_xmit(pMgmt
->pAdapter
, pTxPacket
) != CMD_STATUS_PENDING
)
196 /* return (CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG,
197 sizeof(WLAN_FRAME_TPCREP))); */
202 /*--------------------- Export Variables --------------------------*/
204 /*--------------------- Export Functions --------------------------*/
210 * Handles action management frames.
214 * pMgmt - Management Object structure
215 * pRxPacket - Received packet
219 * Return Value: None.
223 IEEE11hbMgrRxAction(void *pMgmtHandle
, void *pRxPacket
)
225 PSMgmtObject pMgmt
= (PSMgmtObject
) pMgmtHandle
;
226 PWLAN_FRAME_ACTION pAction
= NULL
;
227 unsigned int uLength
= 0;
228 PWLAN_IE_CH_SW pChannelSwitch
= NULL
;
230 /* decode the frame */
231 uLength
= ((PSRxMgmtPacket
)pRxPacket
)->cbMPDULen
;
232 if (uLength
> WLAN_A3FR_MAXLEN
)
235 pAction
= (PWLAN_FRAME_ACTION
)
236 (((PSRxMgmtPacket
)pRxPacket
)->p80211Header
);
238 if (pAction
->byCategory
== 0) {
239 switch (pAction
->byAction
) {
241 return s_bRxMSRReq(pMgmt
,
249 return s_bRxTPCReq(pMgmt
,
250 (PWLAN_FRAME_TPCREQ
) pAction
,
251 ((PSRxMgmtPacket
)pRxPacket
)->byRxRate
,
253 ((PSRxMgmtPacket
)pRxPacket
)->uRSSI
);
258 pChannelSwitch
= (PWLAN_IE_CH_SW
) (pAction
->abyVars
);
259 if ((pChannelSwitch
->byElementID
== WLAN_EID_CH_SWITCH
)
260 && (pChannelSwitch
->len
== 3)) {
261 /* valid element id */
262 CARDbChannelSwitch(pMgmt
->pAdapter
,
263 pChannelSwitch
->byMode
,
264 get_channel_mapping(pMgmt
->pAdapter
,
265 pChannelSwitch
->byChannel
,
266 pMgmt
->eCurrentPHYMode
),
267 pChannelSwitch
->byCount
);
271 DBG_PRT(MSG_LEVEL_DEBUG
,
272 KERN_INFO
"Unknown Action = %d\n",
277 DBG_PRT(MSG_LEVEL_DEBUG
, KERN_INFO
"Unknown Category = %d\n",
278 pAction
->byCategory
);
279 pAction
->byCategory
|= 0x80;
281 /*return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG,
289 bool IEEE11hbMSRRepTx(void *pMgmtHandle
)
291 PSMgmtObject pMgmt
= (PSMgmtObject
) pMgmtHandle
;
292 PWLAN_FRAME_MSRREP pMSRRep
= (PWLAN_FRAME_MSRREP
)
293 (pMgmt
->abyCurrentMSRRep
+ sizeof(STxMgmtPacket
));
295 PSTxMgmtPacket pTxPacket
= NULL
;
297 pTxPacket
= (PSTxMgmtPacket
)pMgmt
->abyCurrentMSRRep
;
298 memset(pTxPacket
, 0, sizeof(STxMgmtPacket
) + WLAN_A3FR_MAXLEN
);
299 pTxPacket
->p80211Header
= (PUWLAN_80211HDR
)((unsigned char *)pTxPacket
+
300 sizeof(STxMgmtPacket
));
302 pMSRRep
->Header
.wFrameCtl
= (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT
) |
303 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION
)
306 memcpy(pMSRRep
->Header
.abyAddr1
, ((PWLAN_FRAME_MSRREQ
)
307 (pMgmt
->abyCurrentMSRReq
))->Header
.abyAddr2
, WLAN_ADDR_LEN
);
308 memcpy(pMSRRep
->Header
.abyAddr2
,
309 CARDpGetCurrentAddress(pMgmt
->pAdapter
), WLAN_ADDR_LEN
);
310 memcpy(pMSRRep
->Header
.abyAddr3
, pMgmt
->abyCurrBSSID
, WLAN_BSSID_LEN
);
312 pMSRRep
->byCategory
= 0;
313 pMSRRep
->byAction
= 1;
314 pMSRRep
->byDialogToken
= ((PWLAN_FRAME_MSRREQ
)
315 (pMgmt
->abyCurrentMSRReq
))->byDialogToken
;
317 uLength
= pMgmt
->uLengthOfRepEIDs
+ offsetof(WLAN_FRAME_MSRREP
,
320 pTxPacket
->cbMPDULen
= uLength
;
321 pTxPacket
->cbPayloadLen
= uLength
- WLAN_HDR_ADDR3_LEN
;
322 if (csMgmt_xmit(pMgmt
->pAdapter
, pTxPacket
) != CMD_STATUS_PENDING
)
325 /* return (CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG,