]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/vt6655/IEEE11h.c
Merge tag 'remoteproc-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/ohad...
[karo-tx-linux.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 #include "channel.h"
42
43 /*---------------------  Static Definitions -------------------------*/
44 static int          msglevel                = MSG_LEVEL_INFO;
45
46 #pragma pack(1)
47
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;
54
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;
62
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;
70
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;
78
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;
86
87 #pragma pack()
88
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
95
96 /*---------------------  Static Classes  ----------------------------*/
97
98 /*---------------------  Static Variables  --------------------------*/
99
100 /*---------------------  Static Functions  --------------------------*/
101 static bool s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq,
102                         unsigned int uLength)
103 {
104         size_t    uNumOfEIDs = 0;
105         bool bResult = true;
106
107         if (uLength <= WLAN_A3FR_MAXLEN)
108                 memcpy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength);
109         uNumOfEIDs = ((uLength - offsetof(WLAN_FRAME_MSRREQ,
110                                           sMSRReqEIDs))/
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,
118                                     uNumOfEIDs
119 );
120         return bResult;
121 }
122
123 static bool s_bRxTPCReq(PSMgmtObject pMgmt,
124                         PWLAN_FRAME_TPCREQ pTPCReq,
125                         unsigned char byRate,
126                         unsigned char byRSSI)
127 {
128         PWLAN_FRAME_TPCREP  pFrame;
129         PSTxMgmtPacket      pTxPacket = NULL;
130
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));
135
136         pFrame = (PWLAN_FRAME_TPCREP)((unsigned char *)pTxPacket +
137                                       sizeof(STxMgmtPacket));
138
139         pFrame->Header.wFrameCtl = (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
140                                     WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
141 );
142
143         memcpy(pFrame->Header.abyAddr1,
144                pTPCReq->Header.abyAddr2,
145                WLAN_ADDR_LEN);
146         memcpy(pFrame->Header.abyAddr2,
147                CARDpGetCurrentAddress(pMgmt->pAdapter),
148                WLAN_ADDR_LEN);
149         memcpy(pFrame->Header.abyAddr3,
150                pMgmt->abyCurrBSSID,
151                WLAN_BSSID_LEN);
152
153         pFrame->byCategory = 0;
154         pFrame->byAction = 3;
155         pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ)
156                                  (pMgmt->abyCurrentMSRReq))->byDialogToken;
157
158         pFrame->sTPCRepEIDs.byElementID = WLAN_EID_TPC_REP;
159         pFrame->sTPCRepEIDs.len = 2;
160         pFrame->sTPCRepEIDs.byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
161         switch (byRate) {
162         case RATE_54M:
163                 pFrame->sTPCRepEIDs.byLinkMargin = 65 - byRSSI;
164                 break;
165         case RATE_48M:
166                 pFrame->sTPCRepEIDs.byLinkMargin = 66 - byRSSI;
167                 break;
168         case RATE_36M:
169                 pFrame->sTPCRepEIDs.byLinkMargin = 70 - byRSSI;
170                 break;
171         case RATE_24M:
172                 pFrame->sTPCRepEIDs.byLinkMargin = 74 - byRSSI;
173                 break;
174         case RATE_18M:
175                 pFrame->sTPCRepEIDs.byLinkMargin = 77 - byRSSI;
176                 break;
177         case RATE_12M:
178                 pFrame->sTPCRepEIDs.byLinkMargin = 79 - byRSSI;
179                 break;
180         case RATE_9M:
181                 pFrame->sTPCRepEIDs.byLinkMargin = 81 - byRSSI;
182                 break;
183         case RATE_6M:
184         default:
185                 pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI;
186                 break;
187         }
188
189         pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP);
190         pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) -
191                 WLAN_HDR_ADDR3_LEN;
192         if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
193                 return false;
194         return true;
195 /*    return CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG,
196       sizeof(WLAN_FRAME_TPCREP)); */
197 }
198
199 /*---------------------  Export Variables  --------------------------*/
200
201 /*---------------------  Export Functions  --------------------------*/
202
203 /*+
204  *
205  * Description:
206  *      Handles action management frames.
207  *
208  * Parameters:
209  *  In:
210  *      pMgmt           - Management Object structure
211  *      pRxPacket       - Received packet
212  *  Out:
213  *      none
214  *
215  * Return Value: None.
216  *
217  -*/
218 bool
219 IEEE11hbMgrRxAction(void *pMgmtHandle, void *pRxPacket)
220 {
221         PSMgmtObject            pMgmt = (PSMgmtObject) pMgmtHandle;
222         PWLAN_FRAME_ACTION      pAction = NULL;
223         unsigned int uLength = 0;
224         PWLAN_IE_CH_SW          pChannelSwitch = NULL;
225
226         /* decode the frame */
227         uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen;
228         if (uLength > WLAN_A3FR_MAXLEN)
229                 return false;
230
231         pAction = (PWLAN_FRAME_ACTION)
232                 (((PSRxMgmtPacket)pRxPacket)->p80211Header);
233
234         if (pAction->byCategory == 0) {
235                 switch (pAction->byAction) {
236                 case ACTION_MSRREQ:
237                         return s_bRxMSRReq(pMgmt,
238                                            (PWLAN_FRAME_MSRREQ)
239                                            pAction,
240                                            uLength);
241                         break;
242                 case ACTION_MSRREP:
243                         break;
244                 case ACTION_TPCREQ:
245                         return s_bRxTPCReq(pMgmt,
246                                            (PWLAN_FRAME_TPCREQ) pAction,
247                                            ((PSRxMgmtPacket)pRxPacket)->byRxRate,
248                                            (unsigned char)
249                                            ((PSRxMgmtPacket)pRxPacket)->uRSSI);
250                         break;
251                 case ACTION_TPCREP:
252                         break;
253                 case ACTION_CHSW:
254                         pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars);
255                         if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH)
256                             && (pChannelSwitch->len == 3)) {
257                                 /* valid element id */
258                                 CARDbChannelSwitch(pMgmt->pAdapter,
259                                                    pChannelSwitch->byMode,
260                                                    get_channel_mapping(pMgmt->pAdapter,
261                                                                        pChannelSwitch->byChannel,
262                                                                        pMgmt->eCurrentPHYMode),
263                                                    pChannelSwitch->byCount);
264                         }
265                         break;
266                 default:
267                         DBG_PRT(MSG_LEVEL_DEBUG,
268                                 KERN_INFO "Unknown Action = %d\n",
269                                 pAction->byAction);
270                         break;
271                 }
272         } else {
273                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unknown Category = %d\n",
274                         pAction->byCategory);
275                 pAction->byCategory |= 0x80;
276
277                 /*return CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG,
278                   uLength);*/
279                 return true;
280         }
281         return true;
282 }
283
284 bool IEEE11hbMSRRepTx(void *pMgmtHandle)
285 {
286         PSMgmtObject            pMgmt = (PSMgmtObject) pMgmtHandle;
287         PWLAN_FRAME_MSRREP      pMSRRep = (PWLAN_FRAME_MSRREP)
288                 (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket));
289         size_t                    uLength = 0;
290         PSTxMgmtPacket          pTxPacket = NULL;
291
292         pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep;
293         memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
294         pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket +
295                                                     sizeof(STxMgmtPacket));
296
297         pMSRRep->Header.wFrameCtl = (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
298                                      WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
299 );
300
301         memcpy(pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ)
302                                           (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN);
303         memcpy(pMSRRep->Header.abyAddr2,
304                CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
305         memcpy(pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
306
307         pMSRRep->byCategory = 0;
308         pMSRRep->byAction = 1;
309         pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ)
310                                   (pMgmt->abyCurrentMSRReq))->byDialogToken;
311
312         uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP,
313                                                      sMSRRepEIDs);
314
315         pTxPacket->cbMPDULen = uLength;
316         pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN;
317         if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
318                 return false;
319         return true;
320 /*    return CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG,
321       uLength); */
322 }