1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
44static int msglevel = MSG_LEVEL_INFO;
45
46#pragma pack(1)
47
48typedef 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
55typedef 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
63typedef 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
71typedef 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
79typedef 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
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
97
98
99
100
101static 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
123static 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
196
197}
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218bool
219IEEE11hbMgrRxAction(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
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
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
278
279 return true;
280 }
281 return true;
282}
283
284bool 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
321
322}
323