Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / vt6655 / IEEE11h.c
CommitLineData
5449c685
FB
1/*
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
5449c685 34#include "ttype.h"
5449c685 35#include "tmacro.h"
5449c685 36#include "tether.h"
5449c685 37#include "IEEE11h.h"
5449c685 38#include "device.h"
5449c685 39#include "wmgr.h"
5449c685 40#include "rxtx.h"
5449c685
FB
41
42/*--------------------- Static Definitions -------------------------*/
43static int msglevel =MSG_LEVEL_INFO;
44
45#pragma pack(1)
46
47typedef struct _WLAN_FRAME_ACTION {
48 WLAN_80211HDR_A3 Header;
49 BYTE byCategory;
50 BYTE byAction;
51 BYTE abyVars[1];
52} WLAN_FRAME_ACTION, *PWLAN_FRAME_ACTION;
53
54typedef struct _WLAN_FRAME_MSRREQ {
55 WLAN_80211HDR_A3 Header;
56 BYTE byCategory;
57 BYTE byAction;
58 BYTE byDialogToken;
59 WLAN_IE_MEASURE_REQ sMSRReqEIDs[1];
60} WLAN_FRAME_MSRREQ, *PWLAN_FRAME_MSRREQ;
61
62typedef struct _WLAN_FRAME_MSRREP {
63 WLAN_80211HDR_A3 Header;
64 BYTE byCategory;
65 BYTE byAction;
66 BYTE byDialogToken;
67 WLAN_IE_MEASURE_REP sMSRRepEIDs[1];
68} WLAN_FRAME_MSRREP, *PWLAN_FRAME_MSRREP;
69
70typedef struct _WLAN_FRAME_TPCREQ {
71 WLAN_80211HDR_A3 Header;
72 BYTE byCategory;
73 BYTE byAction;
74 BYTE byDialogToken;
75 WLAN_IE_TPC_REQ sTPCReqEIDs;
76} WLAN_FRAME_TPCREQ, *PWLAN_FRAME_TPCREQ;
77
78typedef struct _WLAN_FRAME_TPCREP {
79 WLAN_80211HDR_A3 Header;
80 BYTE byCategory;
81 BYTE byAction;
82 BYTE byDialogToken;
83 WLAN_IE_TPC_REP sTPCRepEIDs;
84} WLAN_FRAME_TPCREP, *PWLAN_FRAME_TPCREP;
85
86#pragma pack()
87
88// action field reference ieee 802.11h Table 20e
89#define ACTION_MSRREQ 0
90#define ACTION_MSRREP 1
91#define ACTION_TPCREQ 2
92#define ACTION_TPCREP 3
93#define ACTION_CHSW 4
94
95/*--------------------- Static Classes ----------------------------*/
96
97/*--------------------- Static Variables --------------------------*/
98
99/*--------------------- Static Functions --------------------------*/
100static BOOL s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq, UINT uLength)
101{
db6cb903 102 size_t uNumOfEIDs = 0;
5449c685
FB
103 BOOL bResult = TRUE;
104
105 if (uLength <= WLAN_A3FR_MAXLEN) {
51b6d9c2 106 memcpy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength);
5449c685 107 }
db6cb903 108 uNumOfEIDs = ((uLength - offsetof(WLAN_FRAME_MSRREQ, sMSRReqEIDs))/ (sizeof(WLAN_IE_MEASURE_REQ)));
5449c685
FB
109 pMgmt->pCurrMeasureEIDRep = &(((PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep))->sMSRRepEIDs[0]);
110 pMgmt->uLengthOfRepEIDs = 0;
111 bResult = CARDbStartMeasure(pMgmt->pAdapter,
112 ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->sMSRReqEIDs,
113 uNumOfEIDs
114 );
115 return (bResult);
116}
117
118
119static BOOL s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, BYTE byRate, BYTE byRSSI)
120{
121 PWLAN_FRAME_TPCREP pFrame;
122 PSTxMgmtPacket pTxPacket = NULL;
123
124
125 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
126 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
127 pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
128
129 pFrame = (PWLAN_FRAME_TPCREP)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
130
131 pFrame->Header.wFrameCtl = ( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
132 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
133 );
134
51b6d9c2
JL
135 memcpy( pFrame->Header.abyAddr1, pTPCReq->Header.abyAddr2, WLAN_ADDR_LEN);
136 memcpy( pFrame->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
137 memcpy( pFrame->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
5449c685
FB
138
139 pFrame->byCategory = 0;
140 pFrame->byAction = 3;
141 pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken;
142
143 pFrame->sTPCRepEIDs.byElementID = WLAN_EID_TPC_REP;
144 pFrame->sTPCRepEIDs.len = 2;
145 pFrame->sTPCRepEIDs.byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
146 switch (byRate) {
147 case RATE_54M:
148 pFrame->sTPCRepEIDs.byLinkMargin = 65 - byRSSI;
149 break;
150 case RATE_48M:
151 pFrame->sTPCRepEIDs.byLinkMargin = 66 - byRSSI;
152 break;
153 case RATE_36M:
154 pFrame->sTPCRepEIDs.byLinkMargin = 70 - byRSSI;
155 break;
156 case RATE_24M:
157 pFrame->sTPCRepEIDs.byLinkMargin = 74 - byRSSI;
158 break;
159 case RATE_18M:
160 pFrame->sTPCRepEIDs.byLinkMargin = 77 - byRSSI;
161 break;
162 case RATE_12M:
163 pFrame->sTPCRepEIDs.byLinkMargin = 79 - byRSSI;
164 break;
165 case RATE_9M:
166 pFrame->sTPCRepEIDs.byLinkMargin = 81 - byRSSI;
167 break;
168 case RATE_6M:
169 default:
170 pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI;
171 break;
172 }
173
174 pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP);
175 pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) - WLAN_HDR_ADDR3_LEN;
176 if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
177 return (FALSE);
178 return (TRUE);
179// return (CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG, sizeof(WLAN_FRAME_TPCREP)));
180
181}
182
183
184/*--------------------- Export Variables --------------------------*/
185
186/*--------------------- Export Functions --------------------------*/
187
188
189/*+
190 *
191 * Description:
192 * Handles action management frames.
193 *
194 * Parameters:
195 * In:
196 * pMgmt - Management Object structure
197 * pRxPacket - Received packet
198 * Out:
199 * none
200 *
201 * Return Value: None.
202 *
203-*/
204BOOL
205IEEE11hbMgrRxAction (
3a215e0f
CC
206 void *pMgmtHandle,
207 void *pRxPacket
5449c685
FB
208 )
209{
210 PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle;
211 PWLAN_FRAME_ACTION pAction = NULL;
212 UINT uLength = 0;
213 PWLAN_IE_CH_SW pChannelSwitch = NULL;
214
215
216 // decode the frame
217 uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen;
218 if (uLength > WLAN_A3FR_MAXLEN) {
219 return (FALSE);
220 }
221
222
223 pAction = (PWLAN_FRAME_ACTION) (((PSRxMgmtPacket)pRxPacket)->p80211Header);
224
225 if (pAction->byCategory == 0) {
226 switch (pAction->byAction) {
227 case ACTION_MSRREQ:
228 return (s_bRxMSRReq(pMgmt, (PWLAN_FRAME_MSRREQ) pAction, uLength));
229 break;
230 case ACTION_MSRREP:
231 break;
232 case ACTION_TPCREQ:
233 return (s_bRxTPCReq(pMgmt,
234 (PWLAN_FRAME_TPCREQ) pAction,
235 ((PSRxMgmtPacket)pRxPacket)->byRxRate,
236 (BYTE) ((PSRxMgmtPacket)pRxPacket)->uRSSI));
237 break;
238 case ACTION_TPCREP:
239 break;
240 case ACTION_CHSW:
241 pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars);
242 if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH) &&
243 (pChannelSwitch->len == 3)) {
244 // valid element id
245 CARDbChannelSwitch( pMgmt->pAdapter,
246 pChannelSwitch->byMode,
247 CARDbyGetChannelMapping(pMgmt->pAdapter, pChannelSwitch->byChannel, pMgmt->eCurrentPHYMode),
248 pChannelSwitch->byCount
249 );
250 }
251 break;
252 default:
7e809a9b 253 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Action = %d\n", pAction->byAction);
5449c685
FB
254 break;
255 }
256 } else {
7e809a9b 257 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n", pAction->byCategory);
5449c685
FB
258 pAction->byCategory |= 0x80;
259
260 //return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG, uLength));
261 return (TRUE);
262 }
263 return (TRUE);
264}
265
266
267BOOL IEEE11hbMSRRepTx (
3a215e0f 268 void *pMgmtHandle
5449c685
FB
269 )
270{
271 PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle;
272 PWLAN_FRAME_MSRREP pMSRRep = (PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket));
db6cb903 273 size_t uLength = 0;
5449c685
FB
274 PSTxMgmtPacket pTxPacket = NULL;
275
276 pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep;
277 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
278 pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
279
280
281 pMSRRep->Header.wFrameCtl = ( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
282 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
283 );
284
51b6d9c2
JL
285 memcpy( pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN);
286 memcpy( pMSRRep->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
287 memcpy( pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
5449c685
FB
288
289 pMSRRep->byCategory = 0;
290 pMSRRep->byAction = 1;
291 pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken;
292
db6cb903 293 uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP, sMSRRepEIDs);
5449c685
FB
294
295 pTxPacket->cbMPDULen = uLength;
296 pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN;
297 if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
298 return (FALSE);
299 return (TRUE);
300// return (CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG, uLength));
301
302}
303