Merge branch 'kbuild/clean' into kbuild/kbuild
[pandora-kernel.git] / drivers / staging / vt6655 / IEEE11h.c
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
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
42 /*---------------------  Static Definitions -------------------------*/
43 static int          msglevel                =MSG_LEVEL_INFO;
44
45 #pragma pack(1)
46
47 typedef 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
54 typedef 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
62 typedef 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
70 typedef 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
78 typedef 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  --------------------------*/
100 static BOOL s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq, UINT uLength)
101 {
102     size_t    uNumOfEIDs = 0;
103     BOOL    bResult = TRUE;
104
105     if (uLength <= WLAN_A3FR_MAXLEN) {
106         memcpy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength);
107     }
108     uNumOfEIDs = ((uLength - offsetof(WLAN_FRAME_MSRREQ, sMSRReqEIDs))/ (sizeof(WLAN_IE_MEASURE_REQ)));
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
119 static 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
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);
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 -*/
204 BOOL
205 IEEE11hbMgrRxAction (
206     void *pMgmtHandle,
207     void *pRxPacket
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:
253                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Action = %d\n", pAction->byAction);
254                 break;
255         }
256     } else {
257         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n", pAction->byCategory);
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
267 BOOL IEEE11hbMSRRepTx (
268     void *pMgmtHandle
269     )
270 {
271     PSMgmtObject            pMgmt = (PSMgmtObject) pMgmtHandle;
272     PWLAN_FRAME_MSRREP      pMSRRep = (PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket));
273     size_t                    uLength = 0;
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
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);
288
289     pMSRRep->byCategory = 0;
290     pMSRRep->byAction = 1;
291     pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken;
292
293     uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP, sMSRRepEIDs);
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