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