Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
IEEE11h.c
Go to the documentation of this file.
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];
54 
55 typedef struct _WLAN_FRAME_MSRREQ {
56  WLAN_80211HDR_A3 Header;
57  unsigned char byCategory;
58  unsigned char byAction;
59  unsigned char byDialogToken;
62 
63 typedef struct _WLAN_FRAME_MSRREP {
64  WLAN_80211HDR_A3 Header;
65  unsigned char byCategory;
66  unsigned char byAction;
67  unsigned char byDialogToken;
70 
71 typedef struct _WLAN_FRAME_TPCREQ {
72  WLAN_80211HDR_A3 Header;
73  unsigned char byCategory;
74  unsigned char byAction;
75  unsigned char byDialogToken;
78 
79 typedef struct _WLAN_FRAME_TPCREP {
80  WLAN_80211HDR_A3 Header;
81  unsigned char byCategory;
82  unsigned char byAction;
83  unsigned char byDialogToken;
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)));
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 
124 static bool s_bRxTPCReq(PSMgmtObject pMgmt,
125  PWLAN_FRAME_TPCREQ pTPCReq,
126  unsigned char byRate,
127  unsigned char byRSSI)
128 {
129  PWLAN_FRAME_TPCREP pFrame;
130  PSTxMgmtPacket pTxPacket = NULL;
131 
132  pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
133  memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
134  pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket +
135 sizeof(STxMgmtPacket));
136 
137  pFrame = (PWLAN_FRAME_TPCREP)((unsigned char *)pTxPacket +
138 sizeof(STxMgmtPacket));
139 
140  pFrame->Header.wFrameCtl = (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
142  );
143 
144  memcpy(pFrame->Header.abyAddr1,
145  pTPCReq->Header.abyAddr2,
146  WLAN_ADDR_LEN);
147  memcpy(pFrame->Header.abyAddr2,
149  WLAN_ADDR_LEN);
150  memcpy(pFrame->Header.abyAddr3,
151  pMgmt->abyCurrBSSID,
153 
154  pFrame->byCategory = 0;
155  pFrame->byAction = 3;
156  pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ)
157 (pMgmt->abyCurrentMSRReq))->byDialogToken;
158 
160  pFrame->sTPCRepEIDs.len = 2;
162  switch (byRate) {
163  case RATE_54M:
164  pFrame->sTPCRepEIDs.byLinkMargin = 65 - byRSSI;
165  break;
166  case RATE_48M:
167  pFrame->sTPCRepEIDs.byLinkMargin = 66 - byRSSI;
168  break;
169  case RATE_36M:
170  pFrame->sTPCRepEIDs.byLinkMargin = 70 - byRSSI;
171  break;
172  case RATE_24M:
173  pFrame->sTPCRepEIDs.byLinkMargin = 74 - byRSSI;
174  break;
175  case RATE_18M:
176  pFrame->sTPCRepEIDs.byLinkMargin = 77 - byRSSI;
177  break;
178  case RATE_12M:
179  pFrame->sTPCRepEIDs.byLinkMargin = 79 - byRSSI;
180  break;
181  case RATE_9M:
182  pFrame->sTPCRepEIDs.byLinkMargin = 81 - byRSSI;
183  break;
184  case RATE_6M:
185  default:
186  pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI;
187  break;
188 }
189 
190  pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP);
191  pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) -
193  if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
194  return false;
195  return true;
196 /* return (CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG,
197 sizeof(WLAN_FRAME_TPCREP))); */
198 
199 }
200 
201 
202 /*--------------------- Export Variables --------------------------*/
203 
204 /*--------------------- Export Functions --------------------------*/
205 
206 
207 /*+
208  *
209  * Description:
210  * Handles action management frames.
211  *
212  * Parameters:
213  * In:
214  * pMgmt - Management Object structure
215  * pRxPacket - Received packet
216  * Out:
217  * none
218  *
219  * Return Value: None.
220  *
221 -*/
222 bool
223 IEEE11hbMgrRxAction(void *pMgmtHandle, void *pRxPacket)
224 {
225  PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle;
226  PWLAN_FRAME_ACTION pAction = NULL;
227  unsigned int uLength = 0;
228  PWLAN_IE_CH_SW pChannelSwitch = NULL;
229 
230  /* decode the frame */
231  uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen;
232  if (uLength > WLAN_A3FR_MAXLEN)
233  return false;
234 
235  pAction = (PWLAN_FRAME_ACTION)
236 (((PSRxMgmtPacket)pRxPacket)->p80211Header);
237 
238  if (pAction->byCategory == 0) {
239  switch (pAction->byAction) {
240  case ACTION_MSRREQ:
241  return s_bRxMSRReq(pMgmt,
242  (PWLAN_FRAME_MSRREQ)
243  pAction,
244  uLength);
245  break;
246  case ACTION_MSRREP:
247  break;
248  case ACTION_TPCREQ:
249  return s_bRxTPCReq(pMgmt,
250  (PWLAN_FRAME_TPCREQ) pAction,
251  ((PSRxMgmtPacket)pRxPacket)->byRxRate,
252  (unsigned char)
253  ((PSRxMgmtPacket)pRxPacket)->uRSSI);
254  break;
255  case ACTION_TPCREP:
256  break;
257  case ACTION_CHSW:
258  pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars);
259  if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH)
260  && (pChannelSwitch->len == 3)) {
261  /* valid element id */
263  pChannelSwitch->byMode,
265  pChannelSwitch->byChannel,
266  pMgmt->eCurrentPHYMode),
267  pChannelSwitch->byCount);
268  }
269  break;
270  default:
272  KERN_INFO"Unknown Action = %d\n",
273  pAction->byAction);
274  break;
275  }
276  } else {
277  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n",
278 pAction->byCategory);
279  pAction->byCategory |= 0x80;
280 
281  /*return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG,
282 uLength));*/
283  return true;
284  }
285  return true;
286 }
287 
288 
289 bool IEEE11hbMSRRepTx(void *pMgmtHandle)
290 {
291  PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle;
292  PWLAN_FRAME_MSRREP pMSRRep = (PWLAN_FRAME_MSRREP)
293 (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket));
294  size_t uLength = 0;
295  PSTxMgmtPacket pTxPacket = NULL;
296 
297  pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep;
298  memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
299  pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket +
300 sizeof(STxMgmtPacket));
301 
302  pMSRRep->Header.wFrameCtl = (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
304  );
305 
306  memcpy(pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ)
307  (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN);
308  memcpy(pMSRRep->Header.abyAddr2,
310  memcpy(pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
311 
312  pMSRRep->byCategory = 0;
313  pMSRRep->byAction = 1;
314  pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ)
315  (pMgmt->abyCurrentMSRReq))->byDialogToken;
316 
317  uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP,
318  sMSRRepEIDs);
319 
320  pTxPacket->cbMPDULen = uLength;
321  pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN;
322  if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
323  return false;
324  return true;
325 /* return (CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG,
326 uLength)); */
327 
328 }
329