Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux...
[linux-btrfs-devel.git] / drivers / staging / vt6655 / IEEE11h.c
blobe07ebd578d449e17ed5b79e6f9c7722239e4ea6b
1 /*
2 * Copyright (c) 1996, 2005 VIA Networking Technologies, Inc.
3 * All rights reserved.
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.
20 * File: IEEE11h.c
22 * Purpose:
24 * Functions:
26 * Revision History:
28 * Author: Yiching Chen
30 * Date: Mar. 31, 2005
34 #include "ttype.h"
35 #include "tmacro.h"
36 #include "tether.h"
37 #include "IEEE11h.h"
38 #include "device.h"
39 #include "wmgr.h"
40 #include "rxtx.h"
41 #include "channel.h"
43 /*--------------------- Static Definitions -------------------------*/
44 static int msglevel =MSG_LEVEL_INFO;
46 #pragma pack(1)
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;
87 #pragma pack()
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
94 #define ACTION_CHSW 4
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;
105 bool bResult = true;
107 if (uLength <= WLAN_A3FR_MAXLEN) {
108 memcpy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength);
110 uNumOfEIDs = ((uLength - offsetof(WLAN_FRAME_MSRREQ, sMSRReqEIDs))/ (sizeof(WLAN_IE_MEASURE_REQ)));
111 pMgmt->pCurrMeasureEIDRep = &(((PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep))->sMSRRepEIDs[0]);
112 pMgmt->uLengthOfRepEIDs = 0;
113 bResult = CARDbStartMeasure(pMgmt->pAdapter,
114 ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->sMSRReqEIDs,
115 uNumOfEIDs
117 return (bResult);
121 static bool s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, unsigned char byRate, unsigned char byRSSI)
123 PWLAN_FRAME_TPCREP pFrame;
124 PSTxMgmtPacket pTxPacket = NULL;
127 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
128 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
129 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
131 pFrame = (PWLAN_FRAME_TPCREP)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
133 pFrame->Header.wFrameCtl = ( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
134 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
137 memcpy( pFrame->Header.abyAddr1, pTPCReq->Header.abyAddr2, WLAN_ADDR_LEN);
138 memcpy( pFrame->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
139 memcpy( pFrame->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
141 pFrame->byCategory = 0;
142 pFrame->byAction = 3;
143 pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken;
145 pFrame->sTPCRepEIDs.byElementID = WLAN_EID_TPC_REP;
146 pFrame->sTPCRepEIDs.len = 2;
147 pFrame->sTPCRepEIDs.byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
148 switch (byRate) {
149 case RATE_54M:
150 pFrame->sTPCRepEIDs.byLinkMargin = 65 - byRSSI;
151 break;
152 case RATE_48M:
153 pFrame->sTPCRepEIDs.byLinkMargin = 66 - byRSSI;
154 break;
155 case RATE_36M:
156 pFrame->sTPCRepEIDs.byLinkMargin = 70 - byRSSI;
157 break;
158 case RATE_24M:
159 pFrame->sTPCRepEIDs.byLinkMargin = 74 - byRSSI;
160 break;
161 case RATE_18M:
162 pFrame->sTPCRepEIDs.byLinkMargin = 77 - byRSSI;
163 break;
164 case RATE_12M:
165 pFrame->sTPCRepEIDs.byLinkMargin = 79 - byRSSI;
166 break;
167 case RATE_9M:
168 pFrame->sTPCRepEIDs.byLinkMargin = 81 - byRSSI;
169 break;
170 case RATE_6M:
171 default:
172 pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI;
173 break;
176 pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP);
177 pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) - WLAN_HDR_ADDR3_LEN;
178 if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
179 return (false);
180 return (true);
181 // return (CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG, sizeof(WLAN_FRAME_TPCREP)));
186 /*--------------------- Export Variables --------------------------*/
188 /*--------------------- Export Functions --------------------------*/
193 * Description:
194 * Handles action management frames.
196 * Parameters:
197 * In:
198 * pMgmt - Management Object structure
199 * pRxPacket - Received packet
200 * Out:
201 * none
203 * Return Value: None.
206 bool
207 IEEE11hbMgrRxAction (
208 void *pMgmtHandle,
209 void *pRxPacket
212 PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle;
213 PWLAN_FRAME_ACTION pAction = NULL;
214 unsigned int uLength = 0;
215 PWLAN_IE_CH_SW pChannelSwitch = NULL;
218 // decode the frame
219 uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen;
220 if (uLength > WLAN_A3FR_MAXLEN) {
221 return (false);
225 pAction = (PWLAN_FRAME_ACTION) (((PSRxMgmtPacket)pRxPacket)->p80211Header);
227 if (pAction->byCategory == 0) {
228 switch (pAction->byAction) {
229 case ACTION_MSRREQ:
230 return (s_bRxMSRReq(pMgmt, (PWLAN_FRAME_MSRREQ) pAction, uLength));
231 break;
232 case ACTION_MSRREP:
233 break;
234 case ACTION_TPCREQ:
235 return (s_bRxTPCReq(pMgmt,
236 (PWLAN_FRAME_TPCREQ) pAction,
237 ((PSRxMgmtPacket)pRxPacket)->byRxRate,
238 (unsigned char) ((PSRxMgmtPacket)pRxPacket)->uRSSI));
239 break;
240 case ACTION_TPCREP:
241 break;
242 case ACTION_CHSW:
243 pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars);
244 if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH) &&
245 (pChannelSwitch->len == 3)) {
246 // valid element id
247 CARDbChannelSwitch( pMgmt->pAdapter,
248 pChannelSwitch->byMode,
249 get_channel_mapping(pMgmt->pAdapter, pChannelSwitch->byChannel, pMgmt->eCurrentPHYMode),
250 pChannelSwitch->byCount
253 break;
254 default:
255 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Action = %d\n", pAction->byAction);
256 break;
258 } else {
259 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n", pAction->byCategory);
260 pAction->byCategory |= 0x80;
262 //return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG, uLength));
263 return (true);
265 return (true);
269 bool IEEE11hbMSRRepTx (
270 void *pMgmtHandle
273 PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle;
274 PWLAN_FRAME_MSRREP pMSRRep = (PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket));
275 size_t uLength = 0;
276 PSTxMgmtPacket pTxPacket = NULL;
278 pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep;
279 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
280 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
283 pMSRRep->Header.wFrameCtl = ( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
284 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
287 memcpy( pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN);
288 memcpy( pMSRRep->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
289 memcpy( pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
291 pMSRRep->byCategory = 0;
292 pMSRRep->byAction = 1;
293 pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken;
295 uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP, sMSRRepEIDs);
297 pTxPacket->cbMPDULen = uLength;
298 pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN;
299 if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
300 return (false);
301 return (true);
302 // return (CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG, uLength));