1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#define _RTW_MLME_EXT_C_
16
17#include <drv_types.h>
18#include <rtw_debug.h>
19#include <rtw_wifi_regd.h>
20#include <linux/kernel.h>
21
22
23static struct mlme_handler mlme_sta_tbl[] = {
24 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
25 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
26 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
27 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
28 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
29 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
30
31
32
33
34 {0, "DoReserved", &DoReserved},
35 {0, "DoReserved", &DoReserved},
36 {WIFI_BEACON, "OnBeacon", &OnBeacon},
37 {WIFI_ATIM, "OnATIM", &OnAtim},
38 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
39 {WIFI_AUTH, "OnAuth", &OnAuthClient},
40 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
41 {WIFI_ACTION, "OnAction", &OnAction},
42 {WIFI_ACTION_NOACK, "OnActionNoAck", &OnAction},
43};
44
45static struct action_handler OnAction_tbl[] = {
46 {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct},
47 {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &DoReserved},
48 {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &DoReserved},
49 {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
50 {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
51 {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved},
52 {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved},
53 {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht},
54 {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query},
55 {RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved},
56 {RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &DoReserved},
57 {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &DoReserved},
58 {RTW_WLAN_CATEGORY_VHT, "ACTION_VHT", &DoReserved},
59 {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &DoReserved},
60};
61
62
63static u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
64
65
66
67
68unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
69unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
70unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
71unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09};
72unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A};
73
74unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
75unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
76
77static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
78
79
80
81
82static RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
83 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
84 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
85 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
86 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
87 {{10, 11, 12, 13}, 4},
88 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
89 {{}, 0},
90};
91
92static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
93 {{}, 0},
94 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19},
95 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
96 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22},
97 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
98 {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},
99 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},
100 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12},
101 {{149, 153, 157, 161, 165}, 5},
102 {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
103 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20},
104 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 20},
105 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19},
106 {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
107 {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},
108 {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 15},
109 {{56, 60, 64, 149, 153, 157, 161, 165}, 8},
110 {{149, 153, 157, 161, 165}, 5},
111 {{36, 40, 44, 48}, 4},
112 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20},
113 {{149, 153, 157, 161}, 4},
114 {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
115 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},
116 {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},
117 {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},
118 {{149, 153, 157, 161, 165}, 5},
119 {{36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, 149, 153, 157, 161, 165}, 16},
120 {{52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 17},
121 {{149, 153, 157, 161}, 4},
122 {{36, 40, 44, 48, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 17},
123 {{36, 40, 44, 48, 100, 104, 108, 112, 116, 132, 136, 140}, 12},
124 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161}, 20},
125
126
127 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},
128 {{36, 40, 44, 48}, 4},
129 {{36, 40, 44, 48, 149, 153, 157, 161}, 8},
130};
131
132static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
133
134 {0x02, 0x20},
135 {0x02, 0x0A},
136 {0x01, 0x01},
137 {0x01, 0x00},
138 {0x01, 0x00},
139 {0x03, 0x00},
140 {0x03, 0x00},
141 {0x01, 0x09},
142 {0x03, 0x09},
143 {0x03, 0x00},
144 {0x00, 0x00},
145 {0x02, 0x0F},
146 {0x01, 0x08},
147 {0x02, 0x06},
148 {0x02, 0x0B},
149 {0x02, 0x09},
150 {0x01, 0x01},
151 {0x02, 0x05},
152 {0x01, 0x21},
153 {0x00, 0x04},
154 {0x02, 0x10},
155 {0x00, 0x21},
156 {0x00, 0x22},
157 {0x03, 0x21},
158 {0x06, 0x08},
159 {0x02, 0x08},
160 {0x00, 0x00},
161 {0x00, 0x00},
162 {0x00, 0x00},
163 {0x00, 0x00},
164 {0x00, 0x00},
165 {0x06, 0x04},
166
167 {0x00, 0x00},
168 {0x01, 0x00},
169 {0x02, 0x00},
170 {0x03, 0x00},
171 {0x04, 0x00},
172 {0x02, 0x04},
173 {0x00, 0x01},
174 {0x03, 0x0C},
175 {0x00, 0x0B},
176 {0x00, 0x05},
177 {0x00, 0x00},
178 {0x00, 0x00},
179 {0x00, 0x00},
180 {0x00, 0x00},
181 {0x00, 0x00},
182 {0x00, 0x00},
183 {0x00, 0x06},
184 {0x00, 0x07},
185 {0x00, 0x08},
186 {0x00, 0x09},
187 {0x02, 0x0A},
188 {0x00, 0x02},
189 {0x00, 0x03},
190 {0x03, 0x0D},
191 {0x03, 0x0E},
192 {0x02, 0x0F},
193 {0x00, 0x00},
194 {0x00, 0x00},
195 {0x00, 0x00},
196 {0x00, 0x00},
197 {0x00, 0x00},
198 {0x00, 0x00},
199 {0x02, 0x10},
200 {0x05, 0x00},
201 {0x01, 0x12},
202 {0x02, 0x05},
203 {0x02, 0x11},
204 {0x00, 0x13},
205 {0x02, 0x14},
206 {0x00, 0x15},
207 {0x00, 0x16},
208 {0x00, 0x17},
209 {0x00, 0x18},
210 {0x00, 0x19},
211 {0x00, 0x1A},
212 {0x02, 0x1B},
213 {0x00, 0x1C},
214 {0x02, 0x1D},
215 {0x00, 0x1E},
216 {0x02, 0x1F},
217};
218
219static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03, 0x02};
220
221
222
223
224
225
226
227
228int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
229{
230 int i;
231 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
232 if (ch == ch_set[i].ChannelNum)
233 break;
234 }
235
236 if (i >= ch_set[i].ChannelNum)
237 return -1;
238 return i;
239}
240
241
242
243
244
245
246
247
248bool rtw_mlme_band_check(struct adapter *adapter, const u32 ch)
249{
250 if (adapter->setband == GHZ24_50
251 || (adapter->setband == GHZ_24 && ch < 35)
252 || (adapter->setband == GHZ_50 && ch > 35)
253 ) {
254 return true;
255 }
256 return false;
257}
258
259
260
261
262
263
264
265int init_hw_mlme_ext(struct adapter *padapter)
266{
267 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
268
269 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
270 return _SUCCESS;
271}
272
273void init_mlme_default_rate_set(struct adapter *padapter)
274{
275 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
276
277 unsigned char mixed_datarate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_, _48M_RATE_, _54M_RATE_, 0xff};
278 unsigned char mixed_basicrate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,};
279 unsigned char supported_mcs_set[16] = {0xff, 0xff, 0x00, 0x00, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
280
281 memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
282 memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
283
284 memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set));
285}
286
287static void init_mlme_ext_priv_value(struct adapter *padapter)
288{
289 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
290 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
291
292 atomic_set(&pmlmeext->event_seq, 0);
293 pmlmeext->mgnt_seq = 0;
294 pmlmeext->sa_query_seq = 0;
295 pmlmeext->mgnt_80211w_IPN = 0;
296 pmlmeext->mgnt_80211w_IPN_rx = 0;
297 pmlmeext->cur_channel = padapter->registrypriv.channel;
298 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
299 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
300
301 pmlmeext->retry = 0;
302
303 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
304
305 init_mlme_default_rate_set(padapter);
306
307 if (pmlmeext->cur_channel > 14)
308 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
309 else
310 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
311
312 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
313 pmlmeext->sitesurvey_res.channel_idx = 0;
314 pmlmeext->sitesurvey_res.bss_cnt = 0;
315 pmlmeext->scan_abort = false;
316
317 pmlmeinfo->state = WIFI_FW_NULL_STATE;
318 pmlmeinfo->reauth_count = 0;
319 pmlmeinfo->reassoc_count = 0;
320 pmlmeinfo->link_count = 0;
321 pmlmeinfo->auth_seq = 0;
322 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
323 pmlmeinfo->key_index = 0;
324 pmlmeinfo->iv = 0;
325
326 pmlmeinfo->enc_algo = _NO_PRIVACY_;
327 pmlmeinfo->authModeToggle = 0;
328
329 memset(pmlmeinfo->chg_txt, 0, 128);
330
331 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
332 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
333
334 pmlmeinfo->dialogToken = 0;
335
336 pmlmeext->action_public_rxseq = 0xffff;
337 pmlmeext->action_public_dialog_token = 0xff;
338}
339
340static int has_channel(RT_CHANNEL_INFO *channel_set,
341 u8 chanset_size,
342 u8 chan) {
343 int i;
344
345 for (i = 0; i < chanset_size; i++) {
346 if (channel_set[i].ChannelNum == chan) {
347 return 1;
348 }
349 }
350
351 return 0;
352}
353
354static void init_channel_list(struct adapter *padapter, RT_CHANNEL_INFO *channel_set,
355 u8 chanset_size,
356 struct p2p_channels *channel_list) {
357
358 struct p2p_oper_class_map op_class[] = {
359 { IEEE80211G, 81, 1, 13, 1, BW20 },
360 { IEEE80211G, 82, 14, 14, 1, BW20 },
361 { IEEE80211A, 115, 36, 48, 4, BW20 },
362 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
363 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
364 { IEEE80211A, 124, 149, 161, 4, BW20 },
365 { IEEE80211A, 125, 149, 169, 4, BW20 },
366 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
367 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
368 { -1, 0, 0, 0, 0, BW20 }
369 };
370
371 int cla, op;
372
373 cla = 0;
374
375 for (op = 0; op_class[op].op_class; op++) {
376 u8 ch;
377 struct p2p_oper_class_map *o = &op_class[op];
378 struct p2p_reg_class *reg = NULL;
379
380 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
381 if (!has_channel(channel_set, chanset_size, ch)) {
382 continue;
383 }
384
385 if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
386 continue;
387
388 if ((0 < (padapter->registrypriv.bw_mode & 0xf0)) &&
389 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
390 continue;
391
392 if (reg == NULL) {
393 reg = &channel_list->reg_class[cla];
394 cla++;
395 reg->reg_class = o->op_class;
396 reg->channels = 0;
397 }
398 reg->channel[reg->channels] = ch;
399 reg->channels++;
400 }
401 }
402 channel_list->reg_classes = cla;
403
404}
405
406static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set)
407{
408 u8 index, chanset_size = 0;
409 u8 b5GBand = false, b2_4GBand = false;
410 u8 Index2G = 0, Index5G = 0;
411
412 memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM);
413
414 if (ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) {
415 DBG_871X("ChannelPlan ID %x error !!!!!\n", ChannelPlan);
416 return chanset_size;
417 }
418
419 if (IsSupported24G(padapter->registrypriv.wireless_mode)) {
420 b2_4GBand = true;
421 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
422 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
423 else
424 Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
425 }
426
427 if (b2_4GBand) {
428 for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) {
429 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
430
431 if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||
432 (RT_CHANNEL_DOMAIN_GLOBAL_NULL == ChannelPlan)) {
433 if (channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
434 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
435 else if ((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14))
436 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
437 } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan ||
438 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan ||
439 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) {
440 if (channel_set[chanset_size].ChannelNum <= 11)
441 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
442 else
443 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
444 } else
445 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
446
447 chanset_size++;
448 }
449 }
450
451 if (b5GBand) {
452 for (index = 0; index < RTW_ChannelPlan5G[Index5G].Len; index++) {
453 if (RTW_ChannelPlan5G[Index5G].Channel[index] <= 48
454 || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149) {
455 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
456 if (RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)
457 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
458 else
459 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
460 DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __func__, chanset_size, channel_set[chanset_size].ChannelNum);
461 chanset_size++;
462 }
463 }
464 }
465
466 DBG_871X("%s ChannelPlan ID %x Chan num:%d \n", __func__, ChannelPlan, chanset_size);
467 return chanset_size;
468}
469
470int init_mlme_ext_priv(struct adapter *padapter)
471{
472 int res = _SUCCESS;
473 struct registry_priv *pregistrypriv = &padapter->registrypriv;
474 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
475 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
476 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
477
478 pmlmeext->padapter = padapter;
479
480
481
482 init_mlme_ext_priv_value(padapter);
483 pmlmeinfo->accept_addba_req = pregistrypriv->accept_addba_req;
484
485 init_mlme_ext_timer(padapter);
486
487 init_mlme_ap_info(padapter);
488
489 pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan, pmlmeext->channel_set);
490 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
491 pmlmeext->last_scan_time = 0;
492 pmlmeext->chan_scan_time = SURVEY_TO;
493 pmlmeext->mlmeext_init = true;
494 pmlmeext->active_keep_alive_check = true;
495
496#ifdef DBG_FIXED_CHAN
497 pmlmeext->fixed_chan = 0xFF;
498#endif
499
500 return res;
501
502}
503
504void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext)
505{
506 struct adapter *padapter = pmlmeext->padapter;
507
508 if (!padapter)
509 return;
510
511 if (padapter->bDriverStopped) {
512 del_timer_sync(&pmlmeext->survey_timer);
513 del_timer_sync(&pmlmeext->link_timer);
514
515 }
516}
517
518static void _mgt_dispatcher(struct adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
519{
520 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
521 u8 *pframe = precv_frame->u.hdr.rx_data;
522
523 if (ptable->func) {
524
525 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
526 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
527 return;
528
529 ptable->func(padapter, precv_frame);
530 }
531}
532
533void mgt_dispatcher(struct adapter *padapter, union recv_frame *precv_frame)
534{
535 int index;
536 struct mlme_handler *ptable;
537 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
538 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
539 u8 *pframe = precv_frame->u.hdr.rx_data;
540 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
541 struct dvobj_priv *psdpriv = padapter->dvobj;
542 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
543
544 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
545 ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
546 GetFrameType(pframe), GetFrameSubType(pframe)));
547
548 if (GetFrameType(pframe) != WIFI_MGT_TYPE) {
549 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe)));
550 return;
551 }
552
553
554 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
555 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) {
556 return;
557 }
558
559 ptable = mlme_sta_tbl;
560
561 index = GetFrameSubType(pframe) >> 4;
562
563 if (index >= ARRAY_SIZE(mlme_sta_tbl)) {
564 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Currently we do not support reserved sub-fr-type =%d\n", index));
565 return;
566 }
567 ptable += index;
568
569 if (psta != NULL) {
570 if (GetRetry(pframe)) {
571 if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum) {
572
573 pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++;
574 DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
575 return;
576 }
577 }
578 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
579 }
580
581 switch (GetFrameSubType(pframe)) {
582 case WIFI_AUTH:
583 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
584 ptable->func = &OnAuth;
585 else
586 ptable->func = &OnAuthClient;
587
588 case WIFI_ASSOCREQ:
589 case WIFI_REASSOCREQ:
590 _mgt_dispatcher(padapter, ptable, precv_frame);
591 break;
592 case WIFI_PROBEREQ:
593 _mgt_dispatcher(padapter, ptable, precv_frame);
594 break;
595 case WIFI_BEACON:
596 _mgt_dispatcher(padapter, ptable, precv_frame);
597 break;
598 case WIFI_ACTION:
599
600 _mgt_dispatcher(padapter, ptable, precv_frame);
601 break;
602 default:
603 _mgt_dispatcher(padapter, ptable, precv_frame);
604 break;
605 }
606}
607
608
609
610
611
612
613
614unsigned int OnProbeReq(struct adapter *padapter, union recv_frame *precv_frame)
615{
616 unsigned int ielen;
617 unsigned char *p;
618 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
619 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
620 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
621 struct wlan_bssid_ex *cur = &(pmlmeinfo->network);
622 u8 *pframe = precv_frame->u.hdr.rx_data;
623 uint len = precv_frame->u.hdr.len;
624 u8 is_valid_p2p_probereq = false;
625
626 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
627 return _SUCCESS;
628
629 if (check_fwstate(pmlmepriv, _FW_LINKED) == false &&
630 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == false) {
631 return _SUCCESS;
632 }
633
634
635
636
637#ifdef CONFIG_AUTO_AP_MODE
638 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
639 pmlmepriv->cur_network.join_res) {
640 struct sta_info *psta;
641 u8 *mac_addr, *peer_addr;
642 struct sta_priv *pstapriv = &padapter->stapriv;
643 u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A};
644
645
646 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
647 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
648
649 if (!p || ielen != 14)
650 goto _non_rc_device;
651
652 if (memcmp(p+2, RC_OUI, sizeof(RC_OUI)))
653 goto _non_rc_device;
654
655 if (memcmp(p+6, get_sa(pframe), ETH_ALEN)) {
656 DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __func__,
657 MAC_ARG(get_sa(pframe)), MAC_ARG(p+6));
658
659 goto _non_rc_device;
660 }
661
662 DBG_871X("%s, got the pairing device("MAC_FMT")\n", __func__, MAC_ARG(get_sa(pframe)));
663
664
665 psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
666 if (psta == NULL) {
667
668 DBG_871X("going to alloc stainfo for rc ="MAC_FMT"\n", MAC_ARG(get_sa(pframe)));
669 psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
670 if (psta == NULL) {
671
672 DBG_871X(" Exceed the upper limit of supported clients...\n");
673 return _SUCCESS;
674 }
675
676 spin_lock_bh(&pstapriv->asoc_list_lock);
677 if (list_empty(&psta->asoc_list)) {
678 psta->expire_to = pstapriv->expire_to;
679 list_add_tail(&psta->asoc_list, &pstapriv->asoc_list);
680 pstapriv->asoc_list_cnt++;
681 }
682 spin_unlock_bh(&pstapriv->asoc_list_lock);
683
684
685 mac_addr = myid(&(padapter->eeprompriv));
686 peer_addr = psta->hwaddr;
687 psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5]));
688
689
690 psta->isrc = true;
691
692
693
694
695 if (psta->aid > 0) {
696 DBG_871X("old AID %d\n", psta->aid);
697 } else {
698 for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++)
699 if (pstapriv->sta_aid[psta->aid - 1] == NULL)
700 break;
701
702 if (psta->aid > pstapriv->max_num_sta) {
703 psta->aid = 0;
704 DBG_871X("no room for more AIDs\n");
705 return _SUCCESS;
706 } else {
707 pstapriv->sta_aid[psta->aid - 1] = psta;
708 DBG_871X("allocate new AID = (%d)\n", psta->aid);
709 }
710 }
711
712 psta->qos_option = 1;
713 psta->bw_mode = CHANNEL_WIDTH_20;
714 psta->ieee8021x_blocked = false;
715 psta->htpriv.ht_option = true;
716 psta->htpriv.ampdu_enable = false;
717 psta->htpriv.sgi_20m = false;
718 psta->htpriv.sgi_40m = false;
719 psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
720 psta->htpriv.agg_enable_bitmap = 0x0;
721 psta->htpriv.candidate_tid_bitmap = 0x0;
722
723 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
724
725 memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
726
727 spin_lock_bh(&psta->lock);
728 psta->state |= _FW_LINKED;
729 spin_unlock_bh(&psta->lock);
730
731 report_add_sta_event(padapter, psta->hwaddr, psta->aid);
732
733 }
734
735 issue_probersp(padapter, get_sa(pframe), false);
736
737 return _SUCCESS;
738
739 }
740
741_non_rc_device:
742
743 return _SUCCESS;
744
745#endif
746
747 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
748 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
749
750
751
752 if (p != NULL) {
753 if (is_valid_p2p_probereq)
754 goto _issue_probersp;
755
756 if ((ielen != 0 && false == !memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
757 || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
758 )
759 return _SUCCESS;
760
761_issue_probersp:
762 if ((check_fwstate(pmlmepriv, _FW_LINKED) &&
763 pmlmepriv->cur_network.join_res) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
764
765 issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
766 }
767
768 }
769
770 return _SUCCESS;
771
772}
773
774unsigned int OnProbeRsp(struct adapter *padapter, union recv_frame *precv_frame)
775{
776 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
777
778 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
779 report_survey_event(padapter, precv_frame);
780 return _SUCCESS;
781 }
782
783 return _SUCCESS;
784
785}
786
787unsigned int OnBeacon(struct adapter *padapter, union recv_frame *precv_frame)
788{
789 int cam_idx;
790 struct sta_info *psta;
791 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
792 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
793 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
794 struct sta_priv *pstapriv = &padapter->stapriv;
795 u8 *pframe = precv_frame->u.hdr.rx_data;
796 uint len = precv_frame->u.hdr.len;
797 struct wlan_bssid_ex *pbss;
798 int ret = _SUCCESS;
799 u8 *p = NULL;
800 u32 ielen = 0;
801
802 p = rtw_get_ie(pframe + sizeof(struct ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen, precv_frame->u.hdr.len - sizeof(struct ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_);
803 if ((p != NULL) && (ielen > 0)) {
804 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D)) {
805
806 DBG_871X("[WIFIDBG] Error in ESR IE is detected in Beacon of BSSID:"MAC_FMT". Fix the length of ESR IE to avoid failed Beacon parsing.\n", MAC_ARG(GetAddr3Ptr(pframe)));
807 *(p + 1) = ielen - 1;
808 }
809 }
810
811 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
812 report_survey_event(padapter, precv_frame);
813 return _SUCCESS;
814 }
815
816 if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) {
817 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
818
819 pbss = rtw_malloc(sizeof(struct wlan_bssid_ex));
820 if (pbss) {
821 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
822 update_network(&(pmlmepriv->cur_network.network), pbss, padapter, true);
823 rtw_get_bcn_info(&(pmlmepriv->cur_network));
824 }
825 kfree((u8 *)pbss);
826 }
827
828
829 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct ieee80211_hdr_3addr), len-sizeof(struct ieee80211_hdr_3addr));
830
831
832 update_TSF(pmlmeext, pframe, len);
833
834
835 pmlmeext->adaptive_tsf_done = false;
836 pmlmeext->DrvBcnEarly = 0xff;
837 pmlmeext->DrvBcnTimeOut = 0xff;
838 pmlmeext->bcn_cnt = 0;
839 memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt));
840 memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio));
841
842
843 start_clnt_auth(padapter);
844
845 return _SUCCESS;
846 }
847
848 if (((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
849 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
850 if (psta != NULL) {
851 ret = rtw_check_bcn_info(padapter, pframe, len);
852 if (!ret) {
853 DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
854 receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0);
855 return _SUCCESS;
856 }
857
858
859 if ((sta_rx_pkts(psta) & 0xf) == 0)
860
861 update_beacon_info(padapter, pframe, len, psta);
862
863 adaptive_early_32k(pmlmeext, pframe, len);
864 }
865 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
866 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
867 if (psta != NULL) {
868
869
870 if ((sta_rx_pkts(psta) & 0xf) == 0) {
871
872 update_beacon_info(padapter, pframe, len, psta);
873 }
874 } else{
875
876 cam_idx = allocate_fw_sta_entry(padapter);
877 if (cam_idx == NUM_STA)
878 goto _END_ONBEACON_;
879
880
881 if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL) {
882 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
883 goto _END_ONBEACON_;
884 }
885
886
887 update_TSF(pmlmeext, pframe, len);
888
889
890 report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
891 }
892 }
893 }
894
895_END_ONBEACON_:
896
897 return _SUCCESS;
898
899}
900
901unsigned int OnAuth(struct adapter *padapter, union recv_frame *precv_frame)
902{
903 unsigned int auth_mode, seq, ie_len;
904 unsigned char *sa, *p;
905 u16 algorithm;
906 int status;
907 static struct sta_info stat;
908 struct sta_info *pstat = NULL;
909 struct sta_priv *pstapriv = &padapter->stapriv;
910 struct security_priv *psecuritypriv = &padapter->securitypriv;
911 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
912 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
913 u8 *pframe = precv_frame->u.hdr.rx_data;
914 uint len = precv_frame->u.hdr.len;
915 u8 offset = 0;
916
917 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
918 return _FAIL;
919
920 DBG_871X("+OnAuth\n");
921
922 sa = GetAddr2Ptr(pframe);
923
924 auth_mode = psecuritypriv->dot11AuthAlgrthm;
925
926 if (GetPrivacy(pframe)) {
927 u8 *iv;
928 struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib);
929
930 prxattrib->hdrlen = WLAN_HDR_A3_LEN;
931 prxattrib->encrypt = _WEP40_;
932
933 iv = pframe+prxattrib->hdrlen;
934 prxattrib->key_index = ((iv[3]>>6)&0x3);
935
936 prxattrib->iv_len = 4;
937 prxattrib->icv_len = 4;
938
939 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
940
941 offset = 4;
942 }
943
944 algorithm = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
945 seq = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
946
947 DBG_871X("auth alg =%x, seq =%X\n", algorithm, seq);
948
949 if (auth_mode == 2 &&
950 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
951 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
952 auth_mode = 0;
953
954 if ((algorithm > 0 && auth_mode == 0) ||
955 (algorithm == 0 && auth_mode == 1)) {
956 DBG_871X("auth rejected due to bad alg [alg =%d, auth_mib =%d] %02X%02X%02X%02X%02X%02X\n",
957 algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
958
959 status = _STATS_NO_SUPP_ALG_;
960
961 goto auth_fail;
962 }
963
964 if (rtw_access_ctrl(padapter, sa) == false) {
965 status = _STATS_UNABLE_HANDLE_STA_;
966 goto auth_fail;
967 }
968
969 pstat = rtw_get_stainfo(pstapriv, sa);
970 if (pstat == NULL) {
971
972
973 DBG_871X("going to alloc stainfo for sa ="MAC_FMT"\n", MAC_ARG(sa));
974 pstat = rtw_alloc_stainfo(pstapriv, sa);
975 if (pstat == NULL) {
976 DBG_871X(" Exceed the upper limit of supported clients...\n");
977 status = _STATS_UNABLE_HANDLE_STA_;
978 goto auth_fail;
979 }
980
981 pstat->state = WIFI_FW_AUTH_NULL;
982 pstat->auth_seq = 0;
983
984
985
986 } else{
987
988 spin_lock_bh(&pstapriv->asoc_list_lock);
989 if (list_empty(&pstat->asoc_list) == false) {
990 list_del_init(&pstat->asoc_list);
991 pstapriv->asoc_list_cnt--;
992 if (pstat->expire_to > 0) {
993
994 }
995 }
996 spin_unlock_bh(&pstapriv->asoc_list_lock);
997
998 if (seq == 1) {
999
1000 }
1001 }
1002
1003 spin_lock_bh(&pstapriv->auth_list_lock);
1004 if (list_empty(&pstat->auth_list)) {
1005
1006 list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
1007 pstapriv->auth_list_cnt++;
1008 }
1009 spin_unlock_bh(&pstapriv->auth_list_lock);
1010
1011 if (pstat->auth_seq == 0)
1012 pstat->expire_to = pstapriv->auth_to;
1013
1014
1015 if ((pstat->auth_seq + 1) != seq) {
1016 DBG_871X("(1)auth rejected because out of seq [rx_seq =%d, exp_seq =%d]!\n",
1017 seq, pstat->auth_seq+1);
1018 status = _STATS_OUT_OF_AUTH_SEQ_;
1019 goto auth_fail;
1020 }
1021
1022 if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3)) {
1023 if (seq == 1) {
1024 pstat->state &= ~WIFI_FW_AUTH_NULL;
1025 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1026 pstat->expire_to = pstapriv->assoc_to;
1027 pstat->authalg = algorithm;
1028 } else{
1029 DBG_871X("(2)auth rejected because out of seq [rx_seq =%d, exp_seq =%d]!\n",
1030 seq, pstat->auth_seq+1);
1031 status = _STATS_OUT_OF_AUTH_SEQ_;
1032 goto auth_fail;
1033 }
1034 } else{
1035 if (seq == 1) {
1036
1037 memset((void *)pstat->chg_txt, 78, 128);
1038
1039 pstat->state &= ~WIFI_FW_AUTH_NULL;
1040 pstat->state |= WIFI_FW_AUTH_STATE;
1041 pstat->authalg = algorithm;
1042 pstat->auth_seq = 2;
1043 } else if (seq == 3) {
1044
1045 DBG_871X("checking for challenging txt...\n");
1046
1047 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&ie_len,
1048 len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
1049
1050 if ((p == NULL) || (ie_len <= 0)) {
1051 DBG_871X("auth rejected because challenge failure!(1)\n");
1052 status = _STATS_CHALLENGE_FAIL_;
1053 goto auth_fail;
1054 }
1055
1056 if (!memcmp((void *)(p + 2), pstat->chg_txt, 128)) {
1057 pstat->state &= (~WIFI_FW_AUTH_STATE);
1058 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1059
1060 pstat->expire_to = pstapriv->assoc_to;
1061 } else{
1062 DBG_871X("auth rejected because challenge failure!\n");
1063 status = _STATS_CHALLENGE_FAIL_;
1064 goto auth_fail;
1065 }
1066 } else{
1067 DBG_871X("(3)auth rejected because out of seq [rx_seq =%d, exp_seq =%d]!\n",
1068 seq, pstat->auth_seq+1);
1069 status = _STATS_OUT_OF_AUTH_SEQ_;
1070 goto auth_fail;
1071 }
1072 }
1073
1074
1075
1076 pstat->auth_seq = seq + 1;
1077
1078 issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
1079
1080 if (pstat->state & WIFI_FW_AUTH_SUCCESS)
1081 pstat->auth_seq = 0;
1082
1083
1084 return _SUCCESS;
1085
1086auth_fail:
1087
1088 if (pstat)
1089 rtw_free_stainfo(padapter, pstat);
1090
1091 pstat = &stat;
1092 memset((char *)pstat, '\0', sizeof(stat));
1093 pstat->auth_seq = 2;
1094 memcpy(pstat->hwaddr, sa, 6);
1095
1096 issue_auth(padapter, pstat, (unsigned short)status);
1097
1098 return _FAIL;
1099
1100}
1101
1102unsigned int OnAuthClient(struct adapter *padapter, union recv_frame *precv_frame)
1103{
1104 unsigned int seq, len, status, algthm, offset;
1105 unsigned char *p;
1106 unsigned int go2asoc = 0;
1107 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1108 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1109 u8 *pframe = precv_frame->u.hdr.rx_data;
1110 uint pkt_len = precv_frame->u.hdr.len;
1111
1112 DBG_871X("%s\n", __func__);
1113
1114
1115 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
1116 return _SUCCESS;
1117
1118 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
1119 return _SUCCESS;
1120
1121 offset = (GetPrivacy(pframe)) ? 4 : 0;
1122
1123 algthm = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
1124 seq = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
1125 status = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
1126
1127 if (status != 0) {
1128 DBG_871X("clnt auth fail, status: %d\n", status);
1129 if (status == 13) {
1130 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1131 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1132 else
1133 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
1134
1135 }
1136
1137 set_link_timer(pmlmeext, 1);
1138 goto authclnt_fail;
1139 }
1140
1141 if (seq == 2) {
1142 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
1143
1144 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
1145 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
1146
1147 if (p == NULL) {
1148
1149 goto authclnt_fail;
1150 }
1151
1152 memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
1153 pmlmeinfo->auth_seq = 3;
1154 issue_auth(padapter, NULL, 0);
1155 set_link_timer(pmlmeext, REAUTH_TO);
1156
1157 return _SUCCESS;
1158 } else{
1159
1160 go2asoc = 1;
1161 }
1162 } else if (seq == 4) {
1163 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
1164 go2asoc = 1;
1165 } else{
1166 goto authclnt_fail;
1167 }
1168 } else{
1169
1170
1171 goto authclnt_fail;
1172 }
1173
1174 if (go2asoc) {
1175 DBG_871X_LEVEL(_drv_always_, "auth success, start assoc\n");
1176 start_clnt_assoc(padapter);
1177 return _SUCCESS;
1178 }
1179
1180authclnt_fail:
1181
1182
1183
1184 return _FAIL;
1185
1186}
1187
1188unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame)
1189{
1190 u16 capab_info, listen_interval;
1191 struct rtw_ieee802_11_elems elems;
1192 struct sta_info *pstat;
1193 unsigned char reassoc, *p, *pos, *wpa_ie;
1194 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
1195 int i, ie_len, wpa_ie_len, left;
1196 unsigned char supportRate[16];
1197 int supportRateNum;
1198 unsigned short status = _STATS_SUCCESSFUL_;
1199 unsigned short frame_type, ie_offset = 0;
1200 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1201 struct security_priv *psecuritypriv = &padapter->securitypriv;
1202 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1203 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1204 struct wlan_bssid_ex *cur = &(pmlmeinfo->network);
1205 struct sta_priv *pstapriv = &padapter->stapriv;
1206 u8 *pframe = precv_frame->u.hdr.rx_data;
1207 uint pkt_len = precv_frame->u.hdr.len;
1208
1209 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1210 return _FAIL;
1211
1212 frame_type = GetFrameSubType(pframe);
1213 if (frame_type == WIFI_ASSOCREQ) {
1214 reassoc = 0;
1215 ie_offset = _ASOCREQ_IE_OFFSET_;
1216 } else{
1217 reassoc = 1;
1218 ie_offset = _REASOCREQ_IE_OFFSET_;
1219 }
1220
1221
1222 if (pkt_len < sizeof(struct ieee80211_hdr_3addr) + ie_offset) {
1223 DBG_871X("handle_assoc(reassoc =%d) - too short payload (len =%lu)"
1224 "\n", reassoc, (unsigned long)pkt_len);
1225 return _FAIL;
1226 }
1227
1228 pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1229 if (pstat == NULL) {
1230 status = _RSON_CLS2_;
1231 goto asoc_class2_error;
1232 }
1233
1234 capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
1235
1236
1237 listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
1238
1239 left = pkt_len - (sizeof(struct ieee80211_hdr_3addr) + ie_offset);
1240 pos = pframe + (sizeof(struct ieee80211_hdr_3addr) + ie_offset);
1241
1242
1243 DBG_871X("%s\n", __func__);
1244
1245
1246 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) {
1247 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) {
1248 status = _RSON_CLS2_;
1249 goto asoc_class2_error;
1250 } else{
1251 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
1252 pstat->state |= WIFI_FW_ASSOC_STATE;
1253 }
1254 } else{
1255 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1256 pstat->state |= WIFI_FW_ASSOC_STATE;
1257 }
1258
1259
1260 pstat->capability = capab_info;
1261
1262
1263 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
1264 !elems.ssid) {
1265 DBG_871X("STA " MAC_FMT " sent invalid association request\n",
1266 MAC_ARG(pstat->hwaddr));
1267 status = _STATS_FAILURE_;
1268 goto OnAssocReqFail;
1269 }
1270
1271
1272
1273
1274 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
1275 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1276 if (p == NULL) {
1277 status = _STATS_FAILURE_;
1278 }
1279
1280 if (ie_len == 0)
1281 status = _STATS_FAILURE_;
1282 else {
1283
1284 if (memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
1285 status = _STATS_FAILURE_;
1286
1287 if (ie_len != cur->Ssid.SsidLength)
1288 status = _STATS_FAILURE_;
1289 }
1290
1291 if (_STATS_SUCCESSFUL_ != status)
1292 goto OnAssocReqFail;
1293
1294
1295 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1296 if (p == NULL) {
1297 DBG_871X("Rx a sta assoc-req which supported rate is empty!\n");
1298
1299
1300
1301
1302 status = _STATS_FAILURE_;
1303 goto OnAssocReqFail;
1304 } else {
1305 memcpy(supportRate, p+2, ie_len);
1306 supportRateNum = ie_len;
1307
1308 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_, &ie_len,
1309 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1310 if (p != NULL) {
1311
1312 if (supportRateNum <= sizeof(supportRate)) {
1313 memcpy(supportRate+supportRateNum, p+2, ie_len);
1314 supportRateNum += ie_len;
1315 }
1316 }
1317 }
1318
1319
1320
1321
1322
1323 pstat->bssratelen = supportRateNum;
1324 memcpy(pstat->bssrateset, supportRate, supportRateNum);
1325 UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
1326
1327
1328 pstat->dot8021xalg = 0;
1329 pstat->wpa_psk = 0;
1330 pstat->wpa_group_cipher = 0;
1331 pstat->wpa2_group_cipher = 0;
1332 pstat->wpa_pairwise_cipher = 0;
1333 pstat->wpa2_pairwise_cipher = 0;
1334 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
1335 if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
1336
1337 int group_cipher = 0, pairwise_cipher = 0;
1338
1339 wpa_ie = elems.rsn_ie;
1340 wpa_ie_len = elems.rsn_ie_len;
1341
1342 if (rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1343 pstat->dot8021xalg = 1;
1344 pstat->wpa_psk |= BIT(1);
1345
1346 pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
1347 pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
1348
1349 if (!pstat->wpa2_group_cipher)
1350 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1351
1352 if (!pstat->wpa2_pairwise_cipher)
1353 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1354 } else{
1355 status = WLAN_STATUS_INVALID_IE;
1356 }
1357
1358 } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
1359
1360 int group_cipher = 0, pairwise_cipher = 0;
1361
1362 wpa_ie = elems.wpa_ie;
1363 wpa_ie_len = elems.wpa_ie_len;
1364
1365 if (rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1366 pstat->dot8021xalg = 1;
1367 pstat->wpa_psk |= BIT(0);
1368
1369 pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
1370 pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
1371
1372 if (!pstat->wpa_group_cipher)
1373 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1374
1375 if (!pstat->wpa_pairwise_cipher)
1376 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1377
1378 } else{
1379 status = WLAN_STATUS_INVALID_IE;
1380 }
1381
1382 } else {
1383 wpa_ie = NULL;
1384 wpa_ie_len = 0;
1385 }
1386
1387 if (_STATS_SUCCESSFUL_ != status)
1388 goto OnAssocReqFail;
1389
1390 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
1391 if (wpa_ie == NULL) {
1392 if (elems.wps_ie) {
1393 DBG_871X("STA included WPS IE in "
1394 "(Re)Association Request - assume WPS is "
1395 "used\n");
1396 pstat->flags |= WLAN_STA_WPS;
1397
1398
1399
1400 } else {
1401 DBG_871X("STA did not include WPA/RSN IE "
1402 "in (Re)Association Request - possible WPS "
1403 "use\n");
1404 pstat->flags |= WLAN_STA_MAYBE_WPS;
1405 }
1406
1407
1408
1409
1410 if ((psecuritypriv->wpa_psk > 0)
1411 && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS))) {
1412 if (pmlmepriv->wps_beacon_ie) {
1413 u8 selected_registrar = 0;
1414
1415 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR, &selected_registrar, NULL);
1416
1417 if (!selected_registrar) {
1418 DBG_871X("selected_registrar is false , or AP is not ready to do WPS\n");
1419
1420 status = _STATS_UNABLE_HANDLE_STA_;
1421
1422 goto OnAssocReqFail;
1423 }
1424 }
1425 }
1426
1427 } else{
1428 int copy_len;
1429
1430 if (psecuritypriv->wpa_psk == 0) {
1431 DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association "
1432 "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
1433
1434 status = WLAN_STATUS_INVALID_IE;
1435
1436 goto OnAssocReqFail;
1437
1438 }
1439
1440 if (elems.wps_ie) {
1441 DBG_871X("STA included WPS IE in "
1442 "(Re)Association Request - WPS is "
1443 "used\n");
1444 pstat->flags |= WLAN_STA_WPS;
1445 copy_len = 0;
1446 } else{
1447 copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
1448 }
1449
1450
1451 if (copy_len > 0)
1452 memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
1453
1454 }
1455
1456
1457
1458 pstat->flags &= ~WLAN_STA_WME;
1459 pstat->qos_option = 0;
1460 pstat->qos_info = 0;
1461 pstat->has_legacy_ac = true;
1462 pstat->uapsd_vo = 0;
1463 pstat->uapsd_vi = 0;
1464 pstat->uapsd_be = 0;
1465 pstat->uapsd_bk = 0;
1466 if (pmlmepriv->qospriv.qos_option) {
1467 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
1468 for (;;) {
1469 p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1470 if (p != NULL) {
1471 if (!memcmp(p+2, WMM_IE, 6)) {
1472
1473 pstat->flags |= WLAN_STA_WME;
1474
1475 pstat->qos_option = 1;
1476 pstat->qos_info = *(p+8);
1477
1478 pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
1479
1480 if ((pstat->qos_info&0xf) != 0xf)
1481 pstat->has_legacy_ac = true;
1482 else
1483 pstat->has_legacy_ac = false;
1484
1485 if (pstat->qos_info&0xf) {
1486 if (pstat->qos_info&BIT(0))
1487 pstat->uapsd_vo = BIT(0)|BIT(1);
1488 else
1489 pstat->uapsd_vo = 0;
1490
1491 if (pstat->qos_info&BIT(1))
1492 pstat->uapsd_vi = BIT(0)|BIT(1);
1493 else
1494 pstat->uapsd_vi = 0;
1495
1496 if (pstat->qos_info&BIT(2))
1497 pstat->uapsd_bk = BIT(0)|BIT(1);
1498 else
1499 pstat->uapsd_bk = 0;
1500
1501 if (pstat->qos_info&BIT(3))
1502 pstat->uapsd_be = BIT(0)|BIT(1);
1503 else
1504 pstat->uapsd_be = 0;
1505
1506 }
1507
1508 break;
1509 }
1510 } else {
1511 break;
1512 }
1513 p = p + ie_len + 2;
1514 }
1515 }
1516
1517
1518 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
1519 if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap)) {
1520 pstat->flags |= WLAN_STA_HT;
1521
1522 pstat->flags |= WLAN_STA_WME;
1523
1524 memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
1525
1526 } else
1527 pstat->flags &= ~WLAN_STA_HT;
1528
1529
1530 if ((pmlmepriv->htpriv.ht_option == false) && (pstat->flags&WLAN_STA_HT)) {
1531 status = _STATS_FAILURE_;
1532 goto OnAssocReqFail;
1533 }
1534
1535
1536 if ((pstat->flags & WLAN_STA_HT) &&
1537 ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
1538 (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP))) {
1539 DBG_871X("HT: " MAC_FMT " tried to "
1540 "use TKIP with HT association\n", MAC_ARG(pstat->hwaddr));
1541
1542
1543
1544 }
1545 pstat->flags |= WLAN_STA_NONERP;
1546 for (i = 0; i < pstat->bssratelen; i++) {
1547 if ((pstat->bssrateset[i] & 0x7f) > 22) {
1548 pstat->flags &= ~WLAN_STA_NONERP;
1549 break;
1550 }
1551 }
1552
1553 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1554 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
1555 else
1556 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1557
1558
1559
1560 if (status != _STATS_SUCCESSFUL_)
1561 goto OnAssocReqFail;
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572 if (pstat->aid > 0) {
1573 DBG_871X(" old AID %d\n", pstat->aid);
1574 } else {
1575 for (pstat->aid = 1; pstat->aid < NUM_STA; pstat->aid++)
1576 if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
1577 break;
1578
1579
1580 if (pstat->aid > pstapriv->max_num_sta) {
1581
1582 pstat->aid = 0;
1583
1584 DBG_871X(" no room for more AIDs\n");
1585
1586 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1587
1588 goto OnAssocReqFail;
1589
1590
1591 } else {
1592 pstapriv->sta_aid[pstat->aid - 1] = pstat;
1593 DBG_871X("allocate new AID = (%d)\n", pstat->aid);
1594 }
1595 }
1596
1597
1598 pstat->state &= (~WIFI_FW_ASSOC_STATE);
1599 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
1600
1601 spin_lock_bh(&pstapriv->auth_list_lock);
1602 if (!list_empty(&pstat->auth_list)) {
1603 list_del_init(&pstat->auth_list);
1604 pstapriv->auth_list_cnt--;
1605 }
1606 spin_unlock_bh(&pstapriv->auth_list_lock);
1607
1608 spin_lock_bh(&pstapriv->asoc_list_lock);
1609 if (list_empty(&pstat->asoc_list)) {
1610 pstat->expire_to = pstapriv->expire_to;
1611 list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
1612 pstapriv->asoc_list_cnt++;
1613 }
1614 spin_unlock_bh(&pstapriv->asoc_list_lock);
1615
1616
1617 if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) {
1618
1619 bss_cap_update_on_sta_join(padapter, pstat);
1620 sta_info_update(padapter, pstat);
1621
1622
1623 if (frame_type == WIFI_ASSOCREQ)
1624 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
1625 else
1626 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
1627
1628 spin_lock_bh(&pstat->lock);
1629 if (pstat->passoc_req) {
1630 kfree(pstat->passoc_req);
1631 pstat->passoc_req = NULL;
1632 pstat->assoc_req_len = 0;
1633 }
1634
1635 pstat->passoc_req = rtw_zmalloc(pkt_len);
1636 if (pstat->passoc_req) {
1637 memcpy(pstat->passoc_req, pframe, pkt_len);
1638 pstat->assoc_req_len = pkt_len;
1639 }
1640 spin_unlock_bh(&pstat->lock);
1641
1642
1643 report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
1644 }
1645
1646 return _SUCCESS;
1647
1648asoc_class2_error:
1649
1650 issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
1651
1652 return _FAIL;
1653
1654OnAssocReqFail:
1655
1656 pstat->aid = 0;
1657 if (frame_type == WIFI_ASSOCREQ)
1658 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
1659 else
1660 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
1661
1662 return _FAIL;
1663}
1664
1665unsigned int OnAssocRsp(struct adapter *padapter, union recv_frame *precv_frame)
1666{
1667 uint i;
1668 int res;
1669 unsigned short status;
1670 struct ndis_80211_var_ie *pIE;
1671 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1672 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1673 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1674
1675 u8 *pframe = precv_frame->u.hdr.rx_data;
1676 uint pkt_len = precv_frame->u.hdr.len;
1677
1678 DBG_871X("%s\n", __func__);
1679
1680
1681 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
1682 return _SUCCESS;
1683
1684 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
1685 return _SUCCESS;
1686
1687 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1688 return _SUCCESS;
1689
1690 del_timer_sync(&pmlmeext->link_timer);
1691
1692
1693 status = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 2));
1694 if (status > 0) {
1695 DBG_871X("assoc reject, status code: %d\n", status);
1696 pmlmeinfo->state = WIFI_FW_NULL_STATE;
1697 res = -4;
1698 goto report_assoc_result;
1699 }
1700
1701
1702 pmlmeinfo->capability = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
1703
1704
1705 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20;
1706
1707
1708 res = pmlmeinfo->aid = (int)(le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
1709
1710
1711
1712
1713 for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) {
1714 pIE = (struct ndis_80211_var_ie *)(pframe + i);
1715
1716 switch (pIE->ElementID) {
1717 case _VENDOR_SPECIFIC_IE_:
1718 if (!memcmp(pIE->data, WMM_PARA_OUI, 6))
1719 WMM_param_handler(padapter, pIE);
1720 break;
1721
1722 case _HT_CAPABILITY_IE_:
1723 HT_caps_handler(padapter, pIE);
1724 break;
1725
1726 case _HT_EXTRA_INFO_IE_:
1727 HT_info_handler(padapter, pIE);
1728 break;
1729
1730 case _ERPINFO_IE_:
1731 ERP_IE_handler(padapter, pIE);
1732
1733 default:
1734 break;
1735 }
1736
1737 i += (pIE->Length + 2);
1738 }
1739
1740 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
1741 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
1742
1743
1744 UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
1745
1746report_assoc_result:
1747 if (res > 0) {
1748 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
1749 } else {
1750 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
1751 }
1752
1753 report_join_res(padapter, res);
1754
1755 return _SUCCESS;
1756}
1757
1758unsigned int OnDeAuth(struct adapter *padapter, union recv_frame *precv_frame)
1759{
1760 unsigned short reason;
1761 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1762 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1763 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1764 u8 *pframe = precv_frame->u.hdr.rx_data;
1765
1766
1767 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1768 return _SUCCESS;
1769
1770 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
1771
1772 DBG_871X("%s Reason code(%d)\n", __func__, reason);
1773
1774 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1775 struct sta_info *psta;
1776 struct sta_priv *pstapriv = &padapter->stapriv;
1777
1778
1779
1780
1781
1782 DBG_871X_LEVEL(_drv_always_, "ap recv deauth reason code(%d) sta:%pM\n",
1783 reason, GetAddr2Ptr(pframe));
1784
1785 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1786 if (psta) {
1787 u8 updated = false;
1788
1789 spin_lock_bh(&pstapriv->asoc_list_lock);
1790 if (list_empty(&psta->asoc_list) == false) {
1791 list_del_init(&psta->asoc_list);
1792 pstapriv->asoc_list_cnt--;
1793 updated = ap_free_sta(padapter, psta, false, reason);
1794
1795 }
1796 spin_unlock_bh(&pstapriv->asoc_list_lock);
1797
1798 associated_clients_update(padapter, updated);
1799 }
1800
1801
1802 return _SUCCESS;
1803 } else{
1804 int ignore_received_deauth = 0;
1805
1806
1807
1808
1809
1810
1811 if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) ||
1812 (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)) {
1813 if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA) {
1814 ignore_received_deauth = 1;
1815 } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
1816
1817 ignore_received_deauth = 1;
1818 }
1819 }
1820
1821 DBG_871X_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM, ignore = %d\n",
1822 reason, GetAddr3Ptr(pframe), ignore_received_deauth);
1823
1824 if (0 == ignore_received_deauth) {
1825 receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
1826 }
1827 }
1828 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1829 return _SUCCESS;
1830
1831}
1832
1833unsigned int OnDisassoc(struct adapter *padapter, union recv_frame *precv_frame)
1834{
1835 unsigned short reason;
1836 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1837 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1838 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1839 u8 *pframe = precv_frame->u.hdr.rx_data;
1840
1841
1842 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1843 return _SUCCESS;
1844
1845 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
1846
1847 DBG_871X("%s Reason code(%d)\n", __func__, reason);
1848
1849 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1850 struct sta_info *psta;
1851 struct sta_priv *pstapriv = &padapter->stapriv;
1852
1853
1854
1855
1856
1857 DBG_871X_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
1858 reason, GetAddr2Ptr(pframe));
1859
1860 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1861 if (psta) {
1862 u8 updated = false;
1863
1864 spin_lock_bh(&pstapriv->asoc_list_lock);
1865 if (list_empty(&psta->asoc_list) == false) {
1866 list_del_init(&psta->asoc_list);
1867 pstapriv->asoc_list_cnt--;
1868 updated = ap_free_sta(padapter, psta, false, reason);
1869
1870 }
1871 spin_unlock_bh(&pstapriv->asoc_list_lock);
1872
1873 associated_clients_update(padapter, updated);
1874 }
1875
1876 return _SUCCESS;
1877 } else{
1878 DBG_871X_LEVEL(_drv_always_, "sta recv disassoc reason code(%d) sta:%pM\n",
1879 reason, GetAddr3Ptr(pframe));
1880
1881 receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
1882 }
1883 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1884 return _SUCCESS;
1885
1886}
1887
1888unsigned int OnAtim(struct adapter *padapter, union recv_frame *precv_frame)
1889{
1890 DBG_871X("%s\n", __func__);
1891 return _SUCCESS;
1892}
1893
1894unsigned int on_action_spct(struct adapter *padapter, union recv_frame *precv_frame)
1895{
1896 unsigned int ret = _FAIL;
1897 struct sta_info *psta = NULL;
1898 struct sta_priv *pstapriv = &padapter->stapriv;
1899 u8 *pframe = precv_frame->u.hdr.rx_data;
1900 u8 *frame_body = (u8 *)(pframe + sizeof(struct ieee80211_hdr_3addr));
1901 u8 category;
1902 u8 action;
1903
1904 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
1905
1906 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1907
1908 if (!psta)
1909 goto exit;
1910
1911 category = frame_body[0];
1912 if (category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
1913 goto exit;
1914
1915 action = frame_body[1];
1916 switch (action) {
1917 case RTW_WLAN_ACTION_SPCT_MSR_REQ:
1918 case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
1919 case RTW_WLAN_ACTION_SPCT_TPC_REQ:
1920 case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
1921 case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
1922 break;
1923 default:
1924 break;
1925 }
1926
1927exit:
1928 return ret;
1929}
1930
1931unsigned int OnAction_back(struct adapter *padapter, union recv_frame *precv_frame)
1932{
1933 u8 *addr;
1934 struct sta_info *psta = NULL;
1935 struct recv_reorder_ctrl *preorder_ctrl;
1936 unsigned char *frame_body;
1937 unsigned char category, action;
1938 unsigned short tid, status, reason_code = 0;
1939 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1940 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1941 u8 *pframe = precv_frame->u.hdr.rx_data;
1942 struct sta_priv *pstapriv = &padapter->stapriv;
1943
1944 DBG_871X("%s\n", __func__);
1945
1946
1947 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))
1948 return _SUCCESS;
1949
1950 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1951 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1952 return _SUCCESS;
1953
1954 addr = GetAddr2Ptr(pframe);
1955 psta = rtw_get_stainfo(pstapriv, addr);
1956
1957 if (psta == NULL)
1958 return _SUCCESS;
1959
1960 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
1961
1962 category = frame_body[0];
1963 if (category == RTW_WLAN_CATEGORY_BACK) {
1964 if (!pmlmeinfo->HT_enable) {
1965 return _SUCCESS;
1966 }
1967
1968 action = frame_body[1];
1969 DBG_871X("%s, action =%d\n", __func__, action);
1970 switch (action) {
1971 case RTW_WLAN_ACTION_ADDBA_REQ:
1972
1973 memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
1974
1975 process_addba_req(padapter, (u8 *)&(pmlmeinfo->ADDBA_req), addr);
1976
1977 if (pmlmeinfo->accept_addba_req) {
1978 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 0);
1979 } else{
1980 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 37);
1981 }
1982
1983 break;
1984
1985 case RTW_WLAN_ACTION_ADDBA_RESP:
1986 status = RTW_GET_LE16(&frame_body[3]);
1987 tid = ((frame_body[5] >> 2) & 0x7);
1988
1989 if (status == 0) {
1990
1991 DBG_871X("agg_enable for TID =%d\n", tid);
1992 psta->htpriv.agg_enable_bitmap |= 1 << tid;
1993 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
1994 } else{
1995 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
1996 }
1997
1998 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
1999 DBG_871X("%s alive check - rx ADDBA response\n", __func__);
2000 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
2001 psta->expire_to = pstapriv->expire_to;
2002 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
2003 }
2004
2005
2006 break;
2007
2008 case RTW_WLAN_ACTION_DELBA:
2009 if ((frame_body[3] & BIT(3)) == 0) {
2010 psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
2011 psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
2012
2013
2014 reason_code = RTW_GET_LE16(&frame_body[4]);
2015 } else if ((frame_body[3] & BIT(3)) == BIT(3)) {
2016 tid = (frame_body[3] >> 4) & 0x0F;
2017
2018 preorder_ctrl = &psta->recvreorder_ctrl[tid];
2019 preorder_ctrl->enable = false;
2020 preorder_ctrl->indicate_seq = 0xffff;
2021 #ifdef DBG_RX_SEQ
2022 DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u\n", __func__, __LINE__,
2023 preorder_ctrl->indicate_seq);
2024 #endif
2025 }
2026
2027 DBG_871X("%s(): DELBA: %x(%x)\n", __func__, pmlmeinfo->agg_enable_bitmap, reason_code);
2028
2029 break;
2030
2031 default:
2032 break;
2033 }
2034 }
2035 return _SUCCESS;
2036}
2037
2038static s32 rtw_action_public_decache(union recv_frame *recv_frame, s32 token)
2039{
2040 struct adapter *adapter = recv_frame->u.hdr.adapter;
2041 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
2042 u8 *frame = recv_frame->u.hdr.rx_data;
2043 u16 seq_ctrl = ((recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
2044 (recv_frame->u.hdr.attrib.frag_num & 0xf);
2045
2046 if (GetRetry(frame)) {
2047 if (token >= 0) {
2048 if ((seq_ctrl == mlmeext->action_public_rxseq)
2049 && (token == mlmeext->action_public_dialog_token)) {
2050 DBG_871X(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x, token:%d\n",
2051 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
2052 return _FAIL;
2053 }
2054 } else {
2055 if (seq_ctrl == mlmeext->action_public_rxseq) {
2056 DBG_871X(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x\n",
2057 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq);
2058 return _FAIL;
2059 }
2060 }
2061 }
2062
2063 mlmeext->action_public_rxseq = seq_ctrl;
2064
2065 if (token >= 0)
2066 mlmeext->action_public_dialog_token = token;
2067
2068 return _SUCCESS;
2069}
2070
2071static unsigned int on_action_public_p2p(union recv_frame *precv_frame)
2072{
2073 u8 *pframe = precv_frame->u.hdr.rx_data;
2074 u8 *frame_body;
2075 u8 dialogToken = 0;
2076
2077 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
2078
2079 dialogToken = frame_body[7];
2080
2081 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
2082 return _FAIL;
2083
2084 return _SUCCESS;
2085}
2086
2087static unsigned int on_action_public_vendor(union recv_frame *precv_frame)
2088{
2089 unsigned int ret = _FAIL;
2090 u8 *pframe = precv_frame->u.hdr.rx_data;
2091 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2092
2093 if (!memcmp(frame_body + 2, P2P_OUI, 4)) {
2094 ret = on_action_public_p2p(precv_frame);
2095 }
2096
2097 return ret;
2098}
2099
2100static unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
2101{
2102 unsigned int ret = _FAIL;
2103 u8 *pframe = precv_frame->u.hdr.rx_data;
2104 uint frame_len = precv_frame->u.hdr.len;
2105 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2106 u8 token;
2107 struct adapter *adapter = precv_frame->u.hdr.adapter;
2108 int cnt = 0;
2109 char msg[64];
2110
2111 token = frame_body[2];
2112
2113 if (rtw_action_public_decache(precv_frame, token) == _FAIL)
2114 goto exit;
2115
2116 cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
2117 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
2118
2119 ret = _SUCCESS;
2120
2121exit:
2122 return ret;
2123}
2124
2125unsigned int on_action_public(struct adapter *padapter, union recv_frame *precv_frame)
2126{
2127 unsigned int ret = _FAIL;
2128 u8 *pframe = precv_frame->u.hdr.rx_data;
2129 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2130 u8 category, action;
2131
2132
2133 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))
2134 goto exit;
2135
2136 category = frame_body[0];
2137 if (category != RTW_WLAN_CATEGORY_PUBLIC)
2138 goto exit;
2139
2140 action = frame_body[1];
2141 switch (action) {
2142 case ACT_PUBLIC_VENDOR:
2143 ret = on_action_public_vendor(precv_frame);
2144 break;
2145 default:
2146 ret = on_action_public_default(precv_frame, action);
2147 break;
2148 }
2149
2150exit:
2151 return ret;
2152}
2153
2154unsigned int OnAction_ht(struct adapter *padapter, union recv_frame *precv_frame)
2155{
2156 u8 *pframe = precv_frame->u.hdr.rx_data;
2157 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2158 u8 category, action;
2159
2160
2161 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))
2162 goto exit;
2163
2164 category = frame_body[0];
2165 if (category != RTW_WLAN_CATEGORY_HT)
2166 goto exit;
2167
2168 action = frame_body[1];
2169 switch (action) {
2170 case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING:
2171 break;
2172 default:
2173 break;
2174 }
2175
2176exit:
2177
2178 return _SUCCESS;
2179}
2180
2181unsigned int OnAction_sa_query(struct adapter *padapter, union recv_frame *precv_frame)
2182{
2183 u8 *pframe = precv_frame->u.hdr.rx_data;
2184 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
2185 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2186 unsigned short tid;
2187
2188
2189 DBG_871X("OnAction_sa_query\n");
2190
2191 switch (pframe[WLAN_HDR_A3_LEN+1]) {
2192 case 0:
2193 memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(unsigned short));
2194 DBG_871X("OnAction_sa_query request, action =%d, tid =%04x\n", pframe[WLAN_HDR_A3_LEN+1], tid);
2195 issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid);
2196 break;
2197
2198 case 1:
2199 del_timer_sync(&pmlmeext->sa_query_timer);
2200 DBG_871X("OnAction_sa_query response, action =%d, tid =%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN+1], pframe[WLAN_HDR_A3_LEN+2]);
2201 break;
2202 default:
2203 break;
2204 }
2205 if (0) {
2206 int pp;
2207 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
2208 for (pp = 0; pp < pattrib->pkt_len; pp++)
2209 printk(" %02x ", pframe[pp]);
2210 printk("\n");
2211 }
2212
2213 return _SUCCESS;
2214}
2215
2216unsigned int OnAction(struct adapter *padapter, union recv_frame *precv_frame)
2217{
2218 int i;
2219 unsigned char category;
2220 struct action_handler *ptable;
2221 unsigned char *frame_body;
2222 u8 *pframe = precv_frame->u.hdr.rx_data;
2223
2224 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
2225
2226 category = frame_body[0];
2227
2228 for (i = 0; i < ARRAY_SIZE(OnAction_tbl); i++) {
2229 ptable = &OnAction_tbl[i];
2230
2231 if (category == ptable->num)
2232 ptable->func(padapter, precv_frame);
2233
2234 }
2235
2236 return _SUCCESS;
2237
2238}
2239
2240unsigned int DoReserved(struct adapter *padapter, union recv_frame *precv_frame)
2241{
2242
2243
2244 return _SUCCESS;
2245}
2246
2247static struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
2248{
2249 struct xmit_frame *pmgntframe;
2250 struct xmit_buf *pxmitbuf;
2251
2252 if (once)
2253 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
2254 else
2255 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
2256
2257 if (pmgntframe == NULL) {
2258 DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
2259 goto exit;
2260 }
2261
2262 pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv);
2263 if (pxmitbuf == NULL) {
2264 DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
2265 rtw_free_xmitframe(pxmitpriv, pmgntframe);
2266 pmgntframe = NULL;
2267 goto exit;
2268 }
2269
2270 pmgntframe->frame_tag = MGNT_FRAMETAG;
2271 pmgntframe->pxmitbuf = pxmitbuf;
2272 pmgntframe->buf_addr = pxmitbuf->pbuf;
2273 pxmitbuf->priv_data = pmgntframe;
2274
2275exit:
2276 return pmgntframe;
2277
2278}
2279
2280inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
2281{
2282 return _alloc_mgtxmitframe(pxmitpriv, false);
2283}
2284
2285
2286
2287
2288
2289
2290
2291void update_mgnt_tx_rate(struct adapter *padapter, u8 rate)
2292{
2293 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2294
2295 pmlmeext->tx_rate = rate;
2296
2297}
2298
2299void update_mgntframe_attrib(struct adapter *padapter, struct pkt_attrib *pattrib)
2300{
2301 u8 wireless_mode;
2302 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2303
2304
2305
2306 pattrib->hdrlen = 24;
2307 pattrib->nr_frags = 1;
2308 pattrib->priority = 7;
2309 pattrib->mac_id = 0;
2310 pattrib->qsel = 0x12;
2311
2312 pattrib->pktlen = 0;
2313
2314 if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
2315 wireless_mode = WIRELESS_11B;
2316 else
2317 wireless_mode = WIRELESS_11G;
2318 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
2319 pattrib->rate = pmlmeext->tx_rate;
2320
2321 pattrib->encrypt = _NO_PRIVACY_;
2322 pattrib->bswenc = false;
2323
2324 pattrib->qos_en = false;
2325 pattrib->ht_en = false;
2326 pattrib->bwmode = CHANNEL_WIDTH_20;
2327 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2328 pattrib->sgi = false;
2329
2330 pattrib->seqnum = pmlmeext->mgnt_seq;
2331
2332 pattrib->retry_ctrl = true;
2333
2334 pattrib->mbssid = 0;
2335
2336}
2337
2338void update_mgntframe_attrib_addr(struct adapter *padapter, struct xmit_frame *pmgntframe)
2339{
2340 u8 *pframe;
2341 struct pkt_attrib *pattrib = &pmgntframe->attrib;
2342
2343 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2344
2345 memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
2346 memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN);
2347}
2348
2349void dump_mgntframe(struct adapter *padapter, struct xmit_frame *pmgntframe)
2350{
2351 if (padapter->bSurpriseRemoved ||
2352 padapter->bDriverStopped) {
2353 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
2354 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
2355 return;
2356 }
2357
2358 rtw_hal_mgnt_xmit(padapter, pmgntframe);
2359}
2360
2361s32 dump_mgntframe_and_wait(struct adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
2362{
2363 s32 ret = _FAIL;
2364 _irqL irqL;
2365 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2366 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
2367 struct submit_ctx sctx;
2368
2369 if (padapter->bSurpriseRemoved ||
2370 padapter->bDriverStopped) {
2371 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
2372 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
2373 return ret;
2374 }
2375
2376 rtw_sctx_init(&sctx, timeout_ms);
2377 pxmitbuf->sctx = &sctx;
2378
2379 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
2380
2381 if (ret == _SUCCESS)
2382 ret = rtw_sctx_wait(&sctx, __func__);
2383
2384 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
2385 pxmitbuf->sctx = NULL;
2386 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
2387
2388 return ret;
2389}
2390
2391s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmgntframe)
2392{
2393 static u8 seq_no;
2394 s32 ret = _FAIL;
2395 u32 timeout_ms = 500;
2396 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2397
2398 if (padapter->bSurpriseRemoved ||
2399 padapter->bDriverStopped) {
2400 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
2401 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
2402 return -1;
2403 }
2404
2405 if (mutex_lock_interruptible(&pxmitpriv->ack_tx_mutex) == 0) {
2406 pxmitpriv->ack_tx = true;
2407 pxmitpriv->seq_no = seq_no++;
2408 pmgntframe->ack_report = 1;
2409 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
2410 ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms);
2411 }
2412
2413 pxmitpriv->ack_tx = false;
2414 mutex_unlock(&pxmitpriv->ack_tx_mutex);
2415 }
2416
2417 return ret;
2418}
2419
2420static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
2421{
2422 u8 *ssid_ie;
2423 sint ssid_len_ori;
2424 int len_diff = 0;
2425
2426 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
2427
2428
2429
2430 if (ssid_ie && ssid_len_ori > 0) {
2431 switch (hidden_ssid_mode) {
2432 case 1:
2433 {
2434 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
2435 u32 remain_len = 0;
2436
2437 remain_len = ies_len - (next_ie-ies);
2438
2439 ssid_ie[1] = 0;
2440 memcpy(ssid_ie+2, next_ie, remain_len);
2441 len_diff -= ssid_len_ori;
2442
2443 break;
2444 }
2445 case 2:
2446 memset(&ssid_ie[2], 0, ssid_len_ori);
2447 break;
2448 default:
2449 break;
2450 }
2451 }
2452
2453 return len_diff;
2454}
2455
2456void issue_beacon(struct adapter *padapter, int timeout_ms)
2457{
2458 struct xmit_frame *pmgntframe;
2459 struct pkt_attrib *pattrib;
2460 unsigned char *pframe;
2461 struct ieee80211_hdr *pwlanhdr;
2462 __le16 *fctrl;
2463 unsigned int rate_len;
2464 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2465 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2466 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2467 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2468 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
2469 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2470
2471
2472
2473 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2474 if (pmgntframe == NULL) {
2475 DBG_871X("%s, alloc mgnt frame fail\n", __func__);
2476 return;
2477 }
2478
2479 spin_lock_bh(&pmlmepriv->bcn_update_lock);
2480
2481
2482 pattrib = &pmgntframe->attrib;
2483 update_mgntframe_attrib(padapter, pattrib);
2484 pattrib->qsel = 0x10;
2485
2486 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2487
2488 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2489 pwlanhdr = (struct ieee80211_hdr *)pframe;
2490
2491
2492 fctrl = &(pwlanhdr->frame_control);
2493 *(fctrl) = 0;
2494
2495 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
2496 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2497 memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
2498
2499 SetSeqNum(pwlanhdr, 0);
2500
2501 SetFrameSubType(pframe, WIFI_BEACON);
2502
2503 pframe += sizeof(struct ieee80211_hdr_3addr);
2504 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2505
2506 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
2507
2508 {
2509 int len_diff;
2510 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2511 len_diff = update_hidden_ssid(
2512 pframe+_BEACON_IE_OFFSET_
2513 , cur_network->IELength-_BEACON_IE_OFFSET_
2514 , pmlmeinfo->hidden_ssid_mode
2515 );
2516 pframe += (cur_network->IELength+len_diff);
2517 pattrib->pktlen += (cur_network->IELength+len_diff);
2518 }
2519
2520 {
2521 u8 *wps_ie;
2522 uint wps_ielen;
2523 u8 sr = 0;
2524 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
2525 pattrib->pktlen-sizeof(struct ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
2526 if (wps_ie && wps_ielen > 0) {
2527 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
2528 }
2529 if (sr != 0)
2530 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
2531 else
2532 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
2533 }
2534
2535 goto _issue_bcn;
2536
2537 }
2538
2539
2540
2541
2542 pframe += 8;
2543 pattrib->pktlen += 8;
2544
2545
2546
2547 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
2548
2549 pframe += 2;
2550 pattrib->pktlen += 2;
2551
2552
2553
2554 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
2555
2556 pframe += 2;
2557 pattrib->pktlen += 2;
2558
2559
2560 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
2561
2562
2563 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
2564 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
2565
2566
2567 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
2568
2569
2570 {
2571 u8 erpinfo = 0;
2572 u32 ATIMWindow;
2573
2574
2575 ATIMWindow = 0;
2576 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
2577
2578
2579 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
2580 }
2581
2582
2583
2584 if (rate_len > 8) {
2585 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
2586 }
2587
2588
2589
2590
2591_issue_bcn:
2592
2593 pmlmepriv->update_bcn = false;
2594
2595 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
2596
2597 if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
2598 DBG_871X("beacon frame too large\n");
2599 return;
2600 }
2601
2602 pattrib->last_txcmdsz = pattrib->pktlen;
2603
2604
2605 if (timeout_ms > 0)
2606 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
2607 else
2608 dump_mgntframe(padapter, pmgntframe);
2609
2610}
2611
2612void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
2613{
2614 struct xmit_frame *pmgntframe;
2615 struct pkt_attrib *pattrib;
2616 unsigned char *pframe;
2617 struct ieee80211_hdr *pwlanhdr;
2618 __le16 *fctrl;
2619 unsigned char *mac, *bssid;
2620 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2621
2622 u8 *pwps_ie;
2623 uint wps_ielen;
2624 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2625 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2626 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2627 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
2628 unsigned int rate_len;
2629
2630
2631
2632 if (da == NULL)
2633 return;
2634
2635 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2636 if (pmgntframe == NULL) {
2637 DBG_871X("%s, alloc mgnt frame fail\n", __func__);
2638 return;
2639 }
2640
2641
2642
2643 pattrib = &pmgntframe->attrib;
2644 update_mgntframe_attrib(padapter, pattrib);
2645
2646 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2647
2648 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2649 pwlanhdr = (struct ieee80211_hdr *)pframe;
2650
2651 mac = myid(&(padapter->eeprompriv));
2652 bssid = cur_network->MacAddress;
2653
2654 fctrl = &(pwlanhdr->frame_control);
2655 *(fctrl) = 0;
2656 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
2657 memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
2658 memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
2659
2660 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2661 pmlmeext->mgnt_seq++;
2662 SetFrameSubType(fctrl, WIFI_PROBERSP);
2663
2664 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2665 pattrib->pktlen = pattrib->hdrlen;
2666 pframe += pattrib->hdrlen;
2667
2668
2669 if (cur_network->IELength > MAX_IE_SZ)
2670 return;
2671
2672 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
2673 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
2674
2675
2676 if ((pmlmepriv->wps_probe_resp_ie != NULL) && pwps_ie && (wps_ielen > 0)) {
2677 uint wps_offset, remainder_ielen;
2678 u8 *premainder_ie;
2679
2680 wps_offset = (uint)(pwps_ie - cur_network->IEs);
2681
2682 premainder_ie = pwps_ie + wps_ielen;
2683
2684 remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
2685
2686 memcpy(pframe, cur_network->IEs, wps_offset);
2687 pframe += wps_offset;
2688 pattrib->pktlen += wps_offset;
2689
2690 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];
2691 if ((wps_offset+wps_ielen+2) <= MAX_IE_SZ) {
2692 memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
2693 pframe += wps_ielen+2;
2694 pattrib->pktlen += wps_ielen+2;
2695 }
2696
2697 if ((wps_offset+wps_ielen+2+remainder_ielen) <= MAX_IE_SZ) {
2698 memcpy(pframe, premainder_ie, remainder_ielen);
2699 pframe += remainder_ielen;
2700 pattrib->pktlen += remainder_ielen;
2701 }
2702 } else{
2703 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2704 pframe += cur_network->IELength;
2705 pattrib->pktlen += cur_network->IELength;
2706 }
2707
2708
2709 {
2710 u8 *ssid_ie;
2711 sint ssid_ielen;
2712 sint ssid_ielen_diff;
2713 u8 buf[MAX_IE_SZ];
2714 u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr);
2715
2716 ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
2717 (pframe-ies)-_FIXED_IE_LENGTH_);
2718
2719 ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
2720
2721 if (ssid_ie && cur_network->Ssid.SsidLength) {
2722 uint remainder_ielen;
2723 u8 *remainder_ie;
2724 remainder_ie = ssid_ie+2;
2725 remainder_ielen = (pframe-remainder_ie);
2726
2727 if (remainder_ielen > MAX_IE_SZ) {
2728 DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
2729 remainder_ielen = MAX_IE_SZ;
2730 }
2731
2732 memcpy(buf, remainder_ie, remainder_ielen);
2733 memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
2734 *(ssid_ie+1) = cur_network->Ssid.SsidLength;
2735 memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
2736
2737 pframe += ssid_ielen_diff;
2738 pattrib->pktlen += ssid_ielen_diff;
2739 }
2740 }
2741 } else{
2742
2743 pframe += 8;
2744 pattrib->pktlen += 8;
2745
2746
2747
2748 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
2749
2750 pframe += 2;
2751 pattrib->pktlen += 2;
2752
2753
2754
2755 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
2756
2757 pframe += 2;
2758 pattrib->pktlen += 2;
2759
2760
2761
2762
2763 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
2764
2765
2766 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
2767 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
2768
2769
2770 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
2771
2772 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
2773 u8 erpinfo = 0;
2774 u32 ATIMWindow;
2775
2776
2777 ATIMWindow = 0;
2778 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
2779
2780
2781 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
2782 }
2783
2784
2785
2786 if (rate_len > 8) {
2787 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
2788 }
2789
2790
2791
2792
2793 }
2794
2795#ifdef CONFIG_AUTO_AP_MODE
2796{
2797 struct sta_info *psta;
2798 struct sta_priv *pstapriv = &padapter->stapriv;
2799
2800 DBG_871X("(%s)\n", __func__);
2801
2802
2803 psta = rtw_get_stainfo(pstapriv, da);
2804 if (psta && psta->isrc && psta->pid > 0) {
2805 u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A};
2806 u8 RC_INFO[14] = {0};
2807
2808 u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
2809
2810 DBG_871X("%s, reply rc(pid = 0x%x) device "MAC_FMT" in ch =%d\n", __func__,
2811 psta->pid, MAC_ARG(psta->hwaddr), cu_ch);
2812
2813
2814 memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
2815 memcpy(&RC_INFO[4], mac, ETH_ALEN);
2816 memcpy(&RC_INFO[10], (u8 *)&psta->pid, 2);
2817 memcpy(&RC_INFO[12], (u8 *)&cu_ch, 2);
2818
2819 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
2820 }
2821}
2822#endif
2823
2824
2825 pattrib->last_txcmdsz = pattrib->pktlen;
2826
2827
2828 dump_mgntframe(padapter, pmgntframe);
2829
2830 return;
2831
2832}
2833
2834static int _issue_probereq(struct adapter *padapter,
2835 struct ndis_802_11_ssid *pssid,
2836 u8 *da, u8 ch, bool append_wps, bool wait_ack)
2837{
2838 int ret = _FAIL;
2839 struct xmit_frame *pmgntframe;
2840 struct pkt_attrib *pattrib;
2841 unsigned char *pframe;
2842 struct ieee80211_hdr *pwlanhdr;
2843 __le16 *fctrl;
2844 unsigned char *mac;
2845 unsigned char bssrate[NumRates];
2846 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2847 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2848 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2849 int bssrate_len = 0;
2850 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2851
2852 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+issue_probereq\n"));
2853
2854 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2855 if (pmgntframe == NULL)
2856 goto exit;
2857
2858
2859 pattrib = &pmgntframe->attrib;
2860 update_mgntframe_attrib(padapter, pattrib);
2861
2862
2863 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2864
2865 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2866 pwlanhdr = (struct ieee80211_hdr *)pframe;
2867
2868 mac = myid(&(padapter->eeprompriv));
2869
2870 fctrl = &(pwlanhdr->frame_control);
2871 *(fctrl) = 0;
2872
2873 if (da) {
2874
2875 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
2876 memcpy(pwlanhdr->addr3, da, ETH_ALEN);
2877 } else{
2878
2879 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
2880 memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
2881 }
2882
2883 memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
2884
2885 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2886 pmlmeext->mgnt_seq++;
2887 SetFrameSubType(pframe, WIFI_PROBEREQ);
2888
2889 pframe += sizeof(struct ieee80211_hdr_3addr);
2890 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2891
2892 if (pssid)
2893 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
2894 else
2895 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
2896
2897 get_rate_set(padapter, bssrate, &bssrate_len);
2898
2899 if (bssrate_len > 8) {
2900 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &(pattrib->pktlen));
2901 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
2902 } else{
2903 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &(pattrib->pktlen));
2904 }
2905
2906 if (ch)
2907 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen);
2908
2909 if (append_wps) {
2910
2911 if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) {
2912 memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
2913 pframe += pmlmepriv->wps_probe_req_ie_len;
2914 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
2915 }
2916 }
2917
2918 pattrib->last_txcmdsz = pattrib->pktlen;
2919
2920 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("issuing probe_req, tx_len =%d\n", pattrib->last_txcmdsz));
2921
2922 if (wait_ack) {
2923 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
2924 } else {
2925 dump_mgntframe(padapter, pmgntframe);
2926 ret = _SUCCESS;
2927 }
2928
2929exit:
2930 return ret;
2931}
2932
2933inline void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da)
2934{
2935 _issue_probereq(padapter, pssid, da, 0, 1, false);
2936}
2937
2938int issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, u8 ch, bool append_wps,
2939 int try_cnt, int wait_ms)
2940{
2941 int ret;
2942 int i = 0;
2943
2944 do {
2945 ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms > 0?true:false);
2946
2947 i++;
2948
2949 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
2950 break;
2951
2952 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
2953 msleep(wait_ms);
2954
2955 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
2956
2957 if (ret != _FAIL) {
2958 ret = _SUCCESS;
2959 #ifndef DBG_XMIT_ACK
2960 goto exit;
2961 #endif
2962 }
2963
2964 if (try_cnt && wait_ms) {
2965 if (da)
2966 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
2967 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
2968 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
2969 else
2970 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
2971 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
2972 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
2973 }
2974exit:
2975 return ret;
2976}
2977
2978
2979void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short status)
2980{
2981 struct xmit_frame *pmgntframe;
2982 struct pkt_attrib *pattrib;
2983 unsigned char *pframe;
2984 struct ieee80211_hdr *pwlanhdr;
2985 __le16 *fctrl;
2986 unsigned int val32;
2987 unsigned short val16;
2988 int use_shared_key = 0;
2989 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2990 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2991 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2992 __le16 le_tmp;
2993
2994 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2995 if (pmgntframe == NULL)
2996 return;
2997
2998
2999 pattrib = &pmgntframe->attrib;
3000 update_mgntframe_attrib(padapter, pattrib);
3001
3002 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3003
3004 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3005 pwlanhdr = (struct ieee80211_hdr *)pframe;
3006
3007 fctrl = &(pwlanhdr->frame_control);
3008 *(fctrl) = 0;
3009
3010 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3011 pmlmeext->mgnt_seq++;
3012 SetFrameSubType(pframe, WIFI_AUTH);
3013
3014 pframe += sizeof(struct ieee80211_hdr_3addr);
3015 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3016
3017
3018 if (psta) {
3019 memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
3020 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3021 memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
3022
3023
3024 val16 = (u16)psta->authalg;
3025
3026 if (status != _STATS_SUCCESSFUL_)
3027 val16 = 0;
3028
3029 if (val16)
3030 use_shared_key = 1;
3031
3032 le_tmp = cpu_to_le16(val16);
3033
3034 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3035
3036
3037 val16 = (u16)psta->auth_seq;
3038 le_tmp = cpu_to_le16(val16);
3039 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3040
3041
3042 val16 = status;
3043 le_tmp = cpu_to_le16(val16);
3044 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3045
3046
3047 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
3048 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
3049
3050 } else{
3051 memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
3052 memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
3053 memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
3054
3055
3056 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;
3057 if (val16) {
3058 use_shared_key = 1;
3059 }
3060 le_tmp = cpu_to_le16(val16);
3061
3062
3063
3064 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
3065 __le32 le_tmp32;
3066
3067
3068 val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
3069 le_tmp32 = cpu_to_le32(val32);
3070 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&le_tmp32, &(pattrib->pktlen));
3071
3072 pattrib->iv_len = 4;
3073 }
3074
3075 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3076
3077
3078 le_tmp = cpu_to_le16(pmlmeinfo->auth_seq);
3079 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3080
3081
3082
3083 le_tmp = cpu_to_le16(status);
3084 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3085
3086
3087 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
3088 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
3089
3090 SetPrivacy(fctrl);
3091
3092 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3093
3094 pattrib->encrypt = _WEP40_;
3095
3096 pattrib->icv_len = 4;
3097
3098 pattrib->pktlen += pattrib->icv_len;
3099
3100 }
3101
3102 }
3103
3104 pattrib->last_txcmdsz = pattrib->pktlen;
3105
3106 rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
3107 DBG_871X("%s\n", __func__);
3108 dump_mgntframe(padapter, pmgntframe);
3109
3110 return;
3111}
3112
3113
3114void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
3115{
3116 struct xmit_frame *pmgntframe;
3117 struct ieee80211_hdr *pwlanhdr;
3118 struct pkt_attrib *pattrib;
3119 unsigned char *pbuf, *pframe;
3120 unsigned short val;
3121 __le16 *fctrl;
3122 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3123 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3124 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3125 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3126 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
3127 u8 *ie = pnetwork->IEs;
3128 __le16 lestatus, le_tmp;
3129
3130 DBG_871X("%s\n", __func__);
3131
3132 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3133 if (pmgntframe == NULL)
3134 return;
3135
3136
3137 pattrib = &pmgntframe->attrib;
3138 update_mgntframe_attrib(padapter, pattrib);
3139
3140
3141 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3142
3143 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3144 pwlanhdr = (struct ieee80211_hdr *)pframe;
3145
3146 fctrl = &(pwlanhdr->frame_control);
3147 *(fctrl) = 0;
3148
3149 memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
3150 memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN);
3151 memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3152
3153
3154 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3155 pmlmeext->mgnt_seq++;
3156 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
3157 SetFrameSubType(pwlanhdr, pkt_type);
3158 else
3159 return;
3160
3161 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3162 pattrib->pktlen += pattrib->hdrlen;
3163 pframe += pattrib->hdrlen;
3164
3165
3166 val = *(unsigned short *)rtw_get_capability_from_ie(ie);
3167
3168 pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_, (unsigned char *)&val, &(pattrib->pktlen));
3169
3170 lestatus = cpu_to_le16(status);
3171 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&lestatus, &(pattrib->pktlen));
3172
3173 le_tmp = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
3174 pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3175
3176 if (pstat->bssratelen <= 8) {
3177 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
3178 } else{
3179 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
3180 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
3181 }
3182
3183 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) {
3184 uint ie_len = 0;
3185
3186
3187
3188 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
3189 if (pbuf && ie_len > 0) {
3190 memcpy(pframe, pbuf, ie_len+2);
3191 pframe += (ie_len+2);
3192 pattrib->pktlen += (ie_len+2);
3193 }
3194
3195
3196
3197 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
3198 if (pbuf && ie_len > 0) {
3199 memcpy(pframe, pbuf, ie_len+2);
3200 pframe += (ie_len+2);
3201 pattrib->pktlen += (ie_len+2);
3202 }
3203
3204 }
3205
3206
3207 if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) {
3208 uint ie_len = 0;
3209 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
3210
3211 for (pbuf = ie + _BEACON_IE_OFFSET_; ; pbuf += (ie_len + 2)) {
3212 pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
3213 if (pbuf && !memcmp(pbuf+2, WMM_PARA_IE, 6)) {
3214 memcpy(pframe, pbuf, ie_len+2);
3215 pframe += (ie_len+2);
3216 pattrib->pktlen += (ie_len+2);
3217
3218 break;
3219 }
3220
3221 if ((pbuf == NULL) || (ie_len == 0)) {
3222 break;
3223 }
3224 }
3225
3226 }
3227
3228
3229 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) {
3230 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &(pattrib->pktlen));
3231 }
3232
3233
3234 if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) {
3235 memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
3236
3237 pframe += pmlmepriv->wps_assoc_resp_ie_len;
3238 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
3239 }
3240
3241 pattrib->last_txcmdsz = pattrib->pktlen;
3242
3243 dump_mgntframe(padapter, pmgntframe);
3244}
3245
3246void issue_assocreq(struct adapter *padapter)
3247{
3248 int ret = _FAIL;
3249 struct xmit_frame *pmgntframe;
3250 struct pkt_attrib *pattrib;
3251 unsigned char *pframe;
3252 struct ieee80211_hdr *pwlanhdr;
3253 __le16 *fctrl;
3254 __le16 val16;
3255 unsigned int i, j, index = 0;
3256 unsigned char bssrate[NumRates], sta_bssrate[NumRates];
3257 struct ndis_80211_var_ie *pIE;
3258 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3259 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3260 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3261 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3262 int bssrate_len = 0, sta_bssrate_len = 0;
3263 u8 vs_ie_length = 0;
3264
3265 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3266 if (pmgntframe == NULL)
3267 goto exit;
3268
3269
3270 pattrib = &pmgntframe->attrib;
3271 update_mgntframe_attrib(padapter, pattrib);
3272
3273
3274 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3275
3276 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3277 pwlanhdr = (struct ieee80211_hdr *)pframe;
3278
3279 fctrl = &(pwlanhdr->frame_control);
3280 *(fctrl) = 0;
3281 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3282 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3283 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3284
3285 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3286 pmlmeext->mgnt_seq++;
3287 SetFrameSubType(pframe, WIFI_ASSOCREQ);
3288
3289 pframe += sizeof(struct ieee80211_hdr_3addr);
3290 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3291
3292
3293 memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
3294
3295 pframe += 2;
3296 pattrib->pktlen += 2;
3297
3298
3299
3300 val16 = cpu_to_le16(3);
3301 memcpy(pframe, (unsigned char *)&val16, 2);
3302 pframe += 2;
3303 pattrib->pktlen += 2;
3304
3305
3306 pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
3307
3308
3309
3310
3311 get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
3312
3313
3314 if (pmlmeext->cur_channel == 14)
3315 sta_bssrate_len = 4;
3316
3317
3318
3319
3320
3321
3322 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3323 if (pmlmeinfo->network.SupportedRates[i] == 0)
3324 break;
3325 DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
3326 }
3327
3328
3329 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3330 if (pmlmeinfo->network.SupportedRates[i] == 0)
3331 break;
3332
3333
3334
3335 for (j = 0; j < sta_bssrate_len; j++) {
3336
3337 if ((pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
3338 == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
3339
3340 break;
3341 } else {
3342
3343 }
3344 }
3345
3346 if (j == sta_bssrate_len) {
3347
3348 DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n", __func__, i, pmlmeinfo->network.SupportedRates[i]);
3349 } else {
3350
3351 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
3352 }
3353 }
3354
3355 bssrate_len = index;
3356 DBG_871X("bssrate_len = %d\n", bssrate_len);
3357
3358 if (bssrate_len == 0) {
3359 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
3360 rtw_free_xmitframe(pxmitpriv, pmgntframe);
3361 goto exit;
3362 }
3363
3364
3365 if (bssrate_len > 8) {
3366 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &(pattrib->pktlen));
3367 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
3368 } else
3369 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &(pattrib->pktlen));
3370
3371
3372 for (i = sizeof(struct ndis_802_11_fix_ie); i < pmlmeinfo->network.IELength;) {
3373 pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.IEs + i);
3374
3375 switch (pIE->ElementID) {
3376 case _VENDOR_SPECIFIC_IE_:
3377 if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
3378 (!memcmp(pIE->data, WMM_OUI, 4)) ||
3379 (!memcmp(pIE->data, WPS_OUI, 4))) {
3380 vs_ie_length = pIE->Length;
3381 if ((!padapter->registrypriv.wifi_spec) && (!memcmp(pIE->data, WPS_OUI, 4))) {
3382
3383
3384
3385
3386 vs_ie_length = 14;
3387 }
3388
3389 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen));
3390 }
3391 break;
3392
3393 case EID_WPA2:
3394 pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
3395 break;
3396 case EID_HTCapability:
3397 if (padapter->mlmepriv.htpriv.ht_option) {
3398 if (!(is_ap_in_tkip(padapter))) {
3399 memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
3400 pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length, (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
3401 }
3402 }
3403 break;
3404
3405 case EID_EXTCapability:
3406 if (padapter->mlmepriv.htpriv.ht_option)
3407 pframe = rtw_set_ie(pframe, EID_EXTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
3408 break;
3409 default:
3410 break;
3411 }
3412
3413 i += (pIE->Length + 2);
3414 }
3415
3416 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
3417 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &(pattrib->pktlen));
3418
3419
3420 pattrib->last_txcmdsz = pattrib->pktlen;
3421 dump_mgntframe(padapter, pmgntframe);
3422
3423 ret = _SUCCESS;
3424
3425exit:
3426 if (ret == _SUCCESS)
3427 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
3428 else
3429 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
3430
3431 return;
3432}
3433
3434
3435static int _issue_nulldata(struct adapter *padapter, unsigned char *da,
3436 unsigned int power_mode, bool wait_ack)
3437{
3438 int ret = _FAIL;
3439 struct xmit_frame *pmgntframe;
3440 struct pkt_attrib *pattrib;
3441 unsigned char *pframe;
3442 struct ieee80211_hdr *pwlanhdr;
3443 __le16 *fctrl;
3444 struct xmit_priv *pxmitpriv;
3445 struct mlme_ext_priv *pmlmeext;
3446 struct mlme_ext_info *pmlmeinfo;
3447
3448
3449
3450 if (!padapter)
3451 goto exit;
3452
3453 pxmitpriv = &(padapter->xmitpriv);
3454 pmlmeext = &(padapter->mlmeextpriv);
3455 pmlmeinfo = &(pmlmeext->mlmext_info);
3456
3457 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3458 if (pmgntframe == NULL)
3459 goto exit;
3460
3461
3462 pattrib = &pmgntframe->attrib;
3463 update_mgntframe_attrib(padapter, pattrib);
3464 pattrib->retry_ctrl = false;
3465
3466 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3467
3468 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3469 pwlanhdr = (struct ieee80211_hdr *)pframe;
3470
3471 fctrl = &(pwlanhdr->frame_control);
3472 *(fctrl) = 0;
3473
3474 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3475 SetFrDs(fctrl);
3476 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3477 SetToDs(fctrl);
3478
3479 if (power_mode)
3480 SetPwrMgt(fctrl);
3481
3482 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3483 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3484 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3485
3486 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3487 pmlmeext->mgnt_seq++;
3488 SetFrameSubType(pframe, WIFI_DATA_NULL);
3489
3490 pframe += sizeof(struct ieee80211_hdr_3addr);
3491 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3492
3493 pattrib->last_txcmdsz = pattrib->pktlen;
3494
3495 if (wait_ack) {
3496 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
3497 } else{
3498 dump_mgntframe(padapter, pmgntframe);
3499 ret = _SUCCESS;
3500 }
3501
3502exit:
3503 return ret;
3504}
3505
3506
3507
3508
3509
3510
3511
3512int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
3513{
3514 int ret;
3515 int i = 0;
3516 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3517 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3518 struct sta_info *psta;
3519
3520
3521
3522 if (da == NULL)
3523 da = get_my_bssid(&(pmlmeinfo->network));
3524
3525 psta = rtw_get_stainfo(&padapter->stapriv, da);
3526 if (psta) {
3527 if (power_mode)
3528 rtw_hal_macid_sleep(padapter, psta->mac_id);
3529 else
3530 rtw_hal_macid_wakeup(padapter, psta->mac_id);
3531 } else {
3532 DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
3533 FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup");
3534 rtw_warn_on(1);
3535 }
3536
3537 do {
3538 ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0?true:false);
3539
3540 i++;
3541
3542 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3543 break;
3544
3545 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3546 msleep(wait_ms);
3547
3548 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3549
3550 if (ret != _FAIL) {
3551 ret = _SUCCESS;
3552 #ifndef DBG_XMIT_ACK
3553 goto exit;
3554 #endif
3555 }
3556
3557 if (try_cnt && wait_ms) {
3558 if (da)
3559 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
3560 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
3561 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
3562 else
3563 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
3564 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
3565 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
3566 }
3567exit:
3568 return ret;
3569}
3570
3571
3572
3573
3574
3575
3576
3577s32 issue_nulldata_in_interrupt(struct adapter *padapter, u8 *da)
3578{
3579 int ret;
3580 struct mlme_ext_priv *pmlmeext;
3581 struct mlme_ext_info *pmlmeinfo;
3582
3583
3584 pmlmeext = &padapter->mlmeextpriv;
3585 pmlmeinfo = &pmlmeext->mlmext_info;
3586
3587
3588 if (da == NULL)
3589 da = get_my_bssid(&(pmlmeinfo->network));
3590
3591 ret = _issue_nulldata(padapter, da, 0, false);
3592
3593 return ret;
3594}
3595
3596
3597static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da,
3598 u16 tid, bool wait_ack)
3599{
3600 int ret = _FAIL;
3601 struct xmit_frame *pmgntframe;
3602 struct pkt_attrib *pattrib;
3603 unsigned char *pframe;
3604 struct ieee80211_hdr *pwlanhdr;
3605 __le16 *fctrl;
3606 u16 *qc;
3607 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3608 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3609 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3610
3611 DBG_871X("%s\n", __func__);
3612
3613 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3614 if (pmgntframe == NULL)
3615 goto exit;
3616
3617
3618 pattrib = &pmgntframe->attrib;
3619 update_mgntframe_attrib(padapter, pattrib);
3620
3621 pattrib->hdrlen += 2;
3622 pattrib->qos_en = true;
3623 pattrib->eosp = 1;
3624 pattrib->ack_policy = 0;
3625 pattrib->mdata = 0;
3626
3627 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3628
3629 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3630 pwlanhdr = (struct ieee80211_hdr *)pframe;
3631
3632 fctrl = &(pwlanhdr->frame_control);
3633 *(fctrl) = 0;
3634
3635 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3636 SetFrDs(fctrl);
3637 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3638 SetToDs(fctrl);
3639
3640 if (pattrib->mdata)
3641 SetMData(fctrl);
3642
3643 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
3644
3645 SetPriority(qc, tid);
3646
3647 SetEOSP(qc, pattrib->eosp);
3648
3649 SetAckpolicy(qc, pattrib->ack_policy);
3650
3651 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3652 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3653 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3654
3655 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3656 pmlmeext->mgnt_seq++;
3657 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
3658
3659 pframe += sizeof(struct ieee80211_qos_hdr);
3660 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
3661
3662 pattrib->last_txcmdsz = pattrib->pktlen;
3663
3664 if (wait_ack) {
3665 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
3666 } else{
3667 dump_mgntframe(padapter, pmgntframe);
3668 ret = _SUCCESS;
3669 }
3670
3671exit:
3672 return ret;
3673}
3674
3675
3676
3677int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
3678{
3679 int ret;
3680 int i = 0;
3681 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3682 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3683
3684
3685 if (da == NULL)
3686 da = get_my_bssid(&(pmlmeinfo->network));
3687
3688 do {
3689 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0?true:false);
3690
3691 i++;
3692
3693 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3694 break;
3695
3696 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3697 msleep(wait_ms);
3698
3699 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3700
3701 if (ret != _FAIL) {
3702 ret = _SUCCESS;
3703 #ifndef DBG_XMIT_ACK
3704 goto exit;
3705 #endif
3706 }
3707
3708 if (try_cnt && wait_ms) {
3709 if (da)
3710 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
3711 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
3712 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
3713 else
3714 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
3715 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
3716 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
3717 }
3718exit:
3719 return ret;
3720}
3721
3722static int _issue_deauth(struct adapter *padapter, unsigned char *da,
3723 unsigned short reason, bool wait_ack)
3724{
3725 struct xmit_frame *pmgntframe;
3726 struct pkt_attrib *pattrib;
3727 unsigned char *pframe;
3728 struct ieee80211_hdr *pwlanhdr;
3729 __le16 *fctrl;
3730 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3731 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3732 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3733 int ret = _FAIL;
3734 __le16 le_tmp;
3735
3736
3737
3738 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3739 if (pmgntframe == NULL) {
3740 goto exit;
3741 }
3742
3743
3744 pattrib = &pmgntframe->attrib;
3745 update_mgntframe_attrib(padapter, pattrib);
3746 pattrib->retry_ctrl = false;
3747
3748 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3749
3750 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3751 pwlanhdr = (struct ieee80211_hdr *)pframe;
3752
3753 fctrl = &(pwlanhdr->frame_control);
3754 *(fctrl) = 0;
3755
3756 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3757 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3758 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3759
3760 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3761 pmlmeext->mgnt_seq++;
3762 SetFrameSubType(pframe, WIFI_DEAUTH);
3763
3764 pframe += sizeof(struct ieee80211_hdr_3addr);
3765 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3766
3767 le_tmp = cpu_to_le16(reason);
3768 pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3769
3770 pattrib->last_txcmdsz = pattrib->pktlen;
3771
3772
3773 if (wait_ack) {
3774 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
3775 } else{
3776 dump_mgntframe(padapter, pmgntframe);
3777 ret = _SUCCESS;
3778 }
3779
3780exit:
3781 return ret;
3782}
3783
3784int issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason)
3785{
3786 DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
3787 return _issue_deauth(padapter, da, reason, false);
3788}
3789
3790int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
3791 int wait_ms)
3792{
3793 int ret;
3794 int i = 0;
3795
3796 do {
3797 ret = _issue_deauth(padapter, da, reason, wait_ms > 0?true:false);
3798
3799 i++;
3800
3801 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3802 break;
3803
3804 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3805 msleep(wait_ms);
3806
3807 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3808
3809 if (ret != _FAIL) {
3810 ret = _SUCCESS;
3811 #ifndef DBG_XMIT_ACK
3812 goto exit;
3813 #endif
3814 }
3815
3816 if (try_cnt && wait_ms) {
3817 if (da)
3818 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
3819 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
3820 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
3821 else
3822 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
3823 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
3824 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
3825 }
3826exit:
3827 return ret;
3828}
3829
3830void issue_action_SA_Query(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid)
3831{
3832 u8 category = RTW_WLAN_CATEGORY_SA_QUERY;
3833 struct xmit_frame *pmgntframe;
3834 struct pkt_attrib *pattrib;
3835 u8 *pframe;
3836 struct ieee80211_hdr *pwlanhdr;
3837 __le16 *fctrl;
3838 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3839 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3840 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3841 __le16 le_tmp;
3842
3843 DBG_871X("%s\n", __func__);
3844
3845 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3846 if (pmgntframe == NULL) {
3847 DBG_871X("%s: alloc_mgtxmitframe fail\n", __func__);
3848 return;
3849 }
3850
3851
3852 pattrib = &pmgntframe->attrib;
3853 update_mgntframe_attrib(padapter, pattrib);
3854
3855 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3856
3857 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3858 pwlanhdr = (struct ieee80211_hdr *)pframe;
3859
3860 fctrl = &(pwlanhdr->frame_control);
3861 *(fctrl) = 0;
3862
3863 if (raddr)
3864 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3865 else
3866 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3867 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3868 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3869
3870 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3871 pmlmeext->mgnt_seq++;
3872 SetFrameSubType(pframe, WIFI_ACTION);
3873
3874 pframe += sizeof(struct ieee80211_hdr_3addr);
3875 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3876
3877 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
3878 pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
3879
3880 switch (action) {
3881 case 0:
3882 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
3883 pmlmeext->sa_query_seq++;
3884
3885 set_sa_query_timer(pmlmeext, 1000);
3886 break;
3887
3888 case 1:
3889 le_tmp = cpu_to_le16(tid);
3890 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
3891 break;
3892 default:
3893 break;
3894 }
3895
3896 pattrib->last_txcmdsz = pattrib->pktlen;
3897
3898 dump_mgntframe(padapter, pmgntframe);
3899}
3900
3901void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status)
3902{
3903 u8 category = RTW_WLAN_CATEGORY_BACK;
3904 u16 start_seq;
3905 u16 BA_para_set;
3906 u16 reason_code;
3907 u16 BA_timeout_value;
3908 u16 BA_starting_seqctrl = 0;
3909 enum HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
3910 struct xmit_frame *pmgntframe;
3911 struct pkt_attrib *pattrib;
3912 u8 *pframe;
3913 struct ieee80211_hdr *pwlanhdr;
3914 __le16 *fctrl;
3915 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3916 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3917 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3918 struct sta_info *psta;
3919 struct sta_priv *pstapriv = &padapter->stapriv;
3920 struct registry_priv *pregpriv = &padapter->registrypriv;
3921 __le16 le_tmp;
3922
3923 DBG_871X("%s, category =%d, action =%d, status =%d\n", __func__, category, action, status);
3924
3925 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3926 if (pmgntframe == NULL)
3927 return;
3928
3929
3930 pattrib = &pmgntframe->attrib;
3931 update_mgntframe_attrib(padapter, pattrib);
3932
3933 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3934
3935 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3936 pwlanhdr = (struct ieee80211_hdr *)pframe;
3937
3938 fctrl = &(pwlanhdr->frame_control);
3939 *(fctrl) = 0;
3940
3941
3942 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3943 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3944 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3945
3946 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3947 pmlmeext->mgnt_seq++;
3948 SetFrameSubType(pframe, WIFI_ACTION);
3949
3950 pframe += sizeof(struct ieee80211_hdr_3addr);
3951 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3952
3953 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3954 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3955
3956 if (category == 3) {
3957 switch (action) {
3958 case 0:
3959 do {
3960 pmlmeinfo->dialogToken++;
3961 } while (pmlmeinfo->dialogToken == 0);
3962 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
3963
3964 if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(padapter)) {
3965
3966 BA_para_set = 0;
3967
3968 BA_para_set |= (1 << 1) & IEEE80211_ADDBA_PARAM_POLICY_MASK;
3969
3970 BA_para_set |= (status << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
3971
3972 BA_para_set |= (8 << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3973 } else {
3974 BA_para_set = (0x1002 | ((status & 0xf) << 2));
3975 }
3976 le_tmp = cpu_to_le16(BA_para_set);
3977 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
3978
3979 BA_timeout_value = 5000;
3980 le_tmp = cpu_to_le16(BA_timeout_value);
3981 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
3982
3983
3984 psta = rtw_get_stainfo(pstapriv, raddr);
3985 if (psta != NULL) {
3986 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
3987
3988 DBG_871X("BA_starting_seqctrl = %d for TID =%d\n", start_seq, status & 0x07);
3989
3990 psta->BA_starting_seqctrl[status & 0x07] = start_seq;
3991
3992 BA_starting_seqctrl = start_seq << 4;
3993 }
3994
3995 le_tmp = cpu_to_le16(BA_starting_seqctrl);
3996 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
3997 break;
3998
3999 case 1:
4000 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
4001 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
4002 if (padapter->driver_rx_ampdu_factor != 0xFF)
4003 max_rx_ampdu_factor =
4004 (enum HT_CAP_AMPDU_FACTOR)padapter->driver_rx_ampdu_factor;
4005 else
4006 rtw_hal_get_def_var(padapter,
4007 HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
4008
4009 if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
4010 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000);
4011 else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
4012 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800);
4013 else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
4014 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400);
4015 else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
4016 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200);
4017 else
4018 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000);
4019
4020 if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(padapter) &&
4021 padapter->driver_rx_ampdu_factor == 0xFF) {
4022
4023 BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4024 BA_para_set |= (8 << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4025 }
4026
4027 if (pregpriv->ampdu_amsdu == 0)
4028 le_tmp = cpu_to_le16(BA_para_set & ~BIT(0));
4029 else if (pregpriv->ampdu_amsdu == 1)
4030 le_tmp = cpu_to_le16(BA_para_set | BIT(0));
4031 else
4032 le_tmp = cpu_to_le16(BA_para_set);
4033
4034 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
4035 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
4036 break;
4037 case 2:
4038 BA_para_set = (status & 0x1F) << 3;
4039 le_tmp = cpu_to_le16(BA_para_set);
4040 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
4041
4042 reason_code = 37;
4043 le_tmp = cpu_to_le16(reason_code);
4044 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
4045 break;
4046 default:
4047 break;
4048 }
4049 }
4050
4051 pattrib->last_txcmdsz = pattrib->pktlen;
4052
4053 dump_mgntframe(padapter, pmgntframe);
4054}
4055
4056static void issue_action_BSSCoexistPacket(struct adapter *padapter)
4057{
4058 struct list_head *plist, *phead;
4059 unsigned char category, action;
4060 struct xmit_frame *pmgntframe;
4061 struct pkt_attrib *pattrib;
4062 unsigned char *pframe;
4063 struct ieee80211_hdr *pwlanhdr;
4064 __le16 *fctrl;
4065 struct wlan_network *pnetwork = NULL;
4066 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4067 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4068 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4069 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4070 struct __queue *queue = &(pmlmepriv->scanned_queue);
4071 u8 InfoContent[16] = {0};
4072 u8 ICS[8][15];
4073
4074 if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0))
4075 return;
4076
4077 if (true == pmlmeinfo->bwmode_updated)
4078 return;
4079
4080
4081 DBG_871X("%s\n", __func__);
4082
4083
4084 category = RTW_WLAN_CATEGORY_PUBLIC;
4085 action = ACT_PUBLIC_BSSCOEXIST;
4086
4087 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4088 if (pmgntframe == NULL) {
4089 return;
4090 }
4091
4092
4093 pattrib = &pmgntframe->attrib;
4094 update_mgntframe_attrib(padapter, pattrib);
4095
4096 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4097
4098 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4099 pwlanhdr = (struct ieee80211_hdr *)pframe;
4100
4101 fctrl = &(pwlanhdr->frame_control);
4102 *(fctrl) = 0;
4103
4104 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
4105 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
4106 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
4107
4108 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4109 pmlmeext->mgnt_seq++;
4110 SetFrameSubType(pframe, WIFI_ACTION);
4111
4112 pframe += sizeof(struct ieee80211_hdr_3addr);
4113 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
4114
4115 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4116 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4117
4118
4119
4120 if (pmlmepriv->num_FortyMHzIntolerant > 0) {
4121 u8 iedata = 0;
4122
4123 iedata |= BIT(2);
4124
4125 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
4126
4127 }
4128
4129
4130
4131 memset(ICS, 0, sizeof(ICS));
4132 if (pmlmepriv->num_sta_no_ht > 0) {
4133 int i;
4134
4135 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
4136
4137 phead = get_list_head(queue);
4138 plist = get_next(phead);
4139
4140 while (1) {
4141 int len;
4142 u8 *p;
4143 struct wlan_bssid_ex *pbss_network;
4144
4145 if (phead == plist)
4146 break;
4147
4148 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4149
4150 plist = get_next(plist);
4151
4152 pbss_network = (struct wlan_bssid_ex *)&pnetwork->network;
4153
4154 p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
4155 if ((p == NULL) || (len == 0)) {
4156
4157 if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
4158 continue;
4159
4160 ICS[0][pbss_network->Configuration.DSConfig] = 1;
4161
4162 if (ICS[0][0] == 0)
4163 ICS[0][0] = 1;
4164 }
4165
4166 }
4167
4168 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
4169
4170
4171 for (i = 0; i < 8; i++) {
4172 if (ICS[i][0] == 1) {
4173 int j, k = 0;
4174
4175 InfoContent[k] = i;
4176
4177 k++;
4178
4179 for (j = 1; j <= 14; j++) {
4180 if (ICS[i][j] == 1) {
4181 if (k < 16) {
4182 InfoContent[k] = j;
4183
4184 k++;
4185 }
4186 }
4187 }
4188
4189 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
4190
4191 }
4192
4193 }
4194
4195
4196 }
4197
4198
4199 pattrib->last_txcmdsz = pattrib->pktlen;
4200
4201 dump_mgntframe(padapter, pmgntframe);
4202}
4203
4204unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr)
4205{
4206 struct sta_priv *pstapriv = &padapter->stapriv;
4207 struct sta_info *psta = NULL;
4208
4209 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4210 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4211 u16 tid;
4212
4213 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
4214 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
4215 return _SUCCESS;
4216
4217 psta = rtw_get_stainfo(pstapriv, addr);
4218 if (psta == NULL)
4219 return _SUCCESS;
4220
4221
4222
4223 if (initiator == 0) {
4224 for (tid = 0; tid < MAXTID; tid++) {
4225 if (psta->recvreorder_ctrl[tid].enable) {
4226 DBG_871X("rx agg disable tid(%d)\n", tid);
4227 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator)&0x1F));
4228 psta->recvreorder_ctrl[tid].enable = false;
4229 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
4230 #ifdef DBG_RX_SEQ
4231 DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u\n", __func__, __LINE__,
4232 psta->recvreorder_ctrl[tid].indicate_seq);
4233 #endif
4234 }
4235 }
4236 } else if (initiator == 1) {
4237
4238 for (tid = 0; tid < MAXTID; tid++) {
4239 if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
4240 DBG_871X("tx agg disable tid(%d)\n", tid);
4241 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator)&0x1F));
4242 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
4243 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
4244
4245 }
4246 }
4247 }
4248
4249 return _SUCCESS;
4250
4251}
4252
4253unsigned int send_beacon(struct adapter *padapter)
4254{
4255 u8 bxmitok = false;
4256 int issue = 0;
4257 int poll = 0;
4258 unsigned long start = jiffies;
4259
4260 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
4261 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
4262 do {
4263 issue_beacon(padapter, 100);
4264 issue++;
4265 do {
4266 cond_resched();
4267 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
4268 poll++;
4269 } while ((poll%10) != 0 && false == bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
4270
4271 } while (false == bxmitok && issue < 100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
4272
4273 if (padapter->bSurpriseRemoved || padapter->bDriverStopped) {
4274 return _FAIL;
4275 }
4276
4277
4278 if (false == bxmitok) {
4279 DBG_871X("%s fail! %u ms\n", __func__, jiffies_to_msecs(jiffies - start));
4280 return _FAIL;
4281 } else{
4282 unsigned long passing_time = jiffies_to_msecs(jiffies - start);
4283
4284 if (passing_time > 100 || issue > 3)
4285 DBG_871X("%s success, issue:%d, poll:%d, %lu ms\n", __func__, issue, poll, passing_time);
4286
4287
4288
4289 return _SUCCESS;
4290 }
4291}
4292
4293
4294
4295
4296
4297
4298
4299void site_survey(struct adapter *padapter)
4300{
4301 unsigned char survey_channel = 0, val8;
4302 RT_SCAN_TYPE ScanType = SCAN_PASSIVE;
4303 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4304 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4305 u32 initialgain = 0;
4306 u32 channel_scan_time_ms = 0;
4307
4308 {
4309 struct rtw_ieee80211_channel *ch;
4310 if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
4311 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
4312 survey_channel = ch->hw_value;
4313 ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
4314 }
4315 }
4316
4317 DBG_871X(FUNC_ADPT_FMT" ch:%u (cnt:%u) at %dms, %c%c%c\n"
4318 , FUNC_ADPT_ARG(padapter)
4319 , survey_channel
4320 , pmlmeext->sitesurvey_res.channel_idx
4321 , jiffies_to_msecs(jiffies - padapter->mlmepriv.scan_start_time)
4322 , ScanType?'A':'P', pmlmeext->sitesurvey_res.scan_mode?'A':'P'
4323 , pmlmeext->sitesurvey_res.ssid[0].SsidLength?'S':' '
4324 );
4325#ifdef DBG_FIXED_CHAN
4326 DBG_871X(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
4327#endif
4328
4329 if (survey_channel != 0) {
4330
4331
4332
4333
4334 if (pmlmeext->sitesurvey_res.channel_idx == 0) {
4335#ifdef DBG_FIXED_CHAN
4336 if (pmlmeext->fixed_chan != 0xff)
4337 set_channel_bwmode(padapter, pmlmeext->fixed_chan, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4338 else
4339#endif
4340 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4341 } else{
4342#ifdef DBG_FIXED_CHAN
4343 if (pmlmeext->fixed_chan != 0xff)
4344 SelectChannel(padapter, pmlmeext->fixed_chan);
4345 else
4346#endif
4347 SelectChannel(padapter, survey_channel);
4348 }
4349
4350 if (ScanType == SCAN_ACTIVE) {
4351 {
4352 int i;
4353 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
4354 if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
4355
4356 if (padapter->registrypriv.wifi_spec)
4357 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
4358 else
4359 issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
4360 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
4361 }
4362 }
4363
4364 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
4365
4366 if (padapter->registrypriv.wifi_spec)
4367 issue_probereq(padapter, NULL, NULL);
4368 else
4369 issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
4370 issue_probereq(padapter, NULL, NULL);
4371 }
4372 }
4373 }
4374
4375 channel_scan_time_ms = pmlmeext->chan_scan_time;
4376
4377 set_survey_timer(pmlmeext, channel_scan_time_ms);
4378#if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
4379 {
4380 struct noise_info info;
4381 info.bPauseDIG = false;
4382 info.IGIValue = 0;
4383 info.max_time = channel_scan_time_ms/2;
4384 info.chan = survey_channel;
4385 rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, false);
4386 }
4387#endif
4388
4389 } else{
4390
4391
4392
4393 {
4394 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
4395
4396
4397
4398
4399 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4400
4401
4402
4403
4404
4405
4406 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
4407
4408 initialgain = 0xff;
4409 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
4410
4411 Restore_DM_Func_Flag(padapter);
4412
4413
4414 if (is_client_associated_to_ap(padapter))
4415 issue_nulldata(padapter, NULL, 0, 3, 500);
4416
4417 val8 = 0;
4418 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
4419
4420 report_surveydone_event(padapter);
4421
4422 pmlmeext->chan_scan_time = SURVEY_TO;
4423 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
4424
4425 issue_action_BSSCoexistPacket(padapter);
4426 issue_action_BSSCoexistPacket(padapter);
4427 issue_action_BSSCoexistPacket(padapter);
4428 }
4429 }
4430
4431 return;
4432
4433}
4434
4435
4436u8 collect_bss_info(struct adapter *padapter, union recv_frame *precv_frame, struct wlan_bssid_ex *bssid)
4437{
4438 int i;
4439 u32 len;
4440 u8 *p;
4441 u16 val16, subtype;
4442 u8 *pframe = precv_frame->u.hdr.rx_data;
4443 u32 packet_len = precv_frame->u.hdr.len;
4444 u8 ie_offset;
4445 struct registry_priv *pregistrypriv = &padapter->registrypriv;
4446 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4447 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4448 __le32 le32_tmp;
4449
4450 len = packet_len - sizeof(struct ieee80211_hdr_3addr);
4451
4452 if (len > MAX_IE_SZ) {
4453
4454 return _FAIL;
4455 }
4456
4457 memset(bssid, 0, sizeof(struct wlan_bssid_ex));
4458
4459 subtype = GetFrameSubType(pframe);
4460
4461 if (subtype == WIFI_BEACON) {
4462 bssid->Reserved[0] = 1;
4463 ie_offset = _BEACON_IE_OFFSET_;
4464 } else {
4465
4466 if (subtype == WIFI_PROBERSP) {
4467 ie_offset = _PROBERSP_IE_OFFSET_;
4468 bssid->Reserved[0] = 3;
4469 } else if (subtype == WIFI_PROBEREQ) {
4470 ie_offset = _PROBEREQ_IE_OFFSET_;
4471 bssid->Reserved[0] = 2;
4472 } else {
4473 bssid->Reserved[0] = 0;
4474 ie_offset = _FIXED_IE_LENGTH_;
4475 }
4476 }
4477
4478 bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len;
4479
4480
4481 bssid->IELength = len;
4482 memcpy(bssid->IEs, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->IELength);
4483
4484
4485 bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower;
4486 bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;
4487 bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;
4488
4489
4490 p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset);
4491 if (p == NULL) {
4492 DBG_871X("marc: cannot find SSID for survey event\n");
4493 return _FAIL;
4494 }
4495
4496 if (*(p + 1)) {
4497 if (len > NDIS_802_11_LENGTH_SSID) {
4498 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
4499 return _FAIL;
4500 }
4501 memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
4502 bssid->Ssid.SsidLength = *(p + 1);
4503 } else
4504 bssid->Ssid.SsidLength = 0;
4505
4506 memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
4507
4508
4509 i = 0;
4510 p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
4511 if (p != NULL) {
4512 if (len > NDIS_802_11_LENGTH_RATES_EX) {
4513 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
4514 return _FAIL;
4515 }
4516 memcpy(bssid->SupportedRates, (p + 2), len);
4517 i = len;
4518 }
4519
4520 p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
4521 if (p != NULL) {
4522 if (len > (NDIS_802_11_LENGTH_RATES_EX-i)) {
4523 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
4524 return _FAIL;
4525 }
4526 memcpy(bssid->SupportedRates + i, (p + 2), len);
4527 }
4528
4529 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
4530
4531 if (bssid->IELength < 12)
4532 return _FAIL;
4533
4534
4535 p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
4536
4537 bssid->Configuration.DSConfig = 0;
4538 bssid->Configuration.Length = 0;
4539
4540 if (p) {
4541 bssid->Configuration.DSConfig = *(p + 2);
4542 } else {
4543
4544
4545 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
4546 if (p) {
4547 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
4548 bssid->Configuration.DSConfig = HT_info->primary_channel;
4549 } else {
4550 bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
4551 }
4552 }
4553
4554 memcpy(&le32_tmp, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
4555 bssid->Configuration.BeaconPeriod = le32_to_cpu(le32_tmp);
4556
4557 val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid);
4558
4559 if (val16 & BIT(0)) {
4560 bssid->InfrastructureMode = Ndis802_11Infrastructure;
4561 memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
4562 } else {
4563 bssid->InfrastructureMode = Ndis802_11IBSS;
4564 memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
4565 }
4566
4567 if (val16 & BIT(4))
4568 bssid->Privacy = 1;
4569 else
4570 bssid->Privacy = 0;
4571
4572 bssid->Configuration.ATIMWindow = 0;
4573
4574
4575 if ((pregistrypriv->wifi_spec == 1) && (false == pmlmeinfo->bwmode_updated)) {
4576 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4577
4578 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
4579 if (p && len > 0) {
4580 struct HT_caps_element *pHT_caps;
4581 pHT_caps = (struct HT_caps_element *)(p + 2);
4582
4583 if (le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info) & BIT(14))
4584 pmlmepriv->num_FortyMHzIntolerant++;
4585 } else
4586 pmlmepriv->num_sta_no_ht++;
4587 }
4588
4589#ifdef CONFIG_INTEL_WIDI
4590
4591 if (process_intel_widi_query_or_tigger(padapter, bssid))
4592 return _FAIL;
4593#endif
4594
4595 #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
4596 if (strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
4597 DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
4598 , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
4599 , rtw_get_oper_ch(padapter)
4600 , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
4601 );
4602 }
4603 #endif
4604
4605
4606 if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
4607 bssid->PhyInfo.SignalQuality = 101;
4608
4609 return _SUCCESS;
4610}
4611
4612void start_create_ibss(struct adapter *padapter)
4613{
4614 unsigned short caps;
4615 u8 val8;
4616 u8 join_type;
4617 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4618 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4619 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
4620 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
4621 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
4622
4623
4624 update_wireless_mode(padapter);
4625
4626
4627 caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
4628 update_capinfo(padapter, caps);
4629 if (caps&cap_IBSS) {
4630 val8 = 0xcf;
4631 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
4632
4633 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
4634
4635
4636
4637 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4638
4639 beacon_timing_control(padapter);
4640
4641
4642 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4643 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
4644
4645
4646 if (send_beacon(padapter) == _FAIL) {
4647 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("issuing beacon frame fail....\n"));
4648
4649 report_join_res(padapter, -1);
4650 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4651 } else{
4652 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
4653 join_type = 0;
4654 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
4655
4656 report_join_res(padapter, 1);
4657 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
4658 rtw_indicate_connect(padapter);
4659 }
4660 } else{
4661 DBG_871X("start_create_ibss, invalid cap:%x\n", caps);
4662 return;
4663 }
4664
4665 update_bmc_sta(padapter);
4666
4667}
4668
4669void start_clnt_join(struct adapter *padapter)
4670{
4671 unsigned short caps;
4672 u8 val8;
4673 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4674 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4675 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
4676 int beacon_timeout;
4677
4678
4679 update_wireless_mode(padapter);
4680
4681
4682 caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
4683 update_capinfo(padapter, caps);
4684 if (caps&cap_ESS) {
4685 Set_MSR(padapter, WIFI_FW_STATION_STATE);
4686
4687 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
4688
4689 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
4690
4691
4692
4693
4694
4695
4696
4697 {
4698
4699 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
4700 }
4701
4702
4703
4704 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
4705 set_link_timer(pmlmeext, beacon_timeout);
4706 _set_timer(&padapter->mlmepriv.assoc_timer,
4707 (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout);
4708
4709 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
4710 } else if (caps&cap_IBSS) {
4711 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
4712
4713 val8 = 0xcf;
4714 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
4715
4716 beacon_timing_control(padapter);
4717
4718 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4719
4720 report_join_res(padapter, 1);
4721 } else{
4722
4723 return;
4724 }
4725
4726}
4727
4728void start_clnt_auth(struct adapter *padapter)
4729{
4730 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4731 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4732
4733 del_timer_sync(&pmlmeext->link_timer);
4734
4735 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
4736 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
4737
4738 pmlmeinfo->auth_seq = 1;
4739 pmlmeinfo->reauth_count = 0;
4740 pmlmeinfo->reassoc_count = 0;
4741 pmlmeinfo->link_count = 0;
4742 pmlmeext->retry = 0;
4743
4744
4745 DBG_871X_LEVEL(_drv_always_, "start auth\n");
4746 issue_auth(padapter, NULL, 0);
4747
4748 set_link_timer(pmlmeext, REAUTH_TO);
4749
4750}
4751
4752
4753void start_clnt_assoc(struct adapter *padapter)
4754{
4755 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4756 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4757
4758 del_timer_sync(&pmlmeext->link_timer);
4759
4760 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
4761 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
4762
4763 issue_assocreq(padapter);
4764
4765 set_link_timer(pmlmeext, REASSOC_TO);
4766}
4767
4768unsigned int receive_disconnect(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason)
4769{
4770 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4771 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4772
4773
4774 if (!(!memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
4775 return _SUCCESS;
4776
4777 DBG_871X("%s\n", __func__);
4778
4779 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
4780 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
4781 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4782 report_del_sta_event(padapter, MacAddr, reason);
4783
4784 } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) {
4785 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4786 report_join_res(padapter, -2);
4787 }
4788 }
4789
4790 return _SUCCESS;
4791}
4792
4793static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid)
4794{
4795 struct registry_priv *pregistrypriv;
4796 struct mlme_ext_priv *pmlmeext;
4797 RT_CHANNEL_INFO *chplan_new;
4798 u8 channel;
4799 u8 i;
4800
4801
4802 pregistrypriv = &padapter->registrypriv;
4803 pmlmeext = &padapter->mlmeextpriv;
4804
4805
4806 if (pregistrypriv->enable80211d &&
4807 (!pmlmeext->update_channel_plan_by_ap_done)) {
4808 u8 *ie, *p;
4809 u32 len;
4810 RT_CHANNEL_PLAN chplan_ap;
4811 RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
4812 u8 country[4];
4813 u8 fcn;
4814 u8 noc;
4815 u8 j, k;
4816
4817 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
4818 if (!ie)
4819 return;
4820 if (len < 6)
4821 return;
4822
4823 ie += 2;
4824 p = ie;
4825 ie += len;
4826
4827 memset(country, 0, 4);
4828 memcpy(country, p, 3);
4829 p += 3;
4830 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4831 ("%s: 802.11d country =%s\n", __func__, country));
4832
4833 i = 0;
4834 while ((ie - p) >= 3) {
4835 fcn = *(p++);
4836 noc = *(p++);
4837 p++;
4838
4839 for (j = 0; j < noc; j++) {
4840 if (fcn <= 14)
4841 channel = fcn + j;
4842 else
4843 channel = fcn + j*4;
4844
4845 chplan_ap.Channel[i++] = channel;
4846 }
4847 }
4848 chplan_ap.Len = i;
4849
4850#ifdef DEBUG_RTL871X
4851 i = 0;
4852 DBG_871X("%s: AP[%s] channel plan {", __func__, bssid->Ssid.Ssid);
4853 while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0)) {
4854 DBG_8192C("%02d,", chplan_ap.Channel[i]);
4855 i++;
4856 }
4857 DBG_871X("}\n");
4858#endif
4859
4860 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
4861#ifdef DEBUG_RTL871X
4862 i = 0;
4863 DBG_871X("%s: STA channel plan {", __func__);
4864 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
4865 DBG_871X("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType == SCAN_PASSIVE?'p':'a');
4866 i++;
4867 }
4868 DBG_871X("}\n");
4869#endif
4870
4871 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
4872 chplan_new = pmlmeext->channel_set;
4873
4874 i = j = k = 0;
4875 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
4876 do {
4877 if ((i == MAX_CHANNEL_NUM) ||
4878 (chplan_sta[i].ChannelNum == 0) ||
4879 (chplan_sta[i].ChannelNum > 14))
4880 break;
4881
4882 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
4883 break;
4884
4885 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
4886 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4887 chplan_new[k].ScanType = SCAN_ACTIVE;
4888 i++;
4889 j++;
4890 k++;
4891 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
4892 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4893
4894 chplan_new[k].ScanType = SCAN_PASSIVE;
4895 i++;
4896 k++;
4897 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
4898 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4899 chplan_new[k].ScanType = SCAN_ACTIVE;
4900 j++;
4901 k++;
4902 }
4903 } while (1);
4904
4905
4906 while ((i < MAX_CHANNEL_NUM) &&
4907 (chplan_sta[i].ChannelNum != 0) &&
4908 (chplan_sta[i].ChannelNum <= 14)) {
4909
4910 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4911
4912 chplan_new[k].ScanType = SCAN_PASSIVE;
4913 i++;
4914 k++;
4915 }
4916
4917
4918 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
4919 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4920 chplan_new[k].ScanType = SCAN_ACTIVE;
4921 j++;
4922 k++;
4923 }
4924 } else{
4925
4926 while ((i < MAX_CHANNEL_NUM) &&
4927 (chplan_sta[i].ChannelNum != 0) &&
4928 (chplan_sta[i].ChannelNum <= 14)) {
4929 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4930 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4931 i++;
4932 k++;
4933 }
4934
4935
4936 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
4937 j++;
4938 }
4939 }
4940
4941 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
4942 do {
4943 if ((i == MAX_CHANNEL_NUM) ||
4944 (chplan_sta[i].ChannelNum == 0))
4945 break;
4946
4947 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
4948 break;
4949
4950 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
4951 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4952 chplan_new[k].ScanType = SCAN_ACTIVE;
4953 i++;
4954 j++;
4955 k++;
4956 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
4957 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4958
4959 chplan_new[k].ScanType = SCAN_PASSIVE;
4960 i++;
4961 k++;
4962 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
4963 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4964 chplan_new[k].ScanType = SCAN_ACTIVE;
4965 j++;
4966 k++;
4967 }
4968 } while (1);
4969
4970
4971 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
4972 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4973
4974 chplan_new[k].ScanType = SCAN_PASSIVE;
4975 i++;
4976 k++;
4977 }
4978
4979
4980 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) {
4981 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4982 chplan_new[k].ScanType = SCAN_ACTIVE;
4983 j++;
4984 k++;
4985 }
4986 } else{
4987
4988 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
4989 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4990 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4991 i++;
4992 k++;
4993 }
4994 }
4995
4996 pmlmeext->update_channel_plan_by_ap_done = 1;
4997
4998#ifdef DEBUG_RTL871X
4999 k = 0;
5000 DBG_871X("%s: new STA channel plan {", __func__);
5001 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) {
5002 DBG_871X("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType == SCAN_PASSIVE?'p':'c');
5003 k++;
5004 }
5005 DBG_871X("}\n");
5006#endif
5007 }
5008
5009
5010 channel = bssid->Configuration.DSConfig;
5011 chplan_new = pmlmeext->channel_set;
5012 i = 0;
5013 while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) {
5014 if (chplan_new[i].ChannelNum == channel) {
5015 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
5016
5017 if (channel >= 52 && channel <= 144)
5018 break;
5019
5020 chplan_new[i].ScanType = SCAN_ACTIVE;
5021 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
5022 ("%s: change channel %d scan type from passive to active\n",
5023 __func__, channel));
5024 }
5025 break;
5026 }
5027 i++;
5028 }
5029}
5030
5031
5032
5033
5034
5035
5036
5037void report_survey_event(struct adapter *padapter, union recv_frame *precv_frame)
5038{
5039 struct cmd_obj *pcmd_obj;
5040 u8 *pevtcmd;
5041 u32 cmdsz;
5042 struct survey_event *psurvey_evt;
5043 struct C2HEvent_Header *pc2h_evt_hdr;
5044 struct mlme_ext_priv *pmlmeext;
5045 struct cmd_priv *pcmdpriv;
5046
5047
5048
5049 if (!padapter)
5050 return;
5051
5052 pmlmeext = &padapter->mlmeextpriv;
5053 pcmdpriv = &padapter->cmdpriv;
5054
5055 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
5056 if (pcmd_obj == NULL)
5057 return;
5058
5059 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
5060 pevtcmd = rtw_zmalloc(cmdsz);
5061 if (pevtcmd == NULL) {
5062 kfree((u8 *)pcmd_obj);
5063 return;
5064 }
5065
5066 INIT_LIST_HEAD(&pcmd_obj->list);
5067
5068 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5069 pcmd_obj->cmdsz = cmdsz;
5070 pcmd_obj->parmbuf = pevtcmd;
5071
5072 pcmd_obj->rsp = NULL;
5073 pcmd_obj->rspsz = 0;
5074
5075 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
5076 pc2h_evt_hdr->len = sizeof(struct survey_event);
5077 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
5078 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5079
5080 psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
5081
5082 if (collect_bss_info(padapter, precv_frame, (struct wlan_bssid_ex *)&psurvey_evt->bss) == _FAIL) {
5083 kfree((u8 *)pcmd_obj);
5084 kfree((u8 *)pevtcmd);
5085 return;
5086 }
5087
5088 process_80211d(padapter, &psurvey_evt->bss);
5089
5090 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
5091
5092 pmlmeext->sitesurvey_res.bss_cnt++;
5093
5094 return;
5095
5096}
5097
5098void report_surveydone_event(struct adapter *padapter)
5099{
5100 struct cmd_obj *pcmd_obj;
5101 u8 *pevtcmd;
5102 u32 cmdsz;
5103 struct surveydone_event *psurveydone_evt;
5104 struct C2HEvent_Header *pc2h_evt_hdr;
5105 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5106 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5107
5108 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
5109 if (pcmd_obj == NULL)
5110 return;
5111
5112 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
5113 pevtcmd = rtw_zmalloc(cmdsz);
5114 if (pevtcmd == NULL) {
5115 kfree((u8 *)pcmd_obj);
5116 return;
5117 }
5118
5119 INIT_LIST_HEAD(&pcmd_obj->list);
5120
5121 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5122 pcmd_obj->cmdsz = cmdsz;
5123 pcmd_obj->parmbuf = pevtcmd;
5124
5125 pcmd_obj->rsp = NULL;
5126 pcmd_obj->rspsz = 0;
5127
5128 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
5129 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
5130 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
5131 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5132
5133 psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
5134 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
5135
5136 DBG_871X("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
5137
5138 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
5139
5140 return;
5141
5142}
5143
5144void report_join_res(struct adapter *padapter, int res)
5145{
5146 struct cmd_obj *pcmd_obj;
5147 u8 *pevtcmd;
5148 u32 cmdsz;
5149 struct joinbss_event *pjoinbss_evt;
5150 struct C2HEvent_Header *pc2h_evt_hdr;
5151 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5152 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5153 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5154
5155 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
5156 if (pcmd_obj == NULL)
5157 return;
5158
5159 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
5160 pevtcmd = rtw_zmalloc(cmdsz);
5161 if (pevtcmd == NULL) {
5162 kfree((u8 *)pcmd_obj);
5163 return;
5164 }
5165
5166 INIT_LIST_HEAD(&pcmd_obj->list);
5167
5168 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5169 pcmd_obj->cmdsz = cmdsz;
5170 pcmd_obj->parmbuf = pevtcmd;
5171
5172 pcmd_obj->rsp = NULL;
5173 pcmd_obj->rspsz = 0;
5174
5175 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
5176 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
5177 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
5178 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5179
5180 pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
5181 memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex));
5182 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
5183
5184 DBG_871X("report_join_res(%d)\n", res);
5185
5186
5187 rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
5188
5189
5190 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
5191
5192 return;
5193
5194}
5195
5196void report_wmm_edca_update(struct adapter *padapter)
5197{
5198 struct cmd_obj *pcmd_obj;
5199 u8 *pevtcmd;
5200 u32 cmdsz;
5201 struct wmm_event *pwmm_event;
5202 struct C2HEvent_Header *pc2h_evt_hdr;
5203 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5204 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5205
5206 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
5207 if (pcmd_obj == NULL)
5208 return;
5209
5210 cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header));
5211 pevtcmd = rtw_zmalloc(cmdsz);
5212 if (pevtcmd == NULL) {
5213 kfree((u8 *)pcmd_obj);
5214 return;
5215 }
5216
5217 INIT_LIST_HEAD(&pcmd_obj->list);
5218
5219 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5220 pcmd_obj->cmdsz = cmdsz;
5221 pcmd_obj->parmbuf = pevtcmd;
5222
5223 pcmd_obj->rsp = NULL;
5224 pcmd_obj->rspsz = 0;
5225
5226 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
5227 pc2h_evt_hdr->len = sizeof(struct wmm_event);
5228 pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM);
5229 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5230
5231 pwmm_event = (struct wmm_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
5232 pwmm_event->wmm = 0;
5233
5234 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
5235
5236 return;
5237
5238}
5239
5240void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason)
5241{
5242 struct cmd_obj *pcmd_obj;
5243 u8 *pevtcmd;
5244 u32 cmdsz;
5245 struct sta_info *psta;
5246 int mac_id;
5247 struct stadel_event *pdel_sta_evt;
5248 struct C2HEvent_Header *pc2h_evt_hdr;
5249 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5250 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5251
5252 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
5253 if (pcmd_obj == NULL) {
5254 return;
5255 }
5256
5257 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
5258 pevtcmd = rtw_zmalloc(cmdsz);
5259 if (pevtcmd == NULL) {
5260 kfree((u8 *)pcmd_obj);
5261 return;
5262 }
5263
5264 INIT_LIST_HEAD(&pcmd_obj->list);
5265
5266 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5267 pcmd_obj->cmdsz = cmdsz;
5268 pcmd_obj->parmbuf = pevtcmd;
5269
5270 pcmd_obj->rsp = NULL;
5271 pcmd_obj->rspsz = 0;
5272
5273 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
5274 pc2h_evt_hdr->len = sizeof(struct stadel_event);
5275 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
5276 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5277
5278 pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
5279 memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
5280 memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
5281
5282
5283 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
5284 if (psta)
5285 mac_id = (int)psta->mac_id;
5286 else
5287 mac_id = (-1);
5288
5289 pdel_sta_evt->mac_id = mac_id;
5290
5291 DBG_871X("report_del_sta_event: delete STA, mac_id =%d\n", mac_id);
5292
5293 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
5294
5295 return;
5296}
5297
5298void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int cam_idx)
5299{
5300 struct cmd_obj *pcmd_obj;
5301 u8 *pevtcmd;
5302 u32 cmdsz;
5303 struct stassoc_event *padd_sta_evt;
5304 struct C2HEvent_Header *pc2h_evt_hdr;
5305 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5306 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5307
5308 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
5309 if (pcmd_obj == NULL)
5310 return;
5311
5312 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
5313 pevtcmd = rtw_zmalloc(cmdsz);
5314 if (pevtcmd == NULL) {
5315 kfree((u8 *)pcmd_obj);
5316 return;
5317 }
5318
5319 INIT_LIST_HEAD(&pcmd_obj->list);
5320
5321 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5322 pcmd_obj->cmdsz = cmdsz;
5323 pcmd_obj->parmbuf = pevtcmd;
5324
5325 pcmd_obj->rsp = NULL;
5326 pcmd_obj->rspsz = 0;
5327
5328 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
5329 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
5330 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
5331 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5332
5333 padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
5334 memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
5335 padd_sta_evt->cam_id = cam_idx;
5336
5337 DBG_871X("report_add_sta_event: add STA\n");
5338
5339 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
5340
5341 return;
5342}
5343
5344
5345bool rtw_port_switch_chk(struct adapter *adapter)
5346{
5347 bool switch_needed = false;
5348 return switch_needed;
5349}
5350
5351
5352
5353
5354
5355
5356
5357
5358void update_sta_info(struct adapter *padapter, struct sta_info *psta)
5359{
5360 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5361 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5362 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5363
5364
5365 VCS_update(padapter, psta);
5366
5367
5368 if (pmlmepriv->htpriv.ht_option) {
5369 psta->htpriv.ht_option = true;
5370
5371 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
5372
5373 psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2;
5374
5375 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
5376 psta->htpriv.sgi_20m = true;
5377
5378 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
5379 psta->htpriv.sgi_40m = true;
5380
5381 psta->qos_option = true;
5382
5383 psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
5384 psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
5385 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
5386
5387 memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap));
5388 } else{
5389 psta->htpriv.ht_option = false;
5390
5391 psta->htpriv.ampdu_enable = false;
5392
5393 psta->htpriv.sgi_20m = false;
5394 psta->htpriv.sgi_40m = false;
5395 psta->qos_option = false;
5396
5397 }
5398
5399 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
5400
5401 psta->htpriv.agg_enable_bitmap = 0x0;
5402 psta->htpriv.candidate_tid_bitmap = 0x0;
5403
5404 psta->bw_mode = pmlmeext->cur_bwmode;
5405
5406
5407 if (pmlmepriv->qospriv.qos_option)
5408 psta->qos_option = true;
5409
5410 update_ldpc_stbc_cap(psta);
5411
5412 spin_lock_bh(&psta->lock);
5413 psta->state = _FW_LINKED;
5414 spin_unlock_bh(&psta->lock);
5415
5416}
5417
5418static void rtw_mlmeext_disconnect(struct adapter *padapter)
5419{
5420 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5421 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5422 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5423 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
5424 u8 state_backup = (pmlmeinfo->state&0x03);
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435 {
5436 struct sta_info *psta;
5437 psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(pnetwork));
5438 if (psta)
5439 rtw_hal_macid_wakeup(padapter, psta->mac_id);
5440 }
5441
5442 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
5443 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
5444
5445
5446 Set_MSR(padapter, _HW_STATE_STATION_);
5447
5448 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5449
5450 if (state_backup == WIFI_FW_STATION_STATE) {
5451 if (rtw_port_switch_chk(padapter)) {
5452 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
5453 {
5454 struct adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
5455 if (port0_iface)
5456 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
5457 }
5458 }
5459 }
5460
5461
5462 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
5463 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5464
5465 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5466
5467 flush_all_cam_entry(padapter);
5468
5469 del_timer_sync(&pmlmeext->link_timer);
5470
5471
5472 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
5473 pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
5474
5475}
5476
5477void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res)
5478{
5479 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5480 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5481 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
5482 struct sta_priv *pstapriv = &padapter->stapriv;
5483 u8 join_type;
5484 struct sta_info *psta;
5485 if (join_res < 0) {
5486 join_type = 1;
5487 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
5488 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
5489
5490 goto exit_mlmeext_joinbss_event_callback;
5491 }
5492
5493 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5494
5495 update_bmc_sta(padapter);
5496
5497
5498
5499 Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
5500
5501
5502 update_IOT_info(padapter);
5503
5504 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
5505
5506
5507 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
5508
5509
5510 update_capinfo(padapter, pmlmeinfo->capability);
5511
5512
5513 WMMOnAssocRsp(padapter);
5514
5515
5516 HTOnAssocRsp(padapter);
5517
5518
5519 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5520
5521 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
5522 if (psta) {
5523
5524 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5525
5526
5527
5528 psta->wireless_mode = pmlmeext->cur_wireless_mode;
5529
5530
5531 set_sta_rate(padapter, psta);
5532
5533 rtw_sta_media_status_rpt(padapter, psta, 1);
5534
5535
5536
5537 rtw_hal_macid_wakeup(padapter, psta->mac_id);
5538 }
5539
5540 if (rtw_port_switch_chk(padapter))
5541 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
5542
5543 join_type = 2;
5544 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
5545
5546 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
5547
5548 correct_TSF(padapter, pmlmeext);
5549
5550
5551 }
5552
5553 if (get_iface_type(padapter) == IFACE_PORT0)
5554 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
5555
5556exit_mlmeext_joinbss_event_callback:
5557
5558 DBG_871X("=>%s\n", __func__);
5559
5560}
5561
5562
5563void mlmeext_sta_add_event_callback(struct adapter *padapter, struct sta_info *psta)
5564{
5565 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5566 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5567 u8 join_type;
5568
5569 DBG_871X("%s\n", __func__);
5570
5571 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
5572 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
5573
5574
5575 } else{
5576
5577
5578
5579
5580 correct_TSF(padapter, pmlmeext);
5581
5582
5583 if (send_beacon(padapter) == _FAIL) {
5584 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
5585
5586 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
5587
5588 return;
5589 }
5590
5591 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
5592
5593 }
5594
5595 join_type = 2;
5596 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
5597 }
5598
5599 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5600
5601 psta->bssratelen = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates);
5602 memcpy(psta->bssrateset, pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates, psta->bssratelen);
5603
5604
5605 update_sta_info(padapter, psta);
5606
5607 rtw_hal_update_sta_rate_mask(padapter, psta);
5608
5609
5610 psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
5611 psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
5612
5613
5614 Update_RA_Entry(padapter, psta);
5615}
5616
5617void mlmeext_sta_del_event_callback(struct adapter *padapter)
5618{
5619 if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
5620 rtw_mlmeext_disconnect(padapter);
5621}
5622
5623
5624
5625
5626
5627
5628void _linked_info_dump(struct adapter *padapter)
5629{
5630 int i;
5631 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5632 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5633 int UndecoratedSmoothedPWDB;
5634 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
5635
5636 if (padapter->bLinkInfoDump) {
5637
5638 DBG_871X("\n ============["ADPT_FMT"] linked status check ===================\n", ADPT_ARG(padapter));
5639
5640 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
5641 rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
5642
5643 DBG_871X("AP[" MAC_FMT "] - UndecoratedSmoothedPWDB:%d\n",
5644 MAC_ARG(padapter->mlmepriv.cur_network.network.MacAddress), UndecoratedSmoothedPWDB);
5645 } else if ((pmlmeinfo->state&0x03) == _HW_STATE_AP_) {
5646 struct list_head *phead, *plist;
5647
5648 struct sta_info *psta = NULL;
5649 struct sta_priv *pstapriv = &padapter->stapriv;
5650
5651 spin_lock_bh(&pstapriv->asoc_list_lock);
5652 phead = &pstapriv->asoc_list;
5653 plist = get_next(phead);
5654 while (phead != plist) {
5655 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
5656 plist = get_next(plist);
5657
5658 DBG_871X("STA[" MAC_FMT "]:UndecoratedSmoothedPWDB:%d\n",
5659 MAC_ARG(psta->hwaddr), psta->rssi_stat.UndecoratedSmoothedPWDB);
5660 }
5661 spin_unlock_bh(&pstapriv->asoc_list_lock);
5662
5663 }
5664 for (i = 0; i < NUM_STA; i++) {
5665 if (pdvobj->macid[i]) {
5666 if (i != 1)
5667
5668 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &i);
5669 }
5670 }
5671 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_RX_INFO_DUMP, NULL);
5672
5673
5674 }
5675
5676
5677}
5678
5679static u8 chk_ap_is_alive(struct adapter *padapter, struct sta_info *psta)
5680{
5681 u8 ret = false;
5682
5683 #ifdef DBG_EXPIRATION_CHK
5684 DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
5685
5686 ", retry:%u\n"
5687 , FUNC_ADPT_ARG(padapter)
5688 , STA_RX_PKTS_DIFF_ARG(psta)
5689 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
5690 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
5691
5692
5693
5694
5695 , pmlmeext->retry
5696 );
5697
5698 DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
5699 , padapter->xmitpriv.tx_pkts
5700 , pmlmeinfo->link_count
5701 );
5702 #endif
5703
5704 if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
5705 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
5706 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
5707 ) {
5708 ret = false;
5709 } else{
5710 ret = true;
5711 }
5712
5713 sta_update_last_rx_pkts(psta);
5714
5715 return ret;
5716}
5717
5718void linked_status_chk(struct adapter *padapter)
5719{
5720 u32 i;
5721 struct sta_info *psta;
5722 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5723 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5724 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5725 struct sta_priv *pstapriv = &padapter->stapriv;
5726
5727
5728 if (is_client_associated_to_ap(padapter)) {
5729
5730
5731 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
5732 int rx_chk_limit;
5733 int link_count_limit;
5734
5735 #if defined(DBG_ROAMING_TEST)
5736 rx_chk_limit = 1;
5737 #else
5738 rx_chk_limit = 8;
5739 #endif
5740 link_count_limit = 7;
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
5751 if (psta != NULL) {
5752 if (chk_ap_is_alive(padapter, psta) == false)
5753 rx_chk = _FAIL;
5754
5755 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
5756 tx_chk = _FAIL;
5757
5758 {
5759 if (rx_chk != _SUCCESS) {
5760 if (pmlmeext->retry == 0) {
5761 #ifdef DBG_EXPIRATION_CHK
5762 DBG_871X("issue_probereq to trigger probersp, retry =%d\n", pmlmeext->retry);
5763 #endif
5764 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
5765 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
5766 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
5767 }
5768 }
5769
5770 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) {
5771 #ifdef DBG_EXPIRATION_CHK
5772 DBG_871X("%s issue_nulldata 0\n", __func__);
5773 #endif
5774 tx_chk = issue_nulldata_in_interrupt(padapter, NULL);
5775 }
5776 }
5777
5778 if (rx_chk == _FAIL) {
5779 pmlmeext->retry++;
5780 if (pmlmeext->retry > rx_chk_limit) {
5781 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
5782 FUNC_ADPT_ARG(padapter));
5783 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
5784 , WLAN_REASON_EXPIRATION_CHK);
5785 return;
5786 }
5787 } else {
5788 pmlmeext->retry = 0;
5789 }
5790
5791 if (tx_chk == _FAIL) {
5792 pmlmeinfo->link_count %= (link_count_limit+1);
5793 } else {
5794 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
5795 pmlmeinfo->link_count = 0;
5796 }
5797
5798 }
5799 } else if (is_client_associated_to_ibss(padapter)) {
5800
5801
5802 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
5803 if (pmlmeinfo->FW_sta_info[i].status == 1) {
5804 psta = pmlmeinfo->FW_sta_info[i].psta;
5805
5806 if (NULL == psta)
5807 continue;
5808
5809 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta)) {
5810
5811 if (pmlmeinfo->FW_sta_info[i].retry < 3) {
5812 pmlmeinfo->FW_sta_info[i].retry++;
5813 } else{
5814 pmlmeinfo->FW_sta_info[i].retry = 0;
5815 pmlmeinfo->FW_sta_info[i].status = 0;
5816 report_del_sta_event(padapter, psta->hwaddr
5817 , 65535
5818 );
5819 }
5820 } else{
5821 pmlmeinfo->FW_sta_info[i].retry = 0;
5822 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
5823 }
5824 }
5825 }
5826
5827
5828
5829 }
5830
5831}
5832
5833void survey_timer_hdl(struct timer_list *t)
5834{
5835 struct adapter *padapter =
5836 from_timer(padapter, t, mlmeextpriv.survey_timer);
5837 struct cmd_obj *ph2c;
5838 struct sitesurvey_parm *psurveyPara;
5839 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5840 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5841
5842
5843
5844
5845 if (pmlmeext->sitesurvey_res.state > SCAN_START) {
5846 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
5847 pmlmeext->sitesurvey_res.channel_idx++;
5848 }
5849
5850 if (pmlmeext->scan_abort) {
5851 {
5852 pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
5853 DBG_871X("%s idx:%d\n", __func__
5854 , pmlmeext->sitesurvey_res.channel_idx
5855 );
5856 }
5857
5858 pmlmeext->scan_abort = false;
5859 }
5860
5861 ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
5862 if (ph2c == NULL) {
5863 goto exit_survey_timer_hdl;
5864 }
5865
5866 psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm));
5867 if (psurveyPara == NULL) {
5868 kfree((unsigned char *)ph2c);
5869 goto exit_survey_timer_hdl;
5870 }
5871
5872 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
5873 rtw_enqueue_cmd(pcmdpriv, ph2c);
5874 }
5875
5876
5877exit_survey_timer_hdl:
5878
5879 return;
5880}
5881
5882void link_timer_hdl(struct timer_list *t)
5883{
5884 struct adapter *padapter =
5885 from_timer(padapter, t, mlmeextpriv.link_timer);
5886
5887
5888
5889 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5890 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5891
5892
5893
5894 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
5895 DBG_871X("link_timer_hdl:no beacon while connecting\n");
5896 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5897 report_join_res(padapter, -3);
5898 } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
5899
5900 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
5901
5902
5903 pmlmeinfo->state = 0;
5904 report_join_res(padapter, -1);
5905 return;
5906
5907
5908
5909
5910
5911
5912 }
5913
5914 DBG_871X("link_timer_hdl: auth timeout and try again\n");
5915 pmlmeinfo->auth_seq = 1;
5916 issue_auth(padapter, NULL, 0);
5917 set_link_timer(pmlmeext, REAUTH_TO);
5918 } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
5919
5920 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
5921 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5922 report_join_res(padapter, -2);
5923 return;
5924 }
5925
5926 DBG_871X("link_timer_hdl: assoc timeout and try again\n");
5927 issue_assocreq(padapter);
5928 set_link_timer(pmlmeext, REASSOC_TO);
5929 }
5930
5931 return;
5932}
5933
5934void addba_timer_hdl(struct timer_list *t)
5935{
5936 struct sta_info *psta = from_timer(psta, t, addba_retry_timer);
5937 struct ht_priv *phtpriv;
5938
5939 if (!psta)
5940 return;
5941
5942 phtpriv = &psta->htpriv;
5943
5944 if (phtpriv->ht_option && phtpriv->ampdu_enable) {
5945 if (phtpriv->candidate_tid_bitmap)
5946 phtpriv->candidate_tid_bitmap = 0x0;
5947
5948 }
5949}
5950
5951void sa_query_timer_hdl(struct timer_list *t)
5952{
5953 struct adapter *padapter =
5954 from_timer(padapter, t, mlmeextpriv.sa_query_timer);
5955 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5956
5957 spin_lock_bh(&pmlmepriv->lock);
5958
5959 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
5960 rtw_disassoc_cmd(padapter, 0, true);
5961 rtw_indicate_disconnect(padapter);
5962 rtw_free_assoc_resources(padapter, 1);
5963 }
5964
5965 spin_unlock_bh(&pmlmepriv->lock);
5966 DBG_871X("SA query timeout disconnect\n");
5967}
5968
5969u8 NULL_hdl(struct adapter *padapter, u8 *pbuf)
5970{
5971 return H2C_SUCCESS;
5972}
5973
5974#ifdef CONFIG_AUTO_AP_MODE
5975static int rtw_auto_ap_start_beacon(struct adapter *adapter)
5976{
5977 int ret = 0;
5978 u8 *pbuf = NULL;
5979 uint len;
5980 u8 supportRate[16];
5981 int sz = 0, rateLen;
5982 u8 *ie;
5983 u8 wireless_mode, oper_channel;
5984 u8 ssid[3] = {0};
5985 u32 ssid_len = sizeof(ssid);
5986 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5987
5988
5989 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
5990 return -EINVAL;
5991
5992
5993 len = 128;
5994 pbuf = rtw_zmalloc(len);
5995 if (!pbuf)
5996 return -ENOMEM;
5997
5998
5999
6000 ie = pbuf;
6001
6002
6003 sz += 8;
6004 ie += sz;
6005
6006
6007 *(u16 *)ie = cpu_to_le16((u16)100);
6008 sz += 2;
6009 ie += 2;
6010
6011
6012 *(u16 *)ie = 0;
6013 *(u16 *)ie |= cpu_to_le16(cap_ESS);
6014 *(u16 *)ie |= cpu_to_le16(cap_ShortPremble);
6015
6016 sz += 2;
6017 ie += 2;
6018
6019
6020 ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
6021
6022
6023 wireless_mode = WIRELESS_11BG_24N;
6024 rtw_set_supported_rate(supportRate, wireless_mode);
6025 rateLen = rtw_get_rateset_len(supportRate);
6026 if (rateLen > 8) {
6027 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
6028 } else{
6029 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
6030 }
6031
6032
6033
6034 if (check_buddy_fwstate(adapter, _FW_LINKED) &&
6035 check_buddy_fwstate(adapter, WIFI_STATION_STATE)) {
6036 struct adapter *pbuddystruct adapter = adapter->pbuddystruct adapter;
6037 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddystruct adapter->mlmeextpriv;
6038
6039 oper_channel = pbuddy_mlmeext->cur_channel;
6040 } else{
6041 oper_channel = adapter_to_dvobj(adapter)->oper_channel;
6042 }
6043 ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
6044
6045
6046 if (rateLen > 8) {
6047 ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
6048 }
6049
6050 DBG_871X("%s, start auto ap beacon sz =%d\n", __func__, sz);
6051
6052
6053 if (rtw_check_beacon_data(adapter, pbuf, sz) == _SUCCESS) {
6054
6055 } else{
6056 ret = -EINVAL;
6057 }
6058
6059
6060 kfree(pbuf);
6061
6062 return ret;
6063
6064}
6065#endif
6066
6067u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf)
6068{
6069 u8 type;
6070 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6071 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6072 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
6073
6074 if (psetop->mode == Ndis802_11APMode) {
6075 pmlmeinfo->state = WIFI_FW_AP_STATE;
6076 type = _HW_STATE_AP_;
6077
6078 } else if (psetop->mode == Ndis802_11Infrastructure) {
6079 pmlmeinfo->state &= ~(BIT(0)|BIT(1));
6080 pmlmeinfo->state |= WIFI_FW_STATION_STATE;
6081 type = _HW_STATE_STATION_;
6082 } else if (psetop->mode == Ndis802_11IBSS) {
6083 type = _HW_STATE_ADHOC_;
6084 } else{
6085 type = _HW_STATE_NOLINK_;
6086 }
6087
6088 rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
6089
6090
6091
6092#ifdef CONFIG_AUTO_AP_MODE
6093 if (psetop->mode == Ndis802_11APMode)
6094 rtw_auto_ap_start_beacon(padapter);
6095#endif
6096
6097 if (rtw_port_switch_chk(padapter)) {
6098 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
6099
6100 if (psetop->mode == Ndis802_11APMode)
6101 adapter_to_pwrctl(padapter)->fw_psmode_iface_id = 0xff;
6102 else if (psetop->mode == Ndis802_11Infrastructure) {
6103 struct adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
6104 if (port0_iface)
6105 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
6106 }
6107 }
6108
6109 if (psetop->mode == Ndis802_11APMode) {
6110
6111
6112 rtw_btcoex_MediaStatusNotify(padapter, 1);
6113 }
6114
6115 return H2C_SUCCESS;
6116
6117}
6118
6119u8 createbss_hdl(struct adapter *padapter, u8 *pbuf)
6120{
6121 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6122 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6123 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
6124 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
6125
6126
6127 if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
6128 struct wlan_bssid_ex *network = &padapter->mlmepriv.cur_network.network;
6129 start_bss_network(padapter, (u8 *)network);
6130 return H2C_SUCCESS;
6131 }
6132
6133
6134 if (pparm->network.InfrastructureMode == Ndis802_11IBSS) {
6135 rtw_joinbss_reset(padapter);
6136
6137 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
6138 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6139 pmlmeinfo->ERP_enable = 0;
6140 pmlmeinfo->WMM_enable = 0;
6141 pmlmeinfo->HT_enable = 0;
6142 pmlmeinfo->HT_caps_enable = 0;
6143 pmlmeinfo->HT_info_enable = 0;
6144 pmlmeinfo->agg_enable_bitmap = 0;
6145 pmlmeinfo->candidate_tid_bitmap = 0;
6146
6147
6148 Save_DM_Func_Flag(padapter);
6149 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
6150
6151
6152
6153
6154
6155
6156 del_timer_sync(&pmlmeext->link_timer);
6157
6158
6159 flush_all_cam_entry(padapter);
6160
6161 memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength));
6162 pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength;
6163
6164 if (pnetwork->IELength > MAX_IE_SZ)
6165 return H2C_PARAMETERS_ERROR;
6166
6167 memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength);
6168
6169 start_create_ibss(padapter);
6170
6171 }
6172
6173 return H2C_SUCCESS;
6174
6175}
6176
6177u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
6178{
6179 u8 join_type;
6180 struct ndis_80211_var_ie *pIE;
6181 struct registry_priv *pregpriv = &padapter->registrypriv;
6182 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6183 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6184 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
6185 u32 i;
6186 u8 cbw40_enable = 0;
6187
6188
6189 u8 ch, bw, offset;
6190
6191
6192 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
6193 if (pmlmeinfo->state & WIFI_FW_STATION_STATE) {
6194 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
6195 }
6196 pmlmeinfo->state = WIFI_FW_NULL_STATE;
6197
6198
6199 flush_all_cam_entry(padapter);
6200
6201 del_timer_sync(&pmlmeext->link_timer);
6202
6203
6204
6205 Set_MSR(padapter, _HW_STATE_STATION_);
6206
6207
6208 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
6209 }
6210
6211 rtw_joinbss_reset(padapter);
6212
6213 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
6214 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6215 pmlmeinfo->ERP_enable = 0;
6216 pmlmeinfo->WMM_enable = 0;
6217 pmlmeinfo->HT_enable = 0;
6218 pmlmeinfo->HT_caps_enable = 0;
6219 pmlmeinfo->HT_info_enable = 0;
6220 pmlmeinfo->agg_enable_bitmap = 0;
6221 pmlmeinfo->candidate_tid_bitmap = 0;
6222 pmlmeinfo->bwmode_updated = false;
6223
6224 pmlmeinfo->VHT_enable = 0;
6225
6226 memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength));
6227 pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength;
6228
6229 if (pnetwork->IELength > MAX_IE_SZ)
6230 return H2C_PARAMETERS_ERROR;
6231
6232 memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength);
6233
6234 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
6235 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
6236
6237
6238
6239
6240
6241 for (i = _FIXED_IE_LENGTH_; i < pnetwork->IELength;) {
6242 pIE = (struct ndis_80211_var_ie *)(pnetwork->IEs + i);
6243
6244 switch (pIE->ElementID) {
6245 case _VENDOR_SPECIFIC_IE_:
6246 if (!memcmp(pIE->data, WMM_OUI, 4))
6247 WMM_param_handler(padapter, pIE);
6248 break;
6249
6250 case _HT_CAPABILITY_IE_:
6251 pmlmeinfo->HT_caps_enable = 1;
6252 break;
6253
6254 case _HT_EXTRA_INFO_IE_:
6255 pmlmeinfo->HT_info_enable = 1;
6256
6257
6258 {
6259 struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
6260
6261 if (pnetwork->Configuration.DSConfig > 14) {
6262 if ((pregpriv->bw_mode >> 4) > CHANNEL_WIDTH_20)
6263 cbw40_enable = 1;
6264 } else {
6265 if ((pregpriv->bw_mode & 0x0f) > CHANNEL_WIDTH_20)
6266 cbw40_enable = 1;
6267 }
6268
6269 if ((cbw40_enable) && (pht_info->infos[0] & BIT(2))) {
6270
6271 pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;
6272 switch (pht_info->infos[0] & 0x3) {
6273 case 1:
6274 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
6275 break;
6276
6277 case 3:
6278 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
6279 break;
6280
6281 default:
6282 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6283 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
6284 break;
6285 }
6286
6287 DBG_871X("set HT ch/bw before connected\n");
6288 }
6289 }
6290 break;
6291 default:
6292 break;
6293 }
6294
6295 i += (pIE->Length + 2);
6296 }
6297
6298
6299 if (rtw_chk_start_clnt_join(padapter, &ch, &bw, &offset) == _FAIL) {
6300 report_join_res(padapter, (-4));
6301 return H2C_SUCCESS;
6302 }
6303
6304
6305
6306
6307
6308
6309
6310
6311 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
6312 join_type = 0;
6313 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
6314 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
6315
6316 set_channel_bwmode(padapter, ch, offset, bw);
6317
6318
6319 del_timer_sync(&pmlmeext->link_timer);
6320
6321 start_clnt_join(padapter);
6322
6323 return H2C_SUCCESS;
6324
6325}
6326
6327u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf)
6328{
6329 struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
6330 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6331 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6332 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
6333 u8 val8;
6334
6335 if (is_client_associated_to_ap(padapter)) {
6336 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
6337 }
6338
6339 if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) {
6340
6341 val8 = 0;
6342 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
6343 }
6344
6345 rtw_mlmeext_disconnect(padapter);
6346
6347 rtw_free_uc_swdec_pending_queue(padapter);
6348
6349 return H2C_SUCCESS;
6350}
6351
6352static int rtw_scan_ch_decision(struct adapter *padapter, struct rtw_ieee80211_channel *out,
6353 u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
6354{
6355 int i, j;
6356 int set_idx;
6357 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6358
6359
6360 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
6361
6362
6363 j = 0;
6364 for (i = 0; i < in_num; i++) {
6365
6366 DBG_871X(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
6367
6368 set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value);
6369 if (in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
6370 && set_idx >= 0
6371 && rtw_mlme_band_check(padapter, in[i].hw_value)
6372 ) {
6373 if (j >= out_num) {
6374 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
6375 FUNC_ADPT_ARG(padapter), out_num);
6376 break;
6377 }
6378
6379 memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
6380
6381 if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
6382 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
6383
6384 j++;
6385 }
6386 if (j >= out_num)
6387 break;
6388 }
6389
6390
6391 if (j == 0) {
6392 for (i = 0; i < pmlmeext->max_chan_nums; i++) {
6393
6394 DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum);
6395
6396 if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum)) {
6397
6398 if (j >= out_num) {
6399 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
6400 FUNC_ADPT_ARG(padapter), out_num);
6401 break;
6402 }
6403
6404 out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
6405
6406 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
6407 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
6408
6409 j++;
6410 }
6411 }
6412 }
6413
6414 return j;
6415}
6416
6417u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf)
6418{
6419 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6420 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
6421 u8 bdelayscan = false;
6422 u8 val8;
6423 u32 initialgain;
6424 u32 i;
6425
6426 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
6427 pmlmeext->sitesurvey_res.state = SCAN_START;
6428 pmlmeext->sitesurvey_res.bss_cnt = 0;
6429 pmlmeext->sitesurvey_res.channel_idx = 0;
6430
6431 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
6432 if (pparm->ssid[i].SsidLength) {
6433 memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
6434 pmlmeext->sitesurvey_res.ssid[i].SsidLength = pparm->ssid[i].SsidLength;
6435 } else {
6436 pmlmeext->sitesurvey_res.ssid[i].SsidLength = 0;
6437 }
6438 }
6439
6440 pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter
6441 , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT
6442 , pparm->ch, pparm->ch_num
6443 );
6444
6445 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
6446
6447
6448 if (is_client_associated_to_ap(padapter)) {
6449 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
6450
6451 issue_nulldata(padapter, NULL, 1, 3, 500);
6452
6453 bdelayscan = true;
6454 }
6455 if (bdelayscan) {
6456
6457 set_survey_timer(pmlmeext, 50);
6458 return H2C_SUCCESS;
6459 }
6460 }
6461
6462 if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
6463
6464 Save_DM_Func_Flag(padapter);
6465 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
6466
6467
6468 initialgain = 0x1e;
6469
6470 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
6471
6472
6473 Set_MSR(padapter, _HW_STATE_NOLINK_);
6474
6475 val8 = 1;
6476 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
6477
6478 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
6479 }
6480
6481 site_survey(padapter);
6482
6483 return H2C_SUCCESS;
6484
6485}
6486
6487u8 setauth_hdl(struct adapter *padapter, unsigned char *pbuf)
6488{
6489 struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
6490 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6491 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6492
6493 if (pparm->mode < 4) {
6494 pmlmeinfo->auth_algo = pparm->mode;
6495 }
6496
6497 return H2C_SUCCESS;
6498}
6499
6500u8 setkey_hdl(struct adapter *padapter, u8 *pbuf)
6501{
6502 u16 ctrl = 0;
6503 s16 cam_id = 0;
6504 struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
6505 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6506 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6507 unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
6508 u8 *addr;
6509
6510
6511 if (pparm->set_tx)
6512 pmlmeinfo->key_index = pparm->keyid;
6513
6514 cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid);
6515
6516 if (cam_id < 0) {
6517 } else {
6518 if (cam_id > 3)
6519 addr = get_bssid(&padapter->mlmepriv);
6520 else
6521 addr = null_addr;
6522
6523 ctrl = BIT(15) | BIT6 | ((pparm->algorithm) << 2) | pparm->keyid;
6524 write_cam(padapter, cam_id, ctrl, addr, pparm->key);
6525 DBG_871X_LEVEL(_drv_always_, "set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
6526 , cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm));
6527 }
6528
6529 if (cam_id >= 0 && cam_id <= 3)
6530 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)true);
6531
6532
6533 padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_ON_RCR_AM, null_addr);
6534
6535 return H2C_SUCCESS;
6536}
6537
6538u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf)
6539{
6540 u16 ctrl = 0;
6541 s16 cam_id = 0;
6542 u8 ret = H2C_SUCCESS;
6543 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6544 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6545 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
6546 struct sta_priv *pstapriv = &padapter->stapriv;
6547 struct sta_info *psta;
6548
6549 if (pparm->algorithm == _NO_PRIVACY_)
6550 goto write_to_cam;
6551
6552 psta = rtw_get_stainfo(pstapriv, pparm->addr);
6553 if (!psta) {
6554 DBG_871X_LEVEL(_drv_always_, "%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr));
6555 ret = H2C_REJECTED;
6556 goto exit;
6557 }
6558
6559 pmlmeinfo->enc_algo = pparm->algorithm;
6560 cam_id = rtw_camid_alloc(padapter, psta, 0);
6561 if (cam_id < 0)
6562 goto exit;
6563
6564write_to_cam:
6565 if (pparm->algorithm == _NO_PRIVACY_) {
6566 while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1)) >= 0) {
6567 DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id);
6568 clear_cam_entry(padapter, cam_id);
6569 rtw_camid_free(padapter, cam_id);
6570 }
6571 } else {
6572 DBG_871X_LEVEL(_drv_always_, "set pairwise key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n",
6573 cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm));
6574 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
6575 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
6576 }
6577 ret = H2C_SUCCESS_RSP;
6578
6579exit:
6580 return ret;
6581}
6582
6583u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf)
6584{
6585 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
6586 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6587 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6588
6589 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
6590
6591 if (!psta)
6592 return H2C_SUCCESS;
6593
6594 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
6595 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) {
6596
6597
6598
6599 issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
6600
6601 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
6602 } else{
6603 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
6604 }
6605 return H2C_SUCCESS;
6606}
6607
6608
6609u8 chk_bmc_sleepq_cmd(struct adapter *padapter)
6610{
6611 struct cmd_obj *ph2c;
6612 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
6613 u8 res = _SUCCESS;
6614
6615 ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
6616 if (ph2c == NULL) {
6617 res = _FAIL;
6618 goto exit;
6619 }
6620
6621 init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq));
6622
6623 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
6624
6625exit:
6626 return res;
6627}
6628
6629u8 set_tx_beacon_cmd(struct adapter *padapter)
6630{
6631 struct cmd_obj *ph2c;
6632 struct Tx_Beacon_param *ptxBeacon_parm;
6633 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
6634 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6635 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6636 u8 res = _SUCCESS;
6637 int len_diff = 0;
6638
6639 ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
6640 if (ph2c == NULL) {
6641 res = _FAIL;
6642 goto exit;
6643 }
6644
6645 ptxBeacon_parm = rtw_zmalloc(sizeof(struct Tx_Beacon_param));
6646 if (ptxBeacon_parm == NULL) {
6647 kfree((unsigned char *)ph2c);
6648 res = _FAIL;
6649 goto exit;
6650 }
6651
6652 memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex));
6653
6654 len_diff = update_hidden_ssid(
6655 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_
6656 , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_
6657 , pmlmeinfo->hidden_ssid_mode
6658 );
6659 ptxBeacon_parm->network.IELength += len_diff;
6660
6661 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
6662
6663 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
6664
6665exit:
6666 return res;
6667}
6668
6669
6670u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf)
6671{
6672 u8 evt_code, evt_seq;
6673 u16 evt_sz;
6674 uint *peventbuf;
6675 void (*event_callback)(struct adapter *dev, u8 *pbuf);
6676 struct evt_priv *pevt_priv = &(padapter->evtpriv);
6677
6678 if (pbuf == NULL)
6679 goto _abort_event_;
6680
6681 peventbuf = (uint *)pbuf;
6682 evt_sz = (u16)(*peventbuf&0xffff);
6683 evt_seq = (u8)((*peventbuf>>24)&0x7f);
6684 evt_code = (u8)((*peventbuf>>16)&0xff);
6685
6686
6687 #ifdef CHECK_EVENT_SEQ
6688
6689 if (evt_seq != (atomic_read(&pevt_priv->event_seq) & 0x7f)) {
6690 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
6691 ("Event Seq Error! %d vs %d\n", (evt_seq & 0x7f),
6692 (atomic_read(&pevt_priv->event_seq) & 0x7f)));
6693
6694 pevt_priv->event_seq = (evt_seq+1)&0x7f;
6695
6696 goto _abort_event_;
6697 }
6698 #endif
6699
6700
6701 if (evt_code >= MAX_C2HEVT) {
6702 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent Code(%d) mismatch!\n", evt_code));
6703 goto _abort_event_;
6704 }
6705
6706
6707 if ((wlanevents[evt_code].parmsize != 0) &&
6708 (wlanevents[evt_code].parmsize != evt_sz)) {
6709
6710 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
6711 evt_code, wlanevents[evt_code].parmsize, evt_sz));
6712 goto _abort_event_;
6713
6714 }
6715
6716 atomic_inc(&pevt_priv->event_seq);
6717
6718 peventbuf += 2;
6719
6720 if (peventbuf) {
6721 event_callback = wlanevents[evt_code].event_callback;
6722 event_callback(padapter, (u8 *)peventbuf);
6723
6724 pevt_priv->evt_done_cnt++;
6725 }
6726
6727
6728_abort_event_:
6729
6730
6731 return H2C_SUCCESS;
6732
6733}
6734
6735u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf)
6736{
6737 if (!pbuf)
6738 return H2C_PARAMETERS_ERROR;
6739
6740 return H2C_SUCCESS;
6741}
6742
6743u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf)
6744{
6745 struct sta_info *psta_bmc;
6746 struct list_head *xmitframe_plist, *xmitframe_phead;
6747 struct xmit_frame *pxmitframe = NULL;
6748 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6749 struct sta_priv *pstapriv = &padapter->stapriv;
6750
6751
6752 psta_bmc = rtw_get_bcmc_stainfo(padapter);
6753 if (!psta_bmc)
6754 return H2C_SUCCESS;
6755
6756 if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len > 0)) {
6757 msleep(10);
6758
6759
6760 spin_lock_bh(&pxmitpriv->lock);
6761
6762 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
6763 xmitframe_plist = get_next(xmitframe_phead);
6764
6765 while (xmitframe_phead != xmitframe_plist) {
6766 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
6767
6768 xmitframe_plist = get_next(xmitframe_plist);
6769
6770 list_del_init(&pxmitframe->list);
6771
6772 psta_bmc->sleepq_len--;
6773 if (psta_bmc->sleepq_len > 0)
6774 pxmitframe->attrib.mdata = 1;
6775 else
6776 pxmitframe->attrib.mdata = 0;
6777
6778 pxmitframe->attrib.triggered = 1;
6779
6780 if (xmitframe_hiq_filter(pxmitframe))
6781 pxmitframe->attrib.qsel = 0x11;
6782
6783 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
6784 }
6785
6786
6787 spin_unlock_bh(&pxmitpriv->lock);
6788
6789
6790 rtw_chk_hi_queue_cmd(padapter);
6791 }
6792
6793 return H2C_SUCCESS;
6794}
6795
6796u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf)
6797{
6798 if (send_beacon(padapter) == _FAIL) {
6799 DBG_871X("issue_beacon, fail!\n");
6800 return H2C_PARAMETERS_ERROR;
6801 }
6802
6803
6804 chk_bmc_sleepq_hdl(padapter, NULL);
6805
6806 return H2C_SUCCESS;
6807}
6808
6809int rtw_chk_start_clnt_join(struct adapter *padapter, u8 *ch, u8 *bw, u8 *offset)
6810{
6811 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6812 unsigned char cur_ch = pmlmeext->cur_channel;
6813 unsigned char cur_bw = pmlmeext->cur_bwmode;
6814 unsigned char cur_ch_offset = pmlmeext->cur_ch_offset;
6815 bool connect_allow = true;
6816
6817 if (!ch || !bw || !offset) {
6818 rtw_warn_on(1);
6819 connect_allow = false;
6820 }
6821
6822 if (connect_allow) {
6823 DBG_871X("start_join_set_ch_bw: ch =%d, bwmode =%d, ch_offset =%d\n", cur_ch, cur_bw, cur_ch_offset);
6824 *ch = cur_ch;
6825 *bw = cur_bw;
6826 *offset = cur_ch_offset;
6827 }
6828
6829 return connect_allow == true ? _SUCCESS : _FAIL;
6830}
6831
6832
6833int rtw_get_ch_setting_union(struct adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
6834{
6835 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
6836 struct adapter *iface;
6837 struct mlme_ext_priv *mlmeext;
6838 u8 ch_ret = 0;
6839 u8 bw_ret = CHANNEL_WIDTH_20;
6840 u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6841
6842 if (ch)
6843 *ch = 0;
6844 if (bw)
6845 *bw = CHANNEL_WIDTH_20;
6846 if (offset)
6847 *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6848
6849 iface = dvobj->padapters;
6850 mlmeext = &iface->mlmeextpriv;
6851
6852 if (!check_fwstate(&iface->mlmepriv, _FW_LINKED|_FW_UNDER_LINKING))
6853 return 0;
6854
6855 ch_ret = mlmeext->cur_channel;
6856 bw_ret = mlmeext->cur_bwmode;
6857 offset_ret = mlmeext->cur_ch_offset;
6858
6859 return 1;
6860}
6861
6862u8 set_ch_hdl(struct adapter *padapter, u8 *pbuf)
6863{
6864 struct set_ch_parm *set_ch_parm;
6865 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6866
6867 if (!pbuf)
6868 return H2C_PARAMETERS_ERROR;
6869
6870 set_ch_parm = (struct set_ch_parm *)pbuf;
6871
6872 DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
6873 FUNC_NDEV_ARG(padapter->pnetdev),
6874 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
6875
6876 pmlmeext->cur_channel = set_ch_parm->ch;
6877 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
6878 pmlmeext->cur_bwmode = set_ch_parm->bw;
6879
6880 set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
6881
6882 return H2C_SUCCESS;
6883}
6884
6885u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf)
6886{
6887 struct SetChannelPlan_param *setChannelPlan_param;
6888 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6889
6890 if (!pbuf)
6891 return H2C_PARAMETERS_ERROR;
6892
6893 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
6894
6895 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
6896 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
6897
6898 if ((padapter->rtw_wdev != NULL) && (padapter->rtw_wdev->wiphy)) {
6899 struct regulatory_request request;
6900 request.initiator = NL80211_REGDOM_SET_BY_DRIVER;
6901 rtw_reg_notifier(padapter->rtw_wdev->wiphy, &request);
6902 }
6903
6904 return H2C_SUCCESS;
6905}
6906
6907u8 led_blink_hdl(struct adapter *padapter, unsigned char *pbuf)
6908{
6909 struct LedBlink_param *ledBlink_param;
6910
6911 if (!pbuf)
6912 return H2C_PARAMETERS_ERROR;
6913
6914 ledBlink_param = (struct LedBlink_param *)pbuf;
6915 return H2C_SUCCESS;
6916}
6917
6918u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf)
6919{
6920 return H2C_REJECTED;
6921}
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf)
6934{
6935 return H2C_REJECTED;
6936}
6937
6938u8 run_in_thread_hdl(struct adapter *padapter, u8 *pbuf)
6939{
6940 struct RunInThread_param *p;
6941
6942
6943 if (NULL == pbuf)
6944 return H2C_PARAMETERS_ERROR;
6945 p = (struct RunInThread_param *)pbuf;
6946
6947 if (p->func)
6948 p->func(p->context);
6949
6950 return H2C_SUCCESS;
6951}
6952