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,
123 static bool s_bRxTPCReq(PSMgmtObject pMgmt,
124 PWLAN_FRAME_TPCREQ pTPCReq,
125 unsigned char byRate,
126 unsigned char byRSSI)
128 PWLAN_FRAME_TPCREP pFrame;
129 PSTxMgmtPacket pTxPacket = NULL;
131 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
132 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
133 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket +
134 sizeof(STxMgmtPacket));
136 pFrame = (PWLAN_FRAME_TPCREP)((unsigned char *)pTxPacket +
137 sizeof(STxMgmtPacket));
139 pFrame->Header.wFrameCtl = (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
140 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
143 memcpy(pFrame->Header.abyAddr1,
144 pTPCReq->Header.abyAddr2,
146 memcpy(pFrame->Header.abyAddr2,
147 CARDpGetCurrentAddress(pMgmt->pAdapter),
149 memcpy(pFrame->Header.abyAddr3,
153 pFrame->byCategory = 0;
154 pFrame->byAction = 3;
155 pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ)
156 (pMgmt->abyCurrentMSRReq))->byDialogToken;
158 pFrame->sTPCRepEIDs.byElementID = WLAN_EID_TPC_REP;
159 pFrame->sTPCRepEIDs.len = 2;
160 pFrame->sTPCRepEIDs.byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
163 pFrame->sTPCRepEIDs.byLinkMargin = 65 - byRSSI;
166 pFrame->sTPCRepEIDs.byLinkMargin = 66 - byRSSI;
169 pFrame->sTPCRepEIDs.byLinkMargin = 70 - byRSSI;
172 pFrame->sTPCRepEIDs.byLinkMargin = 74 - byRSSI;
175 pFrame->sTPCRepEIDs.byLinkMargin = 77 - byRSSI;
178 pFrame->sTPCRepEIDs.byLinkMargin = 79 - byRSSI;
181 pFrame->sTPCRepEIDs.byLinkMargin = 81 - byRSSI;
185 pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI;
189 pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP);
190 pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) -
192 if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
197 /*--------------------- Export Variables --------------------------*/
199 /*--------------------- Export Functions --------------------------*/
204 * Handles action management frames.
208 * pMgmt - Management Object structure
209 * pRxPacket - Received packet
213 * Return Value: None.
217 IEEE11hbMgrRxAction(void *pMgmtHandle, void *pRxPacket)
219 PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle;
220 PWLAN_FRAME_ACTION pAction = NULL;
221 unsigned int uLength = 0;
222 PWLAN_IE_CH_SW pChannelSwitch = NULL;
224 /* decode the frame */
225 uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen;
226 if (uLength > WLAN_A3FR_MAXLEN)
229 pAction = (PWLAN_FRAME_ACTION)
230 (((PSRxMgmtPacket)pRxPacket)->p80211Header);
232 if (pAction->byCategory == 0) {
233 switch (pAction->byAction) {
235 return s_bRxMSRReq(pMgmt,
243 return s_bRxTPCReq(pMgmt,
244 (PWLAN_FRAME_TPCREQ) pAction,
245 ((PSRxMgmtPacket)pRxPacket)->byRxRate,
247 ((PSRxMgmtPacket)pRxPacket)->uRSSI);
252 pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars);
253 if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH)
254 && (pChannelSwitch->len == 3)) {
255 /* valid element id */
256 CARDbChannelSwitch(pMgmt->pAdapter,
257 pChannelSwitch->byMode,
258 get_channel_mapping(pMgmt->pAdapter,
259 pChannelSwitch->byChannel,
260 pMgmt->eCurrentPHYMode),
261 pChannelSwitch->byCount);
265 DBG_PRT(MSG_LEVEL_DEBUG,
266 KERN_INFO "Unknown Action = %d\n",
271 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unknown Category = %d\n",
272 pAction->byCategory);
273 pAction->byCategory |= 0x80;
280 bool IEEE11hbMSRRepTx(void *pMgmtHandle)
282 PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle;
283 PWLAN_FRAME_MSRREP pMSRRep = (PWLAN_FRAME_MSRREP)
284 (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket));
286 PSTxMgmtPacket pTxPacket = NULL;
288 pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep;
289 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
290 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket +
291 sizeof(STxMgmtPacket));
293 pMSRRep->Header.wFrameCtl = (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
294 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
297 memcpy(pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ)
298 (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN);
299 memcpy(pMSRRep->Header.abyAddr2,
300 CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
301 memcpy(pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
303 pMSRRep->byCategory = 0;
304 pMSRRep->byAction = 1;
305 pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ)
306 (pMgmt->abyCurrentMSRReq))->byDialogToken;
308 uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP,
311 pTxPacket->cbMPDULen = uLength;
312 pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN;
313 if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)