1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2019 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 *****************************************************************************/
15 #define _RTW_MLME_EXT_C_
16
17 #include <drv_types.h>
18 #include <hal_data.h>
19
20 struct mlme_handler mlme_sta_tbl[] = {
21 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
22 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
23 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
24 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
25 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
26 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
27
28 /*----------------------------------------------------------
29 below 2 are reserved
30 -----------------------------------------------------------*/
31 {0, "DoReserved", &DoReserved},
32 {0, "DoReserved", &DoReserved},
33 {WIFI_BEACON, "OnBeacon", &OnBeacon},
34 {WIFI_ATIM, "OnATIM", &OnAtim},
35 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
36 {WIFI_AUTH, "OnAuth", &OnAuthClient},
37 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
38 {WIFI_ACTION, "OnAction", &OnAction},
39 {WIFI_ACTION_NOACK, "OnActionNoAck", &OnAction},
40 };
41
42 #ifdef _CONFIG_NATIVEAP_MLME_
43 struct mlme_handler mlme_ap_tbl[] = {
44 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
45 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
46 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
47 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
48 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
49 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
50
51 /*----------------------------------------------------------
52 below 2 are reserved
53 -----------------------------------------------------------*/
54 {0, "DoReserved", &DoReserved},
55 {0, "DoReserved", &DoReserved},
56 {WIFI_BEACON, "OnBeacon", &OnBeacon},
57 {WIFI_ATIM, "OnATIM", &OnAtim},
58 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
59 {WIFI_AUTH, "OnAuth", &OnAuth},
60 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
61 {WIFI_ACTION, "OnAction", &OnAction},
62 {WIFI_ACTION_NOACK, "OnActionNoAck", &OnAction},
63 };
64 #endif
65
66 struct action_handler OnAction_tbl[] = {
67 {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct},
68 {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos},
69 {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls},
70 {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
71 {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
72 {RTW_WLAN_CATEGORY_RADIO_MEAS, "ACTION_RADIO_MEAS", &on_action_rm},
73 {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &OnAction_ft},
74 {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht},
75 #ifdef CONFIG_IEEE80211W
76 {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query},
77 #else
78 {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
79 #endif /* CONFIG_IEEE80211W */
80 #ifdef CONFIG_RTW_WNM
81 {RTW_WLAN_CATEGORY_WNM, "ACTION_WNM", &on_action_wnm},
82 #endif
83 {RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved},
84 #ifdef CONFIG_RTW_MESH
85 {RTW_WLAN_CATEGORY_MESH, "ACTION_MESH", &on_action_mesh},
86 {RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &on_action_self_protected},
87 #endif
88 {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
89 {RTW_WLAN_CATEGORY_VHT, "ACTION_VHT", &OnAction_vht},
90 {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
91 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
92 {RTW_WLAN_CATEGORY_TBTX, "ACTION_TBTX_TOKEN", &OnAction_tbtx_token}
93 #endif
94 };
95
96
97 u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
98
99 /**************************************************
100 OUI definitions for the vendor specific IE
101 ***************************************************/
102 unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
103 unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
104 unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
105 unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09};
106 unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A};
107 unsigned char DPP_OUI[] = {0x50, 0x6F, 0x9A, 0x1A};
108 unsigned char MULTI_AP_OUI[] = {0x50, 0x6F, 0x9A, 0x1B};
109
110 unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
111 unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
112
113 unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
114 unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
115
116 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
117 unsigned char REALTEK_TBTX_IE[] = {0x00, 0xe0, 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00};
118 #endif
119 extern unsigned char REALTEK_96B_IE[];
120
init_channel_list(_adapter * padapter,RT_CHANNEL_INFO * channel_set,struct p2p_channels * channel_list)121 static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set
122 , struct p2p_channels *channel_list)
123 {
124 struct registry_priv *regsty = adapter_to_regsty(padapter);
125
126 struct p2p_oper_class_map op_class[] = {
127 { IEEE80211G, 81, 1, 13, 1, BW20 },
128 { IEEE80211G, 82, 14, 14, 1, BW20 },
129 #if 0 /* Do not enable HT40 on 2 GHz */
130 { IEEE80211G, 83, 1, 9, 1, BW40PLUS },
131 { IEEE80211G, 84, 5, 13, 1, BW40MINUS },
132 #endif
133 { IEEE80211A, 115, 36, 48, 4, BW20 },
134 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
135 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
136 { IEEE80211A, 124, 149, 161, 4, BW20 },
137 { IEEE80211A, 125, 149, 169, 4, BW20 },
138 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
139 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
140 { -1, 0, 0, 0, 0, BW20 }
141 };
142
143 int cla, op;
144
145 cla = 0;
146
147 for (op = 0; op_class[op].op_class; op++) {
148 u8 ch;
149 struct p2p_oper_class_map *o = &op_class[op];
150 struct p2p_reg_class *reg = NULL;
151
152 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
153 if (rtw_chset_search_ch(channel_set, ch) == -1)
154 continue;
155 #if defined(CONFIG_80211N_HT) || defined(CONFIG_80211AC_VHT)
156 if ((padapter->registrypriv.ht_enable == 0) && (o->inc == 8))
157 continue;
158
159 if ((REGSTY_IS_BW_5G_SUPPORT(regsty, CHANNEL_WIDTH_40)) &&
160 ((o->bw == BW40MINUS) || (o->bw == BW40PLUS)))
161 continue;
162 #endif
163 if (reg == NULL) {
164 reg = &channel_list->reg_class[cla];
165 cla++;
166 reg->reg_class = o->op_class;
167 reg->channels = 0;
168 }
169 reg->channel[reg->channels] = ch;
170 reg->channels++;
171 }
172 }
173 channel_list->reg_classes = cla;
174
175 }
176
177 #if CONFIG_TXPWR_LIMIT
rtw_txpwr_init_regd_default(struct rf_ctl_t * rfctl)178 static void rtw_txpwr_init_regd_default(struct rf_ctl_t *rfctl)
179 {
180 bool country_txpwr_lmt_override = 0;
181 u8 txpwr_lmt[BAND_MAX];
182 const char *name[BAND_MAX];
183 u8 unknown_bmp = 0; /* unknown bitmap */
184 char buf[TXPWR_NAMES_STR_LEN];
185 u8 band;
186 bool altenate_applied = 0;
187
188 for (band = 0; band < BAND_MAX; band++) {
189 txpwr_lmt[band] = TXPWR_LMT_NONE;
190 name[band] = NULL;
191 unknown_bmp |= BIT(band);
192 }
193
194 if (rfctl->txpwr_lmt_override != TXPWR_LMT_DEF) {
195 country_txpwr_lmt_override = 1;
196 for (band = 0; band < BAND_MAX; band++)
197 txpwr_lmt[band] = rfctl->txpwr_lmt_override;
198 } else {
199 txpwr_lmt[BAND_ON_2_4G] = rtw_regd_to_txpwr_lmt(rtw_chplan_get_default_regd_2g(rfctl->ChannelPlan));
200 #if CONFIG_IEEE80211_BAND_5GHZ
201 txpwr_lmt[BAND_ON_5G] = rtw_regd_to_txpwr_lmt(rtw_chplan_get_default_regd_5g(rfctl->ChannelPlan));
202 #endif
203 #if CONFIG_IEEE80211_BAND_6GHZ
204 txpwr_lmt[BAND_ON_6G] = rtw_regd_to_txpwr_lmt(rtw_chplan_get_default_regd_6g(rfctl->chplan_6g));
205 #endif
206 }
207
208 for (band = 0; band < BAND_MAX; band++) {
209 name[band] = txpwr_lmt_str(txpwr_lmt[band]);
210 if (txpwr_lmt[band] == TXPWR_LMT_NONE || txpwr_lmt[band] == TXPWR_LMT_WW || txpwr_lmt[band] == TXPWR_LMT_NUM
211 || _rtw_txpwr_lmt_get_by_name(rfctl, name[band]))
212 unknown_bmp &= ~BIT(band);
213 }
214
215 if (country_txpwr_lmt_override) {
216 RTW_PRINT("default mapping country:%c%c to txpwr_lmt:%s\n"
217 , rfctl->alpha2[0], rfctl->alpha2[1]
218 , rtw_get_txpwr_lmt_names_str(buf, name, unknown_bmp)
219 );
220 } else {
221 RTW_PRINT("default mapping domain to txpwr_lmt:%s\n"
222 , rtw_get_txpwr_lmt_names_str(buf, name, unknown_bmp));
223 }
224 if (unknown_bmp == 0)
225 goto exit;
226
227 for (band = 0; band < BAND_MAX; band++) {
228 if (!(unknown_bmp & BIT(band)))
229 continue;
230 if (TXPWR_LMT_ALTERNATE_DEFINED(txpwr_lmt[band])) {
231 /*
232 * To support older chips without new predefined txpwr_lmt:
233 * - use txpwr_lmt_alternate() to get alternate if the selection is not found
234 */
235 altenate_applied = 1;
236 txpwr_lmt[band] = txpwr_lmt_alternate(txpwr_lmt[band]);
237 name[band] = txpwr_lmt_str(txpwr_lmt[band]);
238 if (_rtw_txpwr_lmt_get_by_name(rfctl, name[band]))
239 unknown_bmp &= ~BIT(band);
240 }
241 }
242 if (altenate_applied) {
243 RTW_PRINT("alternate applied txpwr_lmt:%s\n"
244 , rtw_get_txpwr_lmt_names_str(buf, name, unknown_bmp));
245 if (unknown_bmp == 0)
246 goto exit;
247 }
248
249 for (band = 0; band < BAND_MAX; band++) {
250 if (!(unknown_bmp & BIT(band)))
251 continue;
252 txpwr_lmt[band] = TXPWR_LMT_WW;
253 name[band] = txpwr_lmt_str(txpwr_lmt[band]);
254 unknown_bmp &= ~BIT(band);
255 }
256 RTW_PRINT("world wide applied txpwr_lmt:%s\n"
257 , rtw_get_txpwr_lmt_names_str(buf, name, unknown_bmp));
258
259 exit:
260 for (band = 0; band < BAND_MAX; band++)
261 rfctl->txpwr_lmt_name[band] = name[band];
262 }
263
rtw_txpwr_init_regd(struct rf_ctl_t * rfctl)264 void rtw_txpwr_init_regd(struct rf_ctl_t *rfctl)
265 {
266 const char *name = NULL;
267 u8 band;
268 struct regd_exc_ent *exc;
269 struct txpwr_lmt_ent *ent;
270 _irqL irqL;
271
272 _enter_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL);
273
274 for (band = 0; band < BAND_MAX; band++)
275 rfctl->txpwr_lmt_name[band] = NULL;
276
277 if (rfctl->txpwr_lmt_num == 0) {
278 RTW_PRINT("there is no any txpwr_regd\n");
279 goto release_lock;
280 }
281
282 /* search from exception mapping */
283 exc = _rtw_regd_exc_search(rfctl, rfctl->alpha2, rfctl->ChannelPlan);
284 if (exc) {
285 u8 has_country = (exc->country[0] == '\0' && exc->country[1] == '\0') ? 0 : 1;
286
287 if (strcmp(exc->lmt_name, txpwr_lmt_str(TXPWR_LMT_NONE)) == 0)
288 name = txpwr_lmt_str(TXPWR_LMT_NONE);
289 else if (strcmp(exc->lmt_name, txpwr_lmt_str(TXPWR_LMT_WW)) == 0)
290 name = txpwr_lmt_str(TXPWR_LMT_WW);
291 else {
292 ent = _rtw_txpwr_lmt_get_by_name(rfctl, exc->lmt_name);
293 if (ent)
294 name = ent->name;
295 }
296
297 RTW_PRINT("exception mapping country:%c%c domain:0x%02x to%s txpwr_lmt:%s\n"
298 , has_country ? exc->country[0] : '-'
299 , has_country ? exc->country[1] : '-'
300 , exc->domain
301 , name ? "" : " unknown"
302 , exc->lmt_name
303 );
304 if (name) {
305 for (band = 0; band < BAND_MAX; band++)
306 rfctl->txpwr_lmt_name[band] = name;
307 goto release_lock;
308 }
309 }
310
311 #ifdef CONFIG_REGD_SRC_FROM_OS
312 if (rfctl->regd_src == REGD_SRC_OS) {
313 if (RFCTL_REG_WORLDWIDE(rfctl))
314 name = txpwr_lmt_str(TXPWR_LMT_WW);
315 else {
316 char alpha2[3] = {
317 rfctl->alpha2[0], rfctl->alpha2[1], 0};
318
319 ent = _rtw_txpwr_lmt_get_by_name(rfctl, alpha2);
320 if (ent)
321 name = ent->name;
322 }
323
324 if (name) {
325 for (band = 0; band < BAND_MAX; band++)
326 rfctl->txpwr_lmt_name[band] = name;
327 RTW_PRINT("mapping country:%c%c to txpwr_lmt:%s\n"
328 , rfctl->alpha2[0]
329 , rfctl->alpha2[1]
330 , name
331 );
332 goto release_lock;
333 }
334
335 if (rfctl->ChannelPlan == RTW_CHPLAN_UNSPECIFIED) {
336 name = txpwr_lmt_str(TXPWR_LMT_WW);
337 for (band = 0; band < BAND_MAX; band++)
338 rfctl->txpwr_lmt_name[band] = name;
339 RTW_PRINT("mapping unsupported country:%c%c to txpwr_lmt:%s\n"
340 , rfctl->alpha2[0]
341 , rfctl->alpha2[1]
342 , name
343 );
344 goto release_lock;
345 }
346 }
347 #endif
348
349 /* follow default channel plan mapping */
350 rtw_txpwr_init_regd_default(rfctl);
351
352 release_lock:
353 _exit_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL);
354 }
355
rtw_rfctl_is_current_txpwr_lmt(struct rf_ctl_t * rfctl,const char * name)356 bool rtw_rfctl_is_current_txpwr_lmt(struct rf_ctl_t *rfctl, const char *name)
357 {
358 int band;
359
360 for (band = 0; band < BAND_MAX; band++)
361 if (rfctl->txpwr_lmt_name[band] && strcmp(name, rfctl->txpwr_lmt_name[band]) == 0)
362 return 1;
363
364 return 0;
365 }
366 #endif /* CONFIG_TXPWR_LIMIT */
367
rtw_rfctl_init(_adapter * adapter)368 int rtw_rfctl_init(_adapter *adapter)
369 {
370 struct registry_priv *regsty = adapter_to_regsty(adapter);
371 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
372 int ret;
373
374 _rtw_mutex_init(&rfctl->offch_mutex);
375
376 rfctl->user_ChannelPlan = RTW_CHPLAN_UNSPECIFIED;
377 #if CONFIG_IEEE80211_BAND_6GHZ
378 rfctl->user_chplan_6g = RTW_CHPLAN_6G_UNSPECIFIED;
379 #endif
380
381 #ifdef CONFIG_80211D
382 rfctl->country_ie_slave_en_role = regsty->country_ie_slave_en_role;
383 rfctl->country_ie_slave_en_ifbmp = regsty->country_ie_slave_en_ifbmp;
384 rfctl->effected_cisr_id = CONFIG_IFACE_NUMBER;
385 #endif
386
387 #if CONFIG_TXPWR_LIMIT
388 _rtw_mutex_init(&rfctl->txpwr_lmt_mutex);
389 _rtw_init_listhead(&rfctl->reg_exc_list);
390 _rtw_init_listhead(&rfctl->txpwr_lmt_list);
391 #endif
392
393 rfctl->ch_sel_within_same_band = 1;
394
395 #ifdef CONFIG_DFS_MASTER
396 rfctl->dfs_region_domain = regsty->dfs_region_domain;
397 rfctl->cac_start_time = rfctl->cac_end_time = RTW_CAC_STOPPED;
398 rtw_init_timer(&(rfctl->radar_detect_timer), adapter, rtw_dfs_rd_timer_hdl, rfctl);
399 #endif
400 #if CONFIG_DFS_SLAVE_WITH_RADAR_DETECT
401 rfctl->dfs_slave_with_rd = 1;
402 #endif
403
404 if (regsty->antenna_gain != UNSPECIFIED_MBM)
405 rfctl->antenna_gain = regsty->antenna_gain;
406
407 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
408 rfctl->ap_csa_cnt_input = DEFAULT_CSA_CNT;
409 #endif
410
411 ret = op_class_pref_init(adapter);
412 if (ret != _SUCCESS)
413 op_class_pref_deinit(adapter);
414
415 return ret;
416 }
417
rtw_rfctl_deinit(_adapter * adapter)418 void rtw_rfctl_deinit(_adapter *adapter)
419 {
420 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
421
422 _rtw_mutex_free(&rfctl->offch_mutex);
423
424 #if CONFIG_TXPWR_LIMIT
425 rtw_regd_exc_list_free(rfctl);
426 rtw_txpwr_lmt_list_free(rfctl);
427 _rtw_mutex_free(&rfctl->txpwr_lmt_mutex);
428 #endif
429
430 op_class_pref_deinit(adapter);
431 }
432
433 /*
434 * Description:
435 * Use hardware(efuse), driver parameter(registry) and default channel plan
436 * to decide which one should be used.
437 *
438 * Parameters:
439 * rfctl pointer of rfctl
440 * hw_alpha2 country code from HW (efuse/eeprom/mapfile)
441 * hw_chplan domain code from HW (efuse/eeprom/mapfile)
442 * hw_chplan_6g 6g domain code from HW (efuse/eeprom/mapfile)
443 * hw_force_chplan if forcing HW channel plan setting (efuse/eeprom/mapfile)
444 * will modified tif HW channel plan setting is invlid, will
445 */
rtw_rfctl_decide_init_chplan(struct rf_ctl_t * rfctl,const char * hw_alpha2,u8 hw_chplan,u8 hw_chplan_6g,u8 hw_force_chplan)446 void rtw_rfctl_decide_init_chplan(struct rf_ctl_t *rfctl,
447 const char *hw_alpha2, u8 hw_chplan, u8 hw_chplan_6g, u8 hw_force_chplan)
448 {
449 struct registry_priv *regsty;
450 char *sw_alpha2;
451 const struct country_chplan *country_ent = NULL;
452 struct country_chplan ent;
453 int chplan = -1;
454 int chplan_6g = -1;
455
456 u8 sw_chplan;
457 u8 def_chplan = RTW_CHPLAN_WORLDWIDE; /* worldwide, used when HW, SW both invalid */
458 #if CONFIG_IEEE80211_BAND_6GHZ
459 u8 sw_chplan_6g;
460 u8 def_chplan_6g = RTW_CHPLAN_6G_WORLDWIDE; /* worldwide, used when HW, SW both invalid */
461 #endif
462
463 if (hw_alpha2) {
464 if (rtw_get_chplan_from_country(hw_alpha2, &ent)) {
465 /* get chplan from hw country code, by pass hw chplan setting */
466 country_ent = &ent;
467 chplan = ent.chplan;
468 #if CONFIG_IEEE80211_BAND_6GHZ
469 chplan_6g = ent.chplan_6g;
470 #endif
471 goto chk_sw_config;
472 } else
473 RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
474 }
475
476 if (rtw_is_channel_plan_valid(hw_chplan))
477 chplan = hw_chplan;
478 else if (hw_force_chplan == _TRUE) {
479 RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
480 /* hw infomaton invalid, refer to sw information */
481 hw_force_chplan = _FALSE;
482 }
483
484 #if CONFIG_IEEE80211_BAND_6GHZ
485 if (rtw_is_channel_plan_6g_valid(hw_chplan_6g))
486 chplan_6g = hw_chplan_6g;
487 else if (hw_force_chplan == _TRUE) {
488 RTW_PRINT("%s unsupported hw_chplan_6g:0x%02X\n", __func__, hw_chplan_6g);
489 /* hw infomaton invalid, refer to sw information */
490 hw_force_chplan = _FALSE;
491 }
492 #endif
493
494 chk_sw_config:
495 if (hw_force_chplan == _TRUE)
496 goto done;
497
498 regsty = dvobj_to_regsty(rfctl_to_dvobj(rfctl));
499 sw_alpha2 = regsty->alpha2;
500 sw_chplan = regsty->channel_plan;
501 #if CONFIG_IEEE80211_BAND_6GHZ
502 sw_chplan_6g = regsty->channel_plan_6g;
503 #endif
504
505 if (sw_alpha2 && !IS_ALPHA2_UNSPEC(sw_alpha2)) {
506 if (IS_ALPHA2_WORLDWIDE(sw_alpha2)
507 || rtw_get_chplan_from_country(sw_alpha2, &ent)
508 ) {
509 /* get chplan from sw country code, by pass sw chplan setting */
510 if (IS_ALPHA2_WORLDWIDE(sw_alpha2))
511 rtw_get_chplan_worldwide(&ent);
512 country_ent = &ent;
513 chplan = ent.chplan;
514 #if CONFIG_IEEE80211_BAND_6GHZ
515 chplan_6g = ent.chplan_6g;
516 #endif
517 goto done;
518 } else
519 RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
520 }
521
522 if (rtw_is_channel_plan_valid(sw_chplan)) {
523 /* cancel hw_alpha2 because chplan is specified by sw_chplan */
524 country_ent = NULL;
525 chplan = sw_chplan;
526 } else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
527 RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
528
529 #if CONFIG_IEEE80211_BAND_6GHZ
530 if (rtw_is_channel_plan_6g_valid(sw_chplan_6g)) {
531 /* cancel hw_alpha2 because chplan_6g is specified by sw_chplan_6g */
532 country_ent = NULL;
533 chplan_6g = sw_chplan_6g;
534 } else if (sw_chplan_6g != RTW_CHPLAN_6G_UNSPECIFIED)
535 RTW_PRINT("%s unsupported sw_chplan_6g:0x%02X\n", __func__, sw_chplan_6g);
536 #endif
537
538 done:
539 if (chplan == -1) {
540 RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
541 chplan = def_chplan;
542 } else
543 RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
544
545 #if CONFIG_IEEE80211_BAND_6GHZ
546 if (chplan_6g == -1) {
547 RTW_PRINT("%s use def_chplan_6g:0x%02X\n", __func__, def_chplan_6g);
548 chplan_6g = def_chplan_6g;
549 } else
550 RTW_PRINT("%s chplan_6g:0x%02X\n", __func__, chplan_6g);
551 #endif
552
553 if (!country_ent) {
554 if (rtw_chplan_ids_is_world_wide(chplan, chplan_6g))
555 rtw_get_chplan_worldwide(&ent);
556 else {
557 SET_UNSPEC_ALPHA2(ent.alpha2);
558 ent.edcca_mode_2g_override = RTW_EDCCA_DEF;
559 #if CONFIG_IEEE80211_BAND_5GHZ
560 ent.edcca_mode_5g_override = RTW_EDCCA_DEF;
561 #endif
562 #if CONFIG_IEEE80211_BAND_6GHZ
563 ent.edcca_mode_6g_override = RTW_EDCCA_DEF;
564 #endif
565 ent.txpwr_lmt_override = TXPWR_LMT_DEF;
566 #if defined(CONFIG_80211AX_HE) || defined(CONFIG_80211AC_VHT)
567 ent.proto_en = CHPLAN_PROTO_EN_ALL;
568 #endif
569 }
570 } else {
571 RTW_PRINT("%s country code:\"%c%c\"\n", __func__
572 , country_ent->alpha2[0], country_ent->alpha2[1]);
573 }
574
575 rfctl->disable_sw_chplan = hw_force_chplan;
576
577 rfctl->regd_inr = RTW_REGD_SET_BY_INIT;
578 rfctl->init_alpha2[0] = rfctl->alpha2[0] = ent.alpha2[0];
579 rfctl->init_alpha2[1] = rfctl->alpha2[1] = ent.alpha2[1];
580 rfctl->init_ChannelPlan = rfctl->ChannelPlan = chplan;
581 #if CONFIG_IEEE80211_BAND_6GHZ
582 rfctl->init_chplan_6g = rfctl->chplan_6g = chplan_6g;
583 #endif
584 rfctl->edcca_mode_2g_override = ent.edcca_mode_2g_override;
585 #if CONFIG_IEEE80211_BAND_5GHZ
586 rfctl->edcca_mode_5g_override = ent.edcca_mode_5g_override;
587 #endif
588 #if CONFIG_IEEE80211_BAND_6GHZ
589 rfctl->edcca_mode_6g_override = ent.edcca_mode_6g_override;
590 #endif
591 #if CONFIG_TXPWR_LIMIT
592 rfctl->txpwr_lmt_override = ent.txpwr_lmt_override;
593 #endif
594 #if defined(CONFIG_80211AX_HE) || defined(CONFIG_80211AC_VHT)
595 rfctl->proto_en = ent.proto_en;
596 #endif
597 }
598
rtw_rfctl_chplan_init(_adapter * adapter)599 void rtw_rfctl_chplan_init(_adapter *adapter)
600 {
601 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
602
603 init_channel_set(adapter);
604 op_class_pref_apply_regulatory(adapter, REG_CHANGE);
605 init_channel_list(adapter, rfctl->channel_set, &rfctl->channel_list);
606 }
607
rtw_rfctl_is_disable_sw_channel_plan(struct dvobj_priv * dvobj)608 bool rtw_rfctl_is_disable_sw_channel_plan(struct dvobj_priv *dvobj)
609 {
610 return dvobj_to_rfctl(dvobj)->disable_sw_chplan;
611 }
612
rtw_rfctl_update_op_mode(struct rf_ctl_t * rfctl,u8 ifbmp_mod,u8 if_op)613 void rtw_rfctl_update_op_mode(struct rf_ctl_t *rfctl, u8 ifbmp_mod, u8 if_op)
614 {
615 struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
616 _adapter *iface;
617 struct mlme_ext_priv *mlmeext;
618 u8 op_class = 0;
619 u8 op_ch = 0;
620 s16 op_txpwr_max;
621 u8 if_op_class[CONFIG_IFACE_NUMBER] = {0};
622 u8 if_op_ch[CONFIG_IFACE_NUMBER] = {0};
623 u8 ch, bw, offset;
624 u8 u_ch = 0, u_bw, u_offset;
625 bool notify = 0;
626 int i;
627
628 for (i = 0; i < dvobj->iface_nums; i++) {
629 iface = dvobj->padapters[i];
630 if (!iface)
631 continue;
632 mlmeext = &iface->mlmeextpriv;
633
634 if (ifbmp_mod & BIT(i)) {
635 if (!if_op)
636 continue;
637 } else if (!MLME_IS_ASOC(iface) || MLME_IS_OPCH_SW(iface))
638 continue;
639
640 ch = mlmeext->cur_channel;
641 bw = mlmeext->cur_bwmode;
642 offset = mlmeext->cur_ch_offset;
643 if_op_class[i] = rtw_get_op_class_by_chbw(ch, bw, offset);
644 if_op_ch[i] = if_op_class[i] ? ch : 0;
645
646 if (!u_ch) {
647 u_ch = ch;
648 u_bw = bw;
649 u_offset = offset;
650 } else {
651 rtw_warn_on(!rtw_is_chbw_grouped(u_ch, u_bw, u_offset, ch, bw, offset));
652 rtw_sync_chbw(&ch, &bw, &offset, &u_ch, &u_bw, &u_offset);
653 }
654 }
655
656 op_class = rtw_get_op_class_by_chbw(u_ch, u_bw, u_offset);
657 op_ch = op_class ? u_ch : 0;
658 op_txpwr_max = rtw_rfctl_get_oper_txpwr_max_mbm(rfctl, u_ch, u_bw, u_offset, ifbmp_mod, if_op, 1);
659
660 if (op_class != rfctl->op_class
661 || op_ch != rfctl->op_ch
662 || op_txpwr_max != rfctl->op_txpwr_max
663 || _rtw_memcmp(if_op_class, rfctl->if_op_class, sizeof(u8) * CONFIG_IFACE_NUMBER) == _FALSE
664 || _rtw_memcmp(if_op_ch, rfctl->if_op_ch, sizeof(u8) * CONFIG_IFACE_NUMBER) == _FALSE)
665 notify = 1;
666
667 rfctl->op_class = op_class;
668 rfctl->op_ch = op_ch;
669 rfctl->op_txpwr_max = op_txpwr_max;
670 _rtw_memcpy(rfctl->if_op_class, if_op_class, sizeof(u8) * CONFIG_IFACE_NUMBER);
671 _rtw_memcpy(rfctl->if_op_ch, if_op_ch, sizeof(u8) * CONFIG_IFACE_NUMBER);
672
673 if (0)
674 RTW_INFO("radio: %u,%u,%u %d notify:%d\n", u_ch, u_bw, u_offset, op_txpwr_max, notify);
675 for (i = 0; i < dvobj->iface_nums; i++) {
676 iface = dvobj->padapters[i];
677 if (!iface)
678 continue;
679 mlmeext = &iface->mlmeextpriv;
680
681 if (ifbmp_mod & BIT(i)) {
682 if (!if_op)
683 continue;
684 } else if (!MLME_IS_ASOC(iface))
685 continue;
686 if (0)
687 RTW_INFO(ADPT_FMT": %u,%u,%u\n", ADPT_ARG(iface)
688 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
689 }
690
691 if (notify)
692 rtw_nlrtw_radio_opmode_notify(rfctl);
693
694 #ifdef CONFIG_PLATFORM_CMAP_INTFS
695 for (i = 0; i < dvobj->iface_nums; i++) {
696 iface = dvobj->padapters[i];
697 if (!iface)
698 continue;
699 cmap_intfs_nl_bss_status_event(iface, 0);
700 }
701 #endif
702 }
703
704 /* domain status specific beacon hint rules */
705 #ifndef RTW_CHPLAN_BEACON_HINT_SPECIFIC_COUNTRY
706 #define RTW_CHPLAN_BEACON_HINT_SPECIFIC_COUNTRY 0
707 #endif
708
rtw_rfctl_reg_allow_beacon_hint(struct rf_ctl_t * rfctl)709 bool rtw_rfctl_reg_allow_beacon_hint(struct rf_ctl_t *rfctl)
710 {
711 return RTW_CHPLAN_BEACON_HINT_SPECIFIC_COUNTRY || RFCTL_REG_WORLDWIDE(rfctl) || RFCTL_REG_ALPHA2_UNSPEC(rfctl);
712 }
713
rtw_rfctl_get_dfs_domain(struct rf_ctl_t * rfctl)714 inline u8 rtw_rfctl_get_dfs_domain(struct rf_ctl_t *rfctl)
715 {
716 #ifdef CONFIG_DFS_MASTER
717 return rfctl->dfs_region_domain;
718 #else
719 return RTW_DFS_REGD_NONE;
720 #endif
721 }
722
rtw_rfctl_dfs_domain_unknown(struct rf_ctl_t * rfctl)723 inline u8 rtw_rfctl_dfs_domain_unknown(struct rf_ctl_t *rfctl)
724 {
725 #ifdef CONFIG_DFS_MASTER
726 return rtw_rfctl_get_dfs_domain(rfctl) == RTW_DFS_REGD_NONE;
727 #else
728 return 1;
729 #endif
730 }
731
732 #ifdef CONFIG_DFS_MASTER
733 /*
734 * called in rtw_dfs_rd_enable()
735 * assume the request channel coverage is DFS range
736 * base on the current status and the request channel coverage to check if need to reset complete CAC time
737 */
rtw_is_cac_reset_needed(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset)738 bool rtw_is_cac_reset_needed(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
739 {
740 bool needed = _FALSE;
741 u32 cur_hi, cur_lo, hi, lo;
742
743 if (rfctl->radar_detected == 1) {
744 needed = _TRUE;
745 goto exit;
746 }
747
748 if (rfctl->radar_detect_ch == 0) {
749 needed = _TRUE;
750 goto exit;
751 }
752
753 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
754 RTW_ERR("request detection range ch:%u, bw:%u, offset:%u\n", ch, bw, offset);
755 rtw_warn_on(1);
756 }
757
758 if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset, &cur_hi, &cur_lo) == _FALSE) {
759 RTW_ERR("cur detection range ch:%u, bw:%u, offset:%u\n", rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset);
760 rtw_warn_on(1);
761 }
762
763 if (hi <= lo || cur_hi <= cur_lo) {
764 RTW_ERR("hi:%u, lo:%u, cur_hi:%u, cur_lo:%u\n", hi, lo, cur_hi, cur_lo);
765 rtw_warn_on(1);
766 }
767
768 if (rtw_is_range_a_in_b(hi, lo, cur_hi, cur_lo)) {
769 /* request is in current detect range */
770 goto exit;
771 }
772
773 /* check if request channel coverage has new range and the new range is in DFS range */
774 if (!rtw_is_range_overlap(hi, lo, cur_hi, cur_lo)) {
775 /* request has no overlap with current */
776 needed = _TRUE;
777 } else if (rtw_is_range_a_in_b(cur_hi, cur_lo, hi, lo)) {
778 /* request is supper set of current */
779 if ((hi != cur_hi && rtw_chset_is_dfs_range(rfctl->channel_set, hi, cur_hi))
780 || (lo != cur_lo && rtw_chset_is_dfs_range(rfctl->channel_set, cur_lo, lo)))
781 needed = _TRUE;
782 } else {
783 /* request is not supper set of current, but has overlap */
784 if ((lo < cur_lo && rtw_chset_is_dfs_range(rfctl->channel_set, cur_lo, lo))
785 || (hi > cur_hi && rtw_chset_is_dfs_range(rfctl->channel_set, hi, cur_hi)))
786 needed = _TRUE;
787 }
788
789 exit:
790 return needed;
791 }
792
_rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset)793 bool _rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
794 {
795 bool ret = _FALSE;
796 u32 hi = 0, lo = 0;
797 u32 r_hi = 0, r_lo = 0;
798 int i;
799
800 if (rfctl->radar_detect_by_others)
801 goto exit;
802
803 if (rfctl->radar_detect_ch == 0)
804 goto exit;
805
806 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
807 rtw_warn_on(1);
808 goto exit;
809 }
810
811 if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch
812 , rfctl->radar_detect_bw, rfctl->radar_detect_offset
813 , &r_hi, &r_lo) == _FALSE) {
814 rtw_warn_on(1);
815 goto exit;
816 }
817
818 if (rtw_is_range_overlap(hi, lo, r_hi, r_lo))
819 ret = _TRUE;
820
821 exit:
822 return ret;
823 }
824
rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t * rfctl)825 bool rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl)
826 {
827 return _rtw_rfctl_overlap_radar_detect_ch(rfctl
828 , rfctl_to_dvobj(rfctl)->oper_channel
829 , rfctl_to_dvobj(rfctl)->oper_bwmode
830 , rfctl_to_dvobj(rfctl)->oper_ch_offset);
831 }
832
rtw_rfctl_is_tx_blocked_by_ch_waiting(struct rf_ctl_t * rfctl)833 bool rtw_rfctl_is_tx_blocked_by_ch_waiting(struct rf_ctl_t *rfctl)
834 {
835 return rtw_rfctl_overlap_radar_detect_ch(rfctl) && IS_CH_WAITING(rfctl);
836 }
837
rtw_chset_is_chbw_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset)838 bool rtw_chset_is_chbw_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
839 {
840 bool ret = _FALSE;
841 u32 hi = 0, lo = 0;
842 int i;
843
844 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
845 goto exit;
846
847 for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
848 if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
849 rtw_warn_on(1);
850 continue;
851 }
852
853 if (!CH_IS_NON_OCP(&ch_set[i]))
854 continue;
855
856 if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
857 && rtw_ch2freq(ch_set[i].ChannelNum) <= hi
858 ) {
859 ret = _TRUE;
860 break;
861 }
862 }
863
864 exit:
865 return ret;
866 }
867
rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch)868 bool rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch)
869 {
870 return rtw_chset_is_chbw_non_ocp(ch_set, ch, CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
871 }
872
rtw_chset_get_ch_non_ocp_ms(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset)873 u32 rtw_chset_get_ch_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
874 {
875 int ms = 0;
876 systime current_time;
877 u32 hi = 0, lo = 0;
878 int i;
879
880 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
881 goto exit;
882
883 current_time = rtw_get_current_time();
884
885 for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
886 if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
887 rtw_warn_on(1);
888 continue;
889 }
890
891 if (!CH_IS_NON_OCP(&ch_set[i]))
892 continue;
893
894 if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
895 && rtw_ch2freq(ch_set[i].ChannelNum) <= hi
896 ) {
897 if (rtw_systime_to_ms(ch_set[i].non_ocp_end_time - current_time) > ms)
898 ms = rtw_systime_to_ms(ch_set[i].non_ocp_end_time - current_time);
899 }
900 }
901
902 exit:
903 return ms;
904 }
905
906 /**
907 * rtw_chset_update_non_ocp - update non_ocp_end_time according to the given @ch, @bw, @offset into @ch_set
908 * @ch_set: the given channel set
909 * @ch: channel number on which radar is detected
910 * @bw: bandwidth on which radar is detected
911 * @offset: bandwidth offset on which radar is detected
912 * @ms: ms to add from now to update non_ocp_end_time, ms < 0 means use NON_OCP_TIME_MS
913 */
_rtw_chset_update_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset,int ms)914 static bool _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
915 {
916 u32 hi = 0, lo = 0;
917 int i;
918 bool updated = 0;
919
920 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
921 goto exit;
922
923 for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
924 if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
925 rtw_warn_on(1);
926 continue;
927 }
928
929 if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
930 && rtw_ch2freq(ch_set[i].ChannelNum) <= hi
931 ) {
932 if (ms >= 0)
933 ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(ms);
934 else
935 ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(NON_OCP_TIME_MS);
936 ch_set[i].flags |= RTW_CHF_NON_OCP;
937 updated = 1;
938 }
939 }
940
941 exit:
942 return updated;
943 }
944
rtw_chset_update_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset)945 inline bool rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
946 {
947 return _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, -1);
948 }
949
rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset,int ms)950 inline bool rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
951 {
952 return _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, ms);
953 }
954
rtw_chset_chk_non_ocp_finish_for_chbw(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset)955 static bool rtw_chset_chk_non_ocp_finish_for_chbw(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
956 {
957 RT_CHANNEL_INFO *ch_set = rfctl->channel_set;
958 u8 cch;
959 u8 *op_chs;
960 u8 op_ch_num;
961 int i;
962 int ch_idx;
963 bool ret = 0;
964
965 cch = rtw_get_center_ch(ch, bw, offset);
966
967 if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num))
968 goto exit;
969
970 for (i = 0; i < op_ch_num; i++) {
971 if (0)
972 RTW_INFO("%u,%u,%u - cch:%u, bw:%u, op_ch:%u\n", ch, bw, offset, cch, bw, *(op_chs + i));
973 ch_idx = rtw_chset_search_ch(ch_set, *(op_chs + i));
974 if (ch_idx == -1)
975 break;
976 if (!(ch_set[ch_idx].flags & RTW_CHF_NON_OCP) || CH_IS_NON_OCP(&ch_set[ch_idx]))
977 break;
978 }
979
980 if (op_ch_num != 0 && i == op_ch_num) {
981 ret = 1;
982 /* clear RTTW_CHF_NON_OCP flag */
983 for (i = 0; i < op_ch_num; i++) {
984 ch_idx = rtw_chset_search_ch(ch_set, *(op_chs + i));
985 ch_set[ch_idx].flags &= ~RTW_CHF_NON_OCP;
986 }
987 rtw_nlrtw_nop_finish_event(dvobj_get_primary_adapter(rfctl_to_dvobj(rfctl)), cch, bw);
988 }
989
990 exit:
991 return ret;
992 }
993
994 /* called by watchdog to clear RTW_CHF_NON_OCP and generate NON_OCP finish event */
rtw_chset_chk_non_ocp_finish(struct rf_ctl_t * rfctl)995 void rtw_chset_chk_non_ocp_finish(struct rf_ctl_t *rfctl)
996 {
997 u8 ch, bw, offset;
998 int i;
999
1000 bw = CHANNEL_WIDTH_160;
1001 while (1) {
1002 for (i = 0; i < rfctl->max_chan_nums; i++) {
1003 ch = rfctl->channel_set[i].ChannelNum;
1004 if (!(rfctl->channel_set[i].flags & RTW_CHF_NON_OCP))
1005 continue;
1006 if (!rtw_get_offset_by_chbw(ch, bw, &offset))
1007 continue;
1008
1009 rtw_chset_chk_non_ocp_finish_for_chbw(rfctl, ch, bw, offset);
1010 }
1011 if (bw-- == CHANNEL_WIDTH_20)
1012 break;
1013 }
1014 }
1015
rtw_get_ch_waiting_ms(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset,u32 * r_non_ocp_ms,u32 * r_cac_ms)1016 u32 rtw_get_ch_waiting_ms(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, u32 *r_non_ocp_ms, u32 *r_cac_ms)
1017 {
1018 struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
1019 u32 non_ocp_ms;
1020 u32 cac_ms;
1021 u8 in_rd_range = 0; /* if in current radar detection range*/
1022
1023 if (rtw_chset_is_chbw_non_ocp(rfctl->channel_set, ch, bw, offset))
1024 non_ocp_ms = rtw_chset_get_ch_non_ocp_ms(rfctl->channel_set, ch, bw, offset);
1025 else
1026 non_ocp_ms = 0;
1027
1028 if (rfctl->radar_detect_enabled) {
1029 u32 cur_hi, cur_lo, hi, lo;
1030
1031 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
1032 RTW_ERR("input range ch:%u, bw:%u, offset:%u\n", ch, bw, offset);
1033 rtw_warn_on(1);
1034 }
1035
1036 if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset, &cur_hi, &cur_lo) == _FALSE) {
1037 RTW_ERR("cur detection range ch:%u, bw:%u, offset:%u\n", rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset);
1038 rtw_warn_on(1);
1039 }
1040
1041 if (rtw_is_range_a_in_b(hi, lo, cur_hi, cur_lo))
1042 in_rd_range = 1;
1043 }
1044
1045 if (!rtw_chset_is_dfs_chbw(rfctl->channel_set, ch, bw, offset))
1046 cac_ms = 0;
1047 else if (in_rd_range && !non_ocp_ms) {
1048 if (IS_CH_WAITING(rfctl))
1049 cac_ms = rtw_systime_to_ms(rfctl->cac_end_time - rtw_get_current_time());
1050 else
1051 cac_ms = 0;
1052 } else if (rtw_is_long_cac_ch(ch, bw, offset, rtw_rfctl_get_dfs_domain(rfctl)))
1053 cac_ms = CAC_TIME_CE_MS;
1054 else
1055 cac_ms = CAC_TIME_MS;
1056
1057 if (r_non_ocp_ms)
1058 *r_non_ocp_ms = non_ocp_ms;
1059 if (r_cac_ms)
1060 *r_cac_ms = cac_ms;
1061
1062 return non_ocp_ms + cac_ms;
1063 }
1064
rtw_reset_cac(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset)1065 void rtw_reset_cac(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
1066 {
1067 u32 non_ocp_ms;
1068 u32 cac_ms;
1069
1070 rtw_get_ch_waiting_ms(rfctl
1071 , ch
1072 , bw
1073 , offset
1074 , &non_ocp_ms
1075 , &cac_ms
1076 );
1077
1078 rfctl->cac_start_time = rtw_get_current_time() + rtw_ms_to_systime(non_ocp_ms);
1079 rfctl->cac_end_time = rfctl->cac_start_time + rtw_ms_to_systime(cac_ms);
1080
1081 /* skip special value */
1082 if (rfctl->cac_start_time == RTW_CAC_STOPPED) {
1083 rfctl->cac_start_time++;
1084 rfctl->cac_end_time++;
1085 }
1086 if (rfctl->cac_end_time == RTW_CAC_STOPPED)
1087 rfctl->cac_end_time++;
1088 }
1089
rtw_force_stop_cac(struct rf_ctl_t * rfctl,u32 timeout_ms)1090 u32 rtw_force_stop_cac(struct rf_ctl_t *rfctl, u32 timeout_ms)
1091 {
1092 struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
1093 systime start;
1094 u32 pass_ms;
1095
1096 start = rtw_get_current_time();
1097
1098 rfctl->cac_force_stop = 1;
1099
1100 while (rtw_get_passing_time_ms(start) <= timeout_ms
1101 && IS_UNDER_CAC(rfctl)
1102 ) {
1103 if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
1104 break;
1105 rtw_msleep_os(20);
1106 }
1107
1108 if (IS_UNDER_CAC(rfctl)) {
1109 if (!dev_is_surprise_removed(dvobj) && !dev_is_drv_stopped(dvobj))
1110 RTW_INFO("%s waiting for cac stop timeout!\n", __func__);
1111 }
1112
1113 rfctl->cac_force_stop = 0;
1114
1115 pass_ms = rtw_get_passing_time_ms(start);
1116
1117 return pass_ms;
1118 }
1119 #endif /* CONFIG_DFS_MASTER */
1120
1121 /* choose channel with shortest waiting (non ocp + cac) time */
rtw_choose_shortest_waiting_ch(struct rf_ctl_t * rfctl,u8 sel_ch,u8 max_bw,u8 * dec_ch,u8 * dec_bw,u8 * dec_offset,u8 e_flags,u8 d_flags,u8 cur_ch,bool by_int_info,u8 mesh_only)1122 bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw
1123 , u8 *dec_ch, u8 *dec_bw, u8 *dec_offset
1124 , u8 e_flags, u8 d_flags, u8 cur_ch, bool by_int_info, u8 mesh_only)
1125 {
1126 #ifndef DBG_CHOOSE_SHORTEST_WAITING_CH
1127 #define DBG_CHOOSE_SHORTEST_WAITING_CH 0
1128 #endif
1129 struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
1130 #ifdef CONFIG_RTW_ACS
1131 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(dvobj_get_primary_adapter(dvobj));
1132 #endif
1133 struct registry_priv *regsty = dvobj_to_regsty(dvobj);
1134 u8 ch, bw, offset;
1135 u8 ch_c = 0, bw_c = 0, offset_c = 0;
1136 int i;
1137 u32 min_waiting_ms = 0;
1138 u16 int_factor_c = 0;
1139
1140 if (!dec_ch || !dec_bw || !dec_offset) {
1141 rtw_warn_on(1);
1142 return _FALSE;
1143 }
1144
1145 RTW_INFO("%s: sel_ch:%u max_bw:%u e_flags:0x%02x d_flags:0x%02x cur_ch:%u within_sb:%d%s%s\n"
1146 , __func__, sel_ch, max_bw, e_flags, d_flags, cur_ch, rfctl->ch_sel_within_same_band
1147 , by_int_info ? " int" : "", mesh_only ? " mesh_only" : "");
1148
1149 /* full search and narrow bw judegement first to avoid potetial judegement timing issue */
1150 for (bw = CHANNEL_WIDTH_20; bw <= max_bw; bw++) {
1151 if (!hal_is_bw_support(dvobj_get_primary_adapter(dvobj), bw))
1152 continue;
1153
1154 for (i = 0; i < rfctl->max_chan_nums; i++) {
1155 u32 non_ocp_ms = 0;
1156 u32 cac_ms = 0;
1157 u32 waiting_ms = 0;
1158 u16 int_factor = 0;
1159 bool dfs_ch;
1160 bool non_ocp;
1161 bool long_cac;
1162
1163 ch = rfctl->channel_set[i].ChannelNum;
1164 if (sel_ch) {
1165 if (ch != sel_ch)
1166 continue;
1167 } else if (rfctl->ch_sel_within_same_band && !rtw_is_same_band(cur_ch, ch))
1168 continue;
1169
1170 if (ch > 14) {
1171 if (bw > REGSTY_BW_5G(regsty))
1172 continue;
1173 } else {
1174 if (bw > REGSTY_BW_2G(regsty))
1175 continue;
1176 }
1177
1178 if (mesh_only && ch >= 5 && ch <= 9 && bw > CHANNEL_WIDTH_20)
1179 continue;
1180
1181 if (!rtw_get_offset_by_chbw(ch, bw, &offset))
1182 continue;
1183
1184 if (!rtw_chset_is_chbw_valid(rfctl->channel_set, ch, bw, offset, 0, 0))
1185 continue;
1186
1187 if ((e_flags & RTW_CHF_DFS) || (d_flags & RTW_CHF_DFS)) {
1188 dfs_ch = rtw_chset_is_dfs_chbw(rfctl->channel_set, ch, bw, offset);
1189 if (((e_flags & RTW_CHF_DFS) && !dfs_ch)
1190 || ((d_flags & RTW_CHF_DFS) && dfs_ch))
1191 continue;
1192 }
1193
1194 if ((e_flags & RTW_CHF_LONG_CAC) || (d_flags & RTW_CHF_LONG_CAC)) {
1195 long_cac = rtw_is_long_cac_ch(ch, bw, offset, rtw_rfctl_get_dfs_domain(rfctl));
1196 if (((e_flags & RTW_CHF_LONG_CAC) && !long_cac)
1197 || ((d_flags & RTW_CHF_LONG_CAC) && long_cac))
1198 continue;
1199 }
1200
1201 if ((e_flags & RTW_CHF_NON_OCP) || (d_flags & RTW_CHF_NON_OCP)) {
1202 non_ocp = rtw_chset_is_chbw_non_ocp(rfctl->channel_set, ch, bw, offset);
1203 if (((e_flags & RTW_CHF_NON_OCP) && !non_ocp)
1204 || ((d_flags & RTW_CHF_NON_OCP) && non_ocp))
1205 continue;
1206 }
1207
1208 #ifdef CONFIG_DFS_MASTER
1209 waiting_ms = rtw_get_ch_waiting_ms(rfctl, ch, bw, offset, &non_ocp_ms, &cac_ms);
1210 #endif
1211
1212 #ifdef CONFIG_RTW_ACS
1213 if (by_int_info) {
1214 /* for now, consider only primary channel */
1215 int_factor = hal_data->acs.interference_time[i];
1216 }
1217 #endif
1218
1219 if (DBG_CHOOSE_SHORTEST_WAITING_CH)
1220 RTW_INFO("%s:%u,%u,%u %u(non_ocp:%u, cac:%u), int:%u\n"
1221 , __func__, ch, bw, offset, waiting_ms, non_ocp_ms, cac_ms, int_factor);
1222
1223 if (ch_c == 0
1224 /* first: smaller wating time */
1225 || min_waiting_ms > waiting_ms
1226 /* then: less interference */
1227 || (min_waiting_ms == waiting_ms && int_factor_c > int_factor)
1228 /* then: wider bw */
1229 || (min_waiting_ms == waiting_ms && int_factor_c == int_factor && bw > bw_c)
1230 /* if all condition equal, same channel -> same band prefer */
1231 || (min_waiting_ms == waiting_ms && int_factor_c == int_factor && bw == bw_c
1232 && ((cur_ch != ch_c && cur_ch == ch)
1233 || (!rtw_is_same_band(cur_ch, ch_c) && rtw_is_same_band(cur_ch, ch)))
1234 )
1235 ) {
1236 ch_c = ch;
1237 bw_c = bw;
1238 offset_c = offset;
1239 min_waiting_ms = waiting_ms;
1240 int_factor_c = int_factor;
1241 }
1242 }
1243 }
1244
1245 if (ch_c != 0) {
1246 RTW_INFO("%s: select %u,%u,%u waiting_ms:%u\n"
1247 , __func__, ch_c, bw_c, offset_c, min_waiting_ms);
1248 *dec_ch = ch_c;
1249 *dec_bw = bw_c;
1250 *dec_offset = offset_c;
1251 return _TRUE;
1252 } else {
1253 RTW_INFO("%s: not found\n", __func__);
1254 if (d_flags == 0)
1255 rtw_warn_on(1);
1256 }
1257
1258 return _FALSE;
1259 }
1260
1261 #ifdef CONFIG_PROC_DEBUG
1262 #define RTW_CHF_FMT "%s%s%s%s%s%s"
1263
1264 #define RTW_CHF_ARG_NO_IR(flags) (flags & RTW_CHF_NO_IR) ? " NO_IR" : ""
1265 #define RTW_CHF_ARG_DFS(flags) , (flags & RTW_CHF_DFS) ? " DFS" : ""
1266 #define RTW_CHF_ARG_NO_HT40U(flags) , (flags & RTW_CHF_NO_HT40U) ? " NO_40M+" : ""
1267 #define RTW_CHF_ARG_NO_HT40L(flags) , (flags & RTW_CHF_NO_HT40L) ? " NO_40M-" : ""
1268 #define RTW_CHF_ARG_NO_80MHZ(flags) , (flags & RTW_CHF_NO_80MHZ) ? " NO_80M" : ""
1269 #define RTW_CHF_ARG_NO_160MHZ(flags) , (flags & RTW_CHF_NO_160MHZ) ? " NO_160M" : ""
1270
1271 #define RTW_CHF_ARG(flags) \
1272 RTW_CHF_ARG_NO_IR(flags) \
1273 RTW_CHF_ARG_DFS(flags) \
1274 RTW_CHF_ARG_NO_HT40U(flags) \
1275 RTW_CHF_ARG_NO_HT40L(flags) \
1276 RTW_CHF_ARG_NO_80MHZ(flags) \
1277 RTW_CHF_ARG_NO_160MHZ(flags)
1278
dump_chset(void * sel,RT_CHANNEL_INFO * ch_set,u8 chset_num)1279 static void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set, u8 chset_num)
1280 {
1281 char buf[8];
1282 u8 i;
1283
1284 RTW_PRINT_SEL(sel, "%-3s %-4s %-4s flags\n", "ch", "freq", "nocp");
1285
1286 for (i = 0; i < MAX_CHANNEL_NUM && i < chset_num && ch_set[i].ChannelNum != 0; i++) {
1287 #ifdef CONFIG_DFS_MASTER
1288 if ((ch_set[i].flags & RTW_CHF_DFS) && CH_IS_NON_OCP(&ch_set[i]))
1289 snprintf(buf, 8, "%d", rtw_systime_to_ms(ch_set[i].non_ocp_end_time - rtw_get_current_time()) / 1000);
1290 else
1291 #endif
1292 snprintf(buf, 8, "0");
1293
1294 RTW_PRINT_SEL(sel, "%3u %4u %4s"RTW_CHF_FMT"\n"
1295 , ch_set[i].ChannelNum, rtw_ch2freq_by_band(ch_set[i].band, ch_set[i].ChannelNum), buf
1296 , RTW_CHF_ARG(ch_set[i].flags)
1297 );
1298 }
1299
1300 RTW_PRINT_SEL(sel, "total ch number:%d\n", i);
1301 }
1302
dump_chplan_txpwr_lmts(void * sel,struct get_chplan_resp * chplan)1303 static void dump_chplan_txpwr_lmts(void *sel, struct get_chplan_resp *chplan)
1304 {
1305 char buf[TXPWR_NAMES_STR_LEN];
1306
1307 RTW_PRINT_SEL(sel, "txpwr_lmt:%s\n", rtw_get_txpwr_lmt_names_str(buf, chplan->txpwr_lmt_name, 0));
1308 }
1309
dump_chplan_edcca_modes(void * sel,struct get_chplan_resp * chplan)1310 static void dump_chplan_edcca_modes(void *sel, struct get_chplan_resp *chplan)
1311 {
1312 u8 modes[BAND_MAX];
1313 char buf[EDCCA_MODES_STR_LEN];
1314
1315 modes[BAND_ON_2_4G] = chplan->edcca_mode_2g;
1316 #if CONFIG_IEEE80211_BAND_5GHZ
1317 modes[BAND_ON_5G] = chplan->edcca_mode_5g;
1318 #endif
1319 #if CONFIG_IEEE80211_BAND_6GHZ
1320 modes[BAND_ON_6G] = chplan->edcca_mode_6g;
1321 #endif
1322
1323 RTW_PRINT_SEL(sel, "edcca_mode:%s\n", rtw_get_edcca_modes_str(buf, modes));
1324 }
1325
dump_cur_country(void * sel,struct rf_ctl_t * rfctl)1326 void dump_cur_country(void *sel, struct rf_ctl_t *rfctl)
1327 {
1328 struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
1329 struct get_chplan_resp *chplan;
1330 int i;
1331
1332 if (rtw_get_chplan_cmd(dvobj_get_primary_adapter(dvobj), RTW_CMDF_WAIT_ACK, &chplan) == _FAIL)
1333 return;
1334
1335 RTW_PRINT_SEL(sel, "%c%c\n", chplan->alpha2[0], chplan->alpha2[1]);
1336
1337 rtw_vmfree(chplan, sizeof(struct get_chplan_resp) + sizeof(RT_CHANNEL_INFO) * chplan->chset_num);
1338 }
1339
dump_cur_chset(void * sel,struct rf_ctl_t * rfctl)1340 void dump_cur_chset(void *sel, struct rf_ctl_t *rfctl)
1341 {
1342 struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
1343 struct registry_priv *regsty = dvobj_to_regsty(dvobj);
1344 struct get_chplan_resp *chplan;
1345 int i;
1346
1347 if (rtw_get_chplan_cmd(dvobj_get_primary_adapter(dvobj), RTW_CMDF_WAIT_ACK, &chplan) == _FAIL)
1348 return;
1349
1350 RTW_PRINT_SEL(sel, "regd_src:%s(%d)\n", regd_src_str(chplan->regd_src), chplan->regd_src);
1351 RTW_PRINT_SEL(sel, "regd_inr:%s\n", regd_inr_str(chplan->regd_inr));
1352
1353 RTW_PRINT_SEL(sel, "alpha2:%c%c\n", chplan->alpha2[0], chplan->alpha2[1]);
1354
1355 #ifdef CONFIG_80211AX_HE
1356 RTW_PRINT_SEL(sel, "ax:%d\n", (chplan->proto_en & CHPLAN_PROTO_EN_AX) ? 1 : 0);
1357 #endif
1358 #ifdef CONFIG_80211AC_VHT
1359 RTW_PRINT_SEL(sel, "ac:%d\n", (chplan->proto_en & CHPLAN_PROTO_EN_AC) ? 1 : 0);
1360 #endif
1361
1362 if (chplan->channel_plan == RTW_CHPLAN_UNSPECIFIED)
1363 RTW_PRINT_SEL(sel, "chplan:NA\n");
1364 else
1365 RTW_PRINT_SEL(sel, "chplan:0x%02X\n", chplan->channel_plan);
1366
1367 #if CONFIG_IEEE80211_BAND_6GHZ
1368 if (chplan->chplan_6g == RTW_CHPLAN_6G_UNSPECIFIED)
1369 RTW_PRINT_SEL(sel, "chplan_6g:NA\n");
1370 else
1371 RTW_PRINT_SEL(sel, "chplan_6g:0x%02X\n", chplan->chplan_6g);
1372 #endif
1373
1374 #if CONFIG_TXPWR_LIMIT
1375 dump_chplan_txpwr_lmts(sel, chplan);
1376 #endif
1377
1378 dump_chplan_edcca_modes(sel, chplan);
1379
1380 #ifdef CONFIG_DFS_MASTER
1381 RTW_PRINT_SEL(sel, "dfs_domain:%s(%u)\n", rtw_dfs_regd_str(chplan->dfs_domain), chplan->dfs_domain);
1382 #endif
1383
1384 for (i = 0; i < MAX_CHANNEL_NUM_2G_5G; i++)
1385 if (regsty->excl_chs[i] != 0)
1386 break;
1387
1388 if (i < MAX_CHANNEL_NUM_2G_5G) {
1389 RTW_PRINT_SEL(sel, "excl_chs:");
1390 for (i = 0; i < MAX_CHANNEL_NUM_2G_5G; i++) {
1391 if (regsty->excl_chs[i] == 0)
1392 break;
1393 _RTW_PRINT_SEL(sel, "%u ", regsty->excl_chs[i]);
1394 }
1395 _RTW_PRINT_SEL(sel, "\n");
1396 }
1397
1398 #if CONFIG_IEEE80211_BAND_6GHZ
1399 for (i = 0; i < MAX_CHANNEL_NUM_6G; i++)
1400 if (regsty->excl_chs_6g[i] != 0)
1401 break;
1402
1403 if (i < MAX_CHANNEL_NUM_6G) {
1404 RTW_PRINT_SEL(sel, "excl_chs_6g:");
1405 for (i = 0; i < MAX_CHANNEL_NUM_6G; i++) {
1406 if (regsty->excl_chs_6g[i] == 0)
1407 break;
1408 _RTW_PRINT_SEL(sel, "%u ", regsty->excl_chs_6g[i]);
1409 }
1410 _RTW_PRINT_SEL(sel, "\n");
1411 }
1412 #endif
1413
1414 dump_chset(sel, chplan->chset, chplan->chset_num);
1415
1416 rtw_vmfree(chplan, sizeof(struct get_chplan_resp) + sizeof(RT_CHANNEL_INFO) * chplan->chset_num);
1417 }
1418 #endif /* CONFIG_PROC_DEBUG */
1419
1420 /*
1421 * Search the @param ch in given @param ch_set
1422 * @ch_set: the given channel set
1423 * @ch: the given channel number
1424 *
1425 * return the index of channel_num in channel_set, -1 if not found
1426 */
rtw_chset_search_ch(RT_CHANNEL_INFO * ch_set,const u32 ch)1427 int rtw_chset_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
1428 {
1429 int i;
1430
1431 if (ch == 0)
1432 return -1;
1433
1434 for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
1435 if (ch == ch_set[i].ChannelNum)
1436 return i;
1437 }
1438
1439 return -1;
1440 }
1441
1442 /*
1443 * Search the @param ch of @param band in given @param ch_set
1444 * @ch_set: the given channel set
1445 * @band: the given band
1446 * @ch: the given channel number
1447 *
1448 * return the index of channel_num in channel_set, -1 if not found
1449 */
rtw_chset_search_ch_by_band(RT_CHANNEL_INFO * ch_set,BAND_TYPE band,const u32 ch)1450 int rtw_chset_search_ch_by_band(RT_CHANNEL_INFO *ch_set, BAND_TYPE band, const u32 ch)
1451 {
1452 int i;
1453
1454 if (ch == 0)
1455 return -1;
1456
1457 for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
1458 if (band == ch_set[i].band && ch == ch_set[i].ChannelNum)
1459 return i;
1460 }
1461
1462 return -1;
1463 }
1464
1465 /*
1466 * Check if the @param ch, bw, offset is valid for the given @param ch_set
1467 * @ch_set: the given channel set
1468 * @ch: the given channel number
1469 * @bw: the given bandwidth
1470 * @offset: the given channel offset
1471 *
1472 * return valid (1) or not (0)
1473 */
rtw_chset_is_chbw_valid(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset,bool allow_primary_passive,bool allow_passive)1474 u8 rtw_chset_is_chbw_valid(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset
1475 , bool allow_primary_passive, bool allow_passive)
1476 {
1477 u8 cch;
1478 u8 *op_chs;
1479 u8 op_ch_num;
1480 u8 valid = 0;
1481 int i;
1482 int ch_idx;
1483
1484 cch = rtw_get_center_ch(ch, bw, offset);
1485
1486 if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num))
1487 goto exit;
1488
1489 for (i = 0; i < op_ch_num; i++) {
1490 if (0)
1491 RTW_INFO("%u,%u,%u - cch:%u, bw:%u, op_ch:%u\n", ch, bw, offset, cch, bw, *(op_chs + i));
1492 ch_idx = rtw_chset_search_ch(ch_set, *(op_chs + i));
1493 if (ch_idx == -1)
1494 break;
1495 if (ch_set[ch_idx].flags & RTW_CHF_NO_IR) {
1496 if (!allow_passive
1497 || (!allow_primary_passive && ch_set[ch_idx].ChannelNum == ch))
1498 break;
1499 }
1500 if (bw >= CHANNEL_WIDTH_40) {
1501 if ((ch_set[ch_idx].flags & RTW_CHF_NO_HT40U) && i % 2 == 0)
1502 break;
1503 if ((ch_set[ch_idx].flags & RTW_CHF_NO_HT40L) && i % 2 == 1)
1504 break;
1505 }
1506 if (bw >= CHANNEL_WIDTH_80 && (ch_set[ch_idx].flags & RTW_CHF_NO_80MHZ))
1507 break;
1508 if (bw >= CHANNEL_WIDTH_160 && (ch_set[ch_idx].flags & RTW_CHF_NO_160MHZ))
1509 break;
1510 }
1511
1512 if (op_ch_num != 0 && i == op_ch_num)
1513 valid = 1;
1514
1515 exit:
1516 return valid;
1517 }
1518
1519 /**
1520 * rtw_chset_sync_chbw - obey g_ch, adjust g_bw, g_offset, bw, offset to fit in channel plan
1521 * @ch_set: channel plan to check
1522 * @req_ch: pointer of the request ch, may be modified further
1523 * @req_bw: pointer of the request bw, may be modified further
1524 * @req_offset: pointer of the request offset, may be modified further
1525 * @g_ch: pointer of the ongoing group ch
1526 * @g_bw: pointer of the ongoing group bw, may be modified further
1527 * @g_offset: pointer of the ongoing group offset, may be modified further
1528 * @allow_primary_passive: if allow passive primary ch when deciding chbw
1529 * @allow_passive: if allow passive ch (not primary) when deciding chbw
1530 */
rtw_chset_sync_chbw(RT_CHANNEL_INFO * ch_set,u8 * req_ch,u8 * req_bw,u8 * req_offset,u8 * g_ch,u8 * g_bw,u8 * g_offset,bool allow_primary_passive,bool allow_passive)1531 void rtw_chset_sync_chbw(RT_CHANNEL_INFO *ch_set, u8 *req_ch, u8 *req_bw, u8 *req_offset
1532 , u8 *g_ch, u8 *g_bw, u8 *g_offset, bool allow_primary_passive, bool allow_passive)
1533 {
1534 u8 r_ch, r_bw, r_offset;
1535 u8 u_ch, u_bw, u_offset;
1536 u8 cur_bw = *req_bw;
1537
1538 while (1) {
1539 r_ch = *req_ch;
1540 r_bw = cur_bw;
1541 r_offset = *req_offset;
1542 u_ch = *g_ch;
1543 u_bw = *g_bw;
1544 u_offset = *g_offset;
1545
1546 rtw_sync_chbw(&r_ch, &r_bw, &r_offset, &u_ch, &u_bw, &u_offset);
1547
1548 if (rtw_chset_is_chbw_valid(ch_set, r_ch, r_bw, r_offset, allow_primary_passive, allow_passive))
1549 break;
1550 if (cur_bw == CHANNEL_WIDTH_20) {
1551 rtw_warn_on(1);
1552 break;
1553 }
1554 cur_bw--;
1555 };
1556
1557 *req_ch = r_ch;
1558 *req_bw = r_bw;
1559 *req_offset = r_offset;
1560 *g_ch = u_ch;
1561 *g_bw = u_bw;
1562 *g_offset = u_offset;
1563 }
1564
1565 /*
1566 * Check the @param ch is fit with setband setting of @param adapter
1567 * @adapter: the given adapter
1568 * @ch: the given channel number
1569 *
1570 * return _TRUE when check valid, _FALSE not valid
1571 */
rtw_mlme_band_check(_adapter * adapter,const u32 ch)1572 bool rtw_mlme_band_check(_adapter *adapter, const u32 ch)
1573 {
1574 if (adapter->setband == WIFI_FREQUENCY_BAND_AUTO /* 2.4G and 5G */
1575 || (adapter->setband == WIFI_FREQUENCY_BAND_2GHZ && ch < 35) /* 2.4G only */
1576 || (adapter->setband == WIFI_FREQUENCY_BAND_5GHZ && ch > 35) /* 5G only */
1577 )
1578 return _TRUE;
1579 return _FALSE;
1580 }
RTW_SET_SCAN_BAND_SKIP(_adapter * padapter,int skip_band)1581 inline void RTW_SET_SCAN_BAND_SKIP(_adapter *padapter, int skip_band)
1582 {
1583 int bs = ATOMIC_READ(&padapter->bandskip);
1584
1585 bs |= skip_band;
1586 ATOMIC_SET(&padapter->bandskip, bs);
1587 }
1588
RTW_CLR_SCAN_BAND_SKIP(_adapter * padapter,int skip_band)1589 inline void RTW_CLR_SCAN_BAND_SKIP(_adapter *padapter, int skip_band)
1590 {
1591 int bs = ATOMIC_READ(&padapter->bandskip);
1592
1593 bs &= ~(skip_band);
1594 ATOMIC_SET(&padapter->bandskip, bs);
1595 }
RTW_GET_SCAN_BAND_SKIP(_adapter * padapter)1596 inline int RTW_GET_SCAN_BAND_SKIP(_adapter *padapter)
1597 {
1598 return ATOMIC_READ(&padapter->bandskip);
1599 }
1600
1601 #define RTW_IS_SCAN_BAND_SKIP(padapter, skip_band) (ATOMIC_READ(&padapter->bandskip) & (skip_band))
1602
rtw_mlme_ignore_chan(_adapter * adapter,const u32 ch)1603 bool rtw_mlme_ignore_chan(_adapter *adapter, const u32 ch)
1604 {
1605 if (RTW_IS_SCAN_BAND_SKIP(adapter, BAND_24G) && ch < 35) /* SKIP 2.4G Band channel */
1606 return _TRUE;
1607 if (RTW_IS_SCAN_BAND_SKIP(adapter, BAND_5G) && ch > 35) /* SKIP 5G Band channel */
1608 return _TRUE;
1609
1610 return _FALSE;
1611 }
1612
1613
1614 /****************************************************************************
1615
1616 Following are the initialization functions for WiFi MLME
1617
1618 *****************************************************************************/
1619
init_hw_mlme_ext(_adapter * padapter)1620 int init_hw_mlme_ext(_adapter *padapter)
1621 {
1622 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1623 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1624 u8 rx_bar_enble = _TRUE;
1625
1626 /*
1627 * Sync driver status and hardware setting
1628 */
1629
1630 /* Modify to make sure first time change channel(band) would be done properly */
1631 pHalData->current_channel = 0;
1632 pHalData->current_channel_bw = CHANNEL_WIDTH_MAX;
1633 #if CONFIG_IEEE80211_BAND_5GHZ
1634 pHalData->current_band_type = BAND_MAX;
1635 #else
1636 pHalData->current_band_type = BAND_ON_2_4G;
1637 #endif
1638
1639 /* set_opmode_cmd(padapter, infra_client_with_mlme); */ /* removed */
1640 rtw_hal_set_hwreg(padapter, HW_VAR_ENABLE_RX_BAR, &rx_bar_enble);
1641 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
1642
1643 return _SUCCESS;
1644 }
1645
init_mlme_default_rate_set(_adapter * padapter)1646 void init_mlme_default_rate_set(_adapter *padapter)
1647 {
1648 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1649 unsigned char end_set[1] = {0xff};
1650 u8 offset_datarate = 0;
1651 u8 offset_basicrate = 0;
1652 #ifdef CONFIG_80211N_HT
1653 unsigned char supported_mcs_set[16] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
1654 #endif
1655
1656 if (IsSupportedTxCCK(padapter->registrypriv.wireless_mode)) {
1657
1658 unsigned char datarate_b[B_MODE_RATE_NUM] ={_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_};
1659 _rtw_memcpy(pmlmeext->datarate, datarate_b, B_MODE_RATE_NUM);
1660 _rtw_memcpy(pmlmeext->basicrate, datarate_b, B_MODE_RATE_NUM);
1661 offset_datarate += B_MODE_RATE_NUM;
1662 offset_basicrate += B_MODE_RATE_NUM;
1663 RTW_INFO("%s: support CCK\n", __func__);
1664 }
1665 if(IsSupportedTxOFDM(padapter->registrypriv.wireless_mode)) {
1666 unsigned char datarate_g[G_MODE_RATE_NUM] ={_6M_RATE_, _9M_RATE_, _12M_RATE_, _18M_RATE_,_24M_RATE_, _36M_RATE_, _48M_RATE_, _54M_RATE_};
1667 unsigned char basicrate_g[G_MODE_BASIC_RATE_NUM] = {_6M_RATE_, _12M_RATE_, _24M_RATE_};
1668 _rtw_memcpy(pmlmeext->datarate + offset_datarate, datarate_g, G_MODE_RATE_NUM);
1669 _rtw_memcpy(pmlmeext->basicrate + offset_basicrate,basicrate_g, G_MODE_BASIC_RATE_NUM);
1670 offset_datarate += G_MODE_RATE_NUM;
1671 offset_basicrate += G_MODE_BASIC_RATE_NUM;
1672 RTW_INFO("%s: support OFDM\n", __func__);
1673
1674 }
1675 _rtw_memcpy(pmlmeext->datarate + offset_datarate, end_set, 1);
1676 _rtw_memcpy(pmlmeext->basicrate + offset_basicrate, end_set, 1);
1677
1678 #ifdef CONFIG_80211N_HT
1679 if( padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode))
1680 _rtw_memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set));
1681 #endif
1682 }
1683
init_mlme_ext_priv_value(_adapter * padapter)1684 static void init_mlme_ext_priv_value(_adapter *padapter)
1685 {
1686 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1687 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1688
1689 ATOMIC_SET(&pmlmeext->event_seq, 0);
1690 pmlmeext->mgnt_seq = 0;/* reset to zero when disconnect at client mode */
1691 #ifdef CONFIG_IEEE80211W
1692 pmlmeext->sa_query_seq = 0;
1693 #endif
1694 pmlmeext->cur_channel = padapter->registrypriv.channel;
1695 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
1696 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1697
1698 pmlmeext->retry = 0;
1699
1700 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
1701 init_mlme_default_rate_set(padapter);
1702
1703 if ((pmlmeext->cur_channel > 14) || ((padapter->registrypriv.wireless_mode & WIRELESS_11B) == 0)) {
1704 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
1705 pmlmeext->tx_rate_section = OFDM;
1706 } else {
1707 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
1708 pmlmeext->tx_rate_section = CCK;
1709 }
1710
1711 mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
1712 pmlmeext->sitesurvey_res.channel_idx = 0;
1713 pmlmeext->sitesurvey_res.bss_cnt = 0;
1714 pmlmeext->sitesurvey_res.scan_ch_ms = SURVEY_TO;
1715 pmlmeext->sitesurvey_res.rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID;
1716 pmlmeext->sitesurvey_res.rx_ampdu_size = RX_AMPDU_SIZE_INVALID;
1717 #ifdef CONFIG_SCAN_BACKOP
1718 #ifdef CONFIG_LAYER2_ROAMING
1719 if (padapter->mlmepriv.roam_flags & BIT2)
1720 mlmeext_assign_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME);
1721 else
1722 #endif
1723 mlmeext_assign_scan_backop_flags_sta(pmlmeext, /*SS_BACKOP_EN |*/ SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME);
1724 #ifdef CONFIG_AP_MODE
1725 #ifdef CONFIG_CUSTOMER_EZVIZ_CHIME2
1726 mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME | SS_BACKOP_EN_NL);
1727 #else
1728 mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME);
1729 #endif
1730 #endif
1731 #ifdef CONFIG_RTW_MESH
1732 mlmeext_assign_scan_backop_flags_mesh(pmlmeext, /*SS_BACKOP_EN | */SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME);
1733 #endif
1734 pmlmeext->sitesurvey_res.scan_cnt = 0;
1735 pmlmeext->sitesurvey_res.scan_cnt_max = RTW_SCAN_NUM_OF_CH;
1736 pmlmeext->sitesurvey_res.backop_ms = RTW_BACK_OP_CH_MS;
1737 #endif
1738 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
1739 pmlmeext->sitesurvey_res.is_sw_antdiv_bl_scan = 0;
1740 #endif
1741 pmlmeext->scan_abort = _FALSE;
1742
1743 pmlmeinfo->state = WIFI_FW_NULL_STATE;
1744 pmlmeinfo->reauth_count = 0;
1745 pmlmeinfo->reassoc_count = 0;
1746 pmlmeinfo->link_count = 0;
1747 pmlmeinfo->auth_seq = 0;
1748 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1749 pmlmeinfo->key_index = 0;
1750 pmlmeinfo->iv = 0;
1751
1752 pmlmeinfo->enc_algo = _NO_PRIVACY_;
1753 pmlmeinfo->authModeToggle = 0;
1754
1755 _rtw_memset(pmlmeinfo->chg_txt, 0, 128);
1756
1757 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
1758 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
1759
1760 pmlmeinfo->dialogToken = 0;
1761
1762 pmlmeext->action_public_rxseq = 0xffff;
1763 pmlmeext->action_public_dialog_token = 0xff;
1764 #ifdef ROKU_PRIVATE
1765 /*infra mode, used to store AP's info*/
1766 _rtw_memset(pmlmeinfo->SupportedRates_infra_ap, 0, NDIS_802_11_LENGTH_RATES_EX);
1767 pmlmeinfo->ht_vht_received = 0;
1768 #endif /* ROKU_PRIVATE */
1769 #ifdef CONFIG_WRITE_BCN_LEN_TO_FW
1770 pmlmeinfo->last_bcn_len = 0;
1771 #endif
1772 }
1773
init_mlme_ext_timer(_adapter * padapter)1774 void init_mlme_ext_timer(_adapter *padapter)
1775 {
1776 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1777
1778 rtw_init_timer(&pmlmeext->survey_timer, padapter, survey_timer_hdl, padapter);
1779 rtw_init_timer(&pmlmeext->link_timer, padapter, link_timer_hdl, padapter);
1780 #ifdef CONFIG_RTW_80211R
1781 rtw_init_timer(&pmlmeext->ft_link_timer, padapter, rtw_ft_link_timer_hdl, padapter);
1782 rtw_init_timer(&pmlmeext->ft_roam_timer, padapter, rtw_ft_roam_timer_hdl, padapter);
1783 #endif
1784
1785 #ifdef CONFIG_RTW_REPEATER_SON
1786 rtw_init_timer(&pmlmeext->rson_scan_timer, padapter, rson_timer_hdl, padapter);
1787 #endif
1788 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
1789 rtw_init_timer(&pmlmeext->tbtx_xmit_timer, padapter, rtw_tbtx_xmit_timer_hdl, padapter);
1790 rtw_init_timer(&pmlmeext->tbtx_token_dispatch_timer, padapter, rtw_tbtx_token_dispatch_timer_hdl, padapter);
1791 #endif
1792 #ifdef CONFIG_DFS
1793 rtw_init_timer(&pmlmeext->csa_timer, padapter->pnetdev, csa_timer_hdl, padapter);
1794 #endif
1795 }
1796
init_mlme_ext_priv(_adapter * padapter)1797 int init_mlme_ext_priv(_adapter *padapter)
1798 {
1799 int res = _SUCCESS;
1800 struct registry_priv *pregistrypriv = &padapter->registrypriv;
1801 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1802 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1803
1804 /* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
1805 /* _rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv)); */
1806
1807 pmlmeext->padapter = padapter;
1808
1809 /* fill_fwpriv(padapter, &(pmlmeext->fwpriv)); */
1810
1811 init_mlme_ext_priv_value(padapter);
1812 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
1813
1814 init_mlme_ext_timer(padapter);
1815
1816 #ifdef CONFIG_AP_MODE
1817 init_mlme_ap_info(padapter);
1818 #endif
1819
1820 pmlmeext->last_scan_time = 0;
1821 pmlmeext->mlmeext_init = _TRUE;
1822
1823
1824 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
1825 pmlmeext->active_keep_alive_check = _TRUE;
1826 #else
1827 pmlmeext->active_keep_alive_check = _FALSE;
1828 #endif
1829
1830 #ifdef DBG_FIXED_CHAN
1831 pmlmeext->fixed_chan = 0xFF;
1832 #endif
1833
1834 pmlmeext->tsf_update_pause_factor = pregistrypriv->tsf_update_pause_factor;
1835 pmlmeext->tsf_update_restore_factor = pregistrypriv->tsf_update_restore_factor;
1836
1837 #ifdef CONFIG_SUPPORT_STATIC_SMPS
1838 pmlmeext->ssmps_en = _FALSE;
1839 pmlmeext->ssmps_tx_tp_th = SSMPS_TX_TP_TH;/*Mbps*/
1840 pmlmeext->ssmps_rx_tp_th = SSMPS_RX_TP_TH;/*Mbps*/
1841 #ifdef DBG_STATIC_SMPS
1842 pmlmeext->ssmps_test = _FALSE;
1843 #endif
1844 #endif
1845
1846 #ifdef CONFIG_CTRL_TXSS_BY_TP
1847 pmlmeext->txss_ctrl_en = _TRUE;
1848 pmlmeext->txss_tp_th = TXSS_TP_TH;
1849 pmlmeext->txss_tp_chk_cnt = TXSS_TP_CHK_CNT;
1850 #endif
1851
1852 return res;
1853
1854 }
1855
free_mlme_ext_priv(struct mlme_ext_priv * pmlmeext)1856 void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext)
1857 {
1858 _adapter *padapter = pmlmeext->padapter;
1859
1860 if (!padapter)
1861 return;
1862
1863 if (rtw_is_drv_stopped(padapter)) {
1864 _cancel_timer_ex(&pmlmeext->survey_timer);
1865 _cancel_timer_ex(&pmlmeext->link_timer);
1866 #ifdef CONFIG_DFS
1867 _cancel_timer_ex(&pmlmeext->csa_timer);
1868 #endif /* CONFIG_DFS */
1869 }
1870 }
1871
1872 #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
cmp_pkt_chnl_diff(_adapter * padapter,u8 * pframe,uint packet_len)1873 static u8 cmp_pkt_chnl_diff(_adapter *padapter, u8 *pframe, uint packet_len)
1874 {
1875 /* if the channel is same, return 0. else return channel differential */
1876 uint len;
1877 u8 channel;
1878 u8 *p;
1879
1880 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);
1881 if (p) {
1882 channel = *(p + 2);
1883 if (padapter->mlmeextpriv.cur_channel >= channel)
1884 return padapter->mlmeextpriv.cur_channel - channel;
1885 else
1886 return channel - padapter->mlmeextpriv.cur_channel;
1887 } else
1888 return 0;
1889 }
1890 #endif /* CONFIG_PATCH_JOIN_WRONG_CHANNEL */
1891
_mgt_dispatcher(_adapter * padapter,struct mlme_handler * ptable,union recv_frame * precv_frame)1892 static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
1893 {
1894 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1895 u8 *pframe = precv_frame->u.hdr.rx_data;
1896
1897 if (ptable->func) {
1898 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
1899 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1900 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1901 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
1902 {
1903 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
1904
1905 if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) != _TRUE)
1906 return;
1907
1908 if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE)
1909 return;
1910
1911 if ( pwdev_priv->pno_mac_addr[0] == 0xFF)
1912 return;
1913
1914 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_pno_mac_addr(padapter), ETH_ALEN))
1915 return;
1916 }
1917 #else
1918 return;
1919 #endif
1920
1921 ptable->func(padapter, precv_frame);
1922 }
1923
1924 }
1925
mgt_dispatcher(_adapter * padapter,union recv_frame * precv_frame)1926 void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
1927 {
1928 int index;
1929 struct mlme_handler *ptable;
1930 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1931 u8 *pframe = precv_frame->u.hdr.rx_data;
1932 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, get_addr2_ptr(pframe));
1933 struct recv_priv *precvpriv = &padapter->recvpriv;
1934
1935
1936 #if 0
1937 {
1938 u8 *pbuf;
1939 pbuf = GetAddr1Ptr(pframe);
1940 RTW_INFO("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf + 1), *(pbuf + 2), *(pbuf + 3), *(pbuf + 4), *(pbuf + 5));
1941 pbuf = get_addr2_ptr(pframe);
1942 RTW_INFO("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf + 1), *(pbuf + 2), *(pbuf + 3), *(pbuf + 4), *(pbuf + 5));
1943 pbuf = GetAddr3Ptr(pframe);
1944 RTW_INFO("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf + 1), *(pbuf + 2), *(pbuf + 3), *(pbuf + 4), *(pbuf + 5));
1945 }
1946 #endif
1947
1948 if (GetFrameType(pframe) != WIFI_MGT_TYPE) {
1949 return;
1950 }
1951
1952 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
1953 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1954 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1955 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
1956 {
1957 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
1958
1959 if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) != _TRUE)
1960 return;
1961
1962 if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE)
1963 return;
1964
1965 if ( pwdev_priv->pno_mac_addr[0] == 0xFF)
1966 return;
1967
1968 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_pno_mac_addr(padapter), ETH_ALEN))
1969 return;
1970 }
1971 #else
1972 return;
1973 #endif
1974
1975 ptable = mlme_sta_tbl;
1976
1977 index = get_frame_sub_type(pframe) >> 4;
1978
1979 #ifdef CONFIG_TDLS
1980 if ((index << 4) == WIFI_ACTION) {
1981 /* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
1982 if (*(pframe + 24) == RTW_WLAN_CATEGORY_PUBLIC && *(pframe + 25) == TDLS_DISCOVERY_RESPONSE) {
1983 RTW_INFO("[TDLS] Recv %s from "MAC_FMT"\n", rtw_tdls_action_txt(TDLS_DISCOVERY_RESPONSE), MAC_ARG(get_addr2_ptr(pframe)));
1984 On_TDLS_Dis_Rsp(padapter, precv_frame);
1985 }
1986 }
1987 #endif /* CONFIG_TDLS */
1988
1989 if (index >= (sizeof(mlme_sta_tbl) / sizeof(struct mlme_handler))) {
1990 return;
1991 }
1992 ptable += index;
1993
1994 #if 1
1995 if (psta != NULL) {
1996 if (GetRetry(pframe)) {
1997 if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum) {
1998 /* drop the duplicate management frame */
1999 precvpriv->dbg_rx_dup_mgt_frame_drop_count++;
2000 RTW_INFO("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
2001 return;
2002 }
2003 }
2004 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
2005 }
2006 #else
2007
2008 if (GetRetry(pframe)) {
2009 /* return; */
2010 }
2011 #endif
2012
2013 #ifdef CONFIG_AP_MODE
2014 switch (get_frame_sub_type(pframe)) {
2015 case WIFI_AUTH:
2016 if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter))
2017 ptable->func = &OnAuth;
2018 else
2019 ptable->func = &OnAuthClient;
2020 fallthrough;
2021 /* fall through */
2022 case WIFI_ASSOCREQ:
2023 case WIFI_REASSOCREQ:
2024 _mgt_dispatcher(padapter, ptable, precv_frame);
2025 #ifdef CONFIG_HOSTAPD_MLME
2026 if (MLME_IS_AP(padapter))
2027 rtw_hostapd_mlme_rx(padapter, precv_frame);
2028 #endif
2029 break;
2030 case WIFI_PROBEREQ:
2031 _mgt_dispatcher(padapter, ptable, precv_frame);
2032 #ifdef CONFIG_HOSTAPD_MLME
2033 if (MLME_IS_AP(padapter))
2034 rtw_hostapd_mlme_rx(padapter, precv_frame);
2035 #endif
2036 break;
2037 case WIFI_BEACON:
2038 _mgt_dispatcher(padapter, ptable, precv_frame);
2039 break;
2040 case WIFI_ACTION:
2041 _mgt_dispatcher(padapter, ptable, precv_frame);
2042 break;
2043 default:
2044 _mgt_dispatcher(padapter, ptable, precv_frame);
2045 #ifdef CONFIG_HOSTAPD_MLME
2046 if (MLME_IS_AP(padapter))
2047 rtw_hostapd_mlme_rx(padapter, precv_frame);
2048 #endif
2049 break;
2050 }
2051 #else
2052
2053 _mgt_dispatcher(padapter, ptable, precv_frame);
2054
2055 #endif
2056
2057 }
2058
2059 #ifdef CONFIG_P2P
p2p_listen_state_process(_adapter * padapter,unsigned char * da)2060 u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
2061 {
2062 bool response = _TRUE;
2063
2064 #ifdef CONFIG_IOCTL_CFG80211
2065 if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
2066 if (rtw_cfg80211_get_is_roch(padapter) == _FALSE
2067 || rtw_get_oper_ch(padapter) != padapter->wdinfo.listen_channel
2068 || adapter_wdev_data(padapter)->p2p_enabled == _FALSE
2069 || padapter->mlmepriv.wps_probe_resp_ie == NULL
2070 || padapter->mlmepriv.p2p_probe_resp_ie == NULL
2071 ) {
2072 #ifdef CONFIG_DEBUG_CFG80211
2073 RTW_INFO(ADPT_FMT" DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n"
2074 , ADPT_ARG(padapter)
2075 , adapter_wdev_data(padapter)->p2p_enabled
2076 , padapter->mlmepriv.wps_probe_resp_ie
2077 , padapter->mlmepriv.p2p_probe_resp_ie);
2078 RTW_INFO(ADPT_FMT" DON'T issue_probersp_p2p: is_ro_ch:%d, op_ch:%d, p2p_listen_channel:%d\n"
2079 , ADPT_ARG(padapter)
2080 , rtw_cfg80211_get_is_roch(padapter)
2081 , rtw_get_oper_ch(padapter)
2082 , padapter->wdinfo.listen_channel);
2083 #endif
2084 response = _FALSE;
2085 }
2086 } else
2087 #endif /* CONFIG_IOCTL_CFG80211 */
2088 if (padapter->wdinfo.driver_interface == DRIVER_WEXT) {
2089 /* do nothing if the device name is empty */
2090 if (!padapter->wdinfo.device_name_len)
2091 response = _FALSE;
2092 }
2093
2094 if (response == _TRUE)
2095 issue_probersp_p2p(padapter, da);
2096
2097 return _SUCCESS;
2098 }
2099 #endif /* CONFIG_P2P */
2100
2101
2102 /****************************************************************************
2103
2104 Following are the callback functions for each subtype of the management frames
2105
2106 *****************************************************************************/
2107
OnProbeReq(_adapter * padapter,union recv_frame * precv_frame)2108 unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
2109 {
2110 unsigned int ielen;
2111 unsigned char *p;
2112 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2113 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2114 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2115 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
2116 u8 *pframe = precv_frame->u.hdr.rx_data;
2117 uint len = precv_frame->u.hdr.len;
2118 u8 is_valid_p2p_probereq = _FALSE;
2119
2120 #ifdef CONFIG_ATMEL_RC_PATCH
2121 u8 *target_ie = NULL, *wps_ie = NULL;
2122 u8 *start;
2123 uint search_len = 0, wps_ielen = 0, target_ielen = 0;
2124 struct sta_info *psta;
2125 struct sta_priv *pstapriv = &padapter->stapriv;
2126 #endif
2127
2128 #ifdef CONFIG_P2P
2129 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
2130 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
2131 u8 wifi_test_chk_rate = 1;
2132
2133 #ifdef CONFIG_IOCTL_CFG80211
2134 #ifdef CONFIG_P2P
2135 if ((adapter_to_dvobj(padapter)->wpas_type == RTW_WPAS_W1FI) &&
2136 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
2137 (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter),
2138 IEEE80211_STYPE_PROBE_REQ) == _TRUE)) {
2139 rtw_cfg80211_rx_probe_request(padapter, precv_frame);
2140 return _SUCCESS;
2141 }
2142 #endif
2143 #endif /* CONFIG_IOCTL_CFG80211 */
2144
2145 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
2146 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
2147 !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
2148 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
2149 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
2150 ) {
2151 /* Commented by Albert 2011/03/17 */
2152 /* mcs_rate = 0->CCK 1M rate */
2153 /* mcs_rate = 1->CCK 2M rate */
2154 /* mcs_rate = 2->CCK 5.5M rate */
2155 /* mcs_rate = 3->CCK 11M rate */
2156 /* In the P2P mode, the driver should not support the CCK rate */
2157
2158 /* Commented by Kurt 2012/10/16 */
2159 /* IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client */
2160 if (padapter->registrypriv.wifi_spec == 1) {
2161 if (pattrib->data_rate <= DESC_RATE11M)
2162 wifi_test_chk_rate = 0;
2163 }
2164
2165 if (wifi_test_chk_rate == 1) {
2166 is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len);
2167 if (is_valid_p2p_probereq == _TRUE) {
2168 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
2169 /* FIXME */
2170 if (padapter->wdinfo.driver_interface == DRIVER_WEXT)
2171 report_survey_event(padapter, precv_frame);
2172
2173 p2p_listen_state_process(padapter, get_sa(pframe));
2174
2175 return _SUCCESS;
2176 }
2177
2178 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2179 goto _continue;
2180 }
2181 }
2182 }
2183
2184 _continue:
2185 #endif /* CONFIG_P2P */
2186
2187 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
2188 return _SUCCESS;
2189
2190 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE &&
2191 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE | WIFI_MESH_STATE) == _FALSE)
2192 return _SUCCESS;
2193
2194
2195 /* RTW_INFO("+OnProbeReq\n"); */
2196
2197
2198 #ifdef CONFIG_ATMEL_RC_PATCH
2199 wps_ie = rtw_get_wps_ie(
2200 pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_,
2201 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_,
2202 NULL, &wps_ielen);
2203 if (wps_ie)
2204 target_ie = rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_MANUFACTURER, NULL, &target_ielen);
2205 if ((target_ie && (target_ielen == 4)) && (_TRUE == _rtw_memcmp((void *)target_ie, "Ozmo", 4))) {
2206 /* psta->flag_atmel_rc = 1; */
2207 unsigned char *sa_addr = get_sa(pframe);
2208 printk("%s: Find Ozmo RC -- %02x:%02x:%02x:%02x:%02x:%02x \n\n",
2209 __func__, *sa_addr, *(sa_addr + 1), *(sa_addr + 2), *(sa_addr + 3), *(sa_addr + 4), *(sa_addr + 5));
2210 _rtw_memcpy(pstapriv->atmel_rc_pattern, get_sa(pframe), ETH_ALEN);
2211 }
2212 #endif
2213
2214
2215 #ifdef CONFIG_AUTO_AP_MODE
2216 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE &&
2217 pmlmepriv->cur_network.join_res == _TRUE) {
2218 _irqL irqL;
2219 struct sta_info *psta;
2220 u8 *mac_addr, *peer_addr;
2221 struct sta_priv *pstapriv = &padapter->stapriv;
2222 u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A};
2223 /* EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] */
2224
2225 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
2226 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
2227
2228 if (!p || ielen != 14)
2229 goto _non_rc_device;
2230
2231 if (!_rtw_memcmp(p + 2, RC_OUI, sizeof(RC_OUI)))
2232 goto _non_rc_device;
2233
2234 if (!_rtw_memcmp(p + 6, get_sa(pframe), ETH_ALEN)) {
2235 RTW_INFO("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
2236 MAC_ARG(get_sa(pframe)), MAC_ARG(p + 6));
2237
2238 goto _non_rc_device;
2239 }
2240
2241 RTW_INFO("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__, MAC_ARG(get_sa(pframe)));
2242
2243 /* new a station */
2244 psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
2245 if (psta == NULL) {
2246 /* allocate a new one */
2247 RTW_INFO("going to alloc stainfo for rc="MAC_FMT"\n", MAC_ARG(get_sa(pframe)));
2248 psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
2249 if (psta == NULL) {
2250 /* TODO: */
2251 RTW_INFO(" Exceed the upper limit of supported clients...\n");
2252 return _SUCCESS;
2253 }
2254
2255 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2256 if (rtw_is_list_empty(&psta->asoc_list)) {
2257 psta->expire_to = pstapriv->expire_to;
2258 rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
2259 pstapriv->asoc_list_cnt++;
2260 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
2261 if (psta->tbtx_enable)
2262 pstapriv->tbtx_asoc_list_cnt++;
2263 #endif
2264 }
2265 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2266
2267 /* generate pairing ID */
2268 mac_addr = adapter_mac_addr(padapter);
2269 peer_addr = psta->cmn.mac_addr;
2270 psta->pid = (u16)(((mac_addr[4] << 8) + mac_addr[5]) + ((peer_addr[4] << 8) + peer_addr[5]));
2271
2272 /* update peer stainfo */
2273 psta->isrc = _TRUE;
2274
2275 /* AID assignment */
2276 if (psta->cmn.aid > 0)
2277 RTW_INFO(FUNC_ADPT_FMT" old AID=%d\n", FUNC_ADPT_ARG(padapter), psta->cmn.aid);
2278 else {
2279 if (!rtw_aid_alloc(padapter, psta)) {
2280 RTW_INFO(FUNC_ADPT_FMT" no room for more AIDs\n", FUNC_ADPT_ARG(padapter));
2281 return _SUCCESS;
2282 }
2283 RTW_INFO(FUNC_ADPT_FMT" allocate new AID=%d\n", FUNC_ADPT_ARG(padapter), psta->cmn.aid);
2284 }
2285
2286 psta->qos_option = 1;
2287 psta->cmn.bw_mode = CHANNEL_WIDTH_20;
2288 psta->ieee8021x_blocked = _FALSE;
2289 #ifdef CONFIG_80211N_HT
2290 if(padapter->registrypriv.ht_enable &&
2291 is_supported_ht(padapter->registrypriv.wireless_mode)) {
2292 psta->htpriv.ht_option = _TRUE;
2293 psta->htpriv.ampdu_enable = _FALSE;
2294 psta->htpriv.sgi_20m = _FALSE;
2295 psta->htpriv.sgi_40m = _FALSE;
2296 psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2297 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
2298 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
2299 }
2300 #endif
2301
2302 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
2303
2304 _rtw_memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
2305
2306 _enter_critical_bh(&psta->lock, &irqL);
2307 psta->state |= WIFI_ASOC_STATE;
2308 _exit_critical_bh(&psta->lock, &irqL);
2309
2310 report_add_sta_event(padapter, psta->cmn.mac_addr);
2311
2312 }
2313
2314 issue_probersp(padapter, get_sa(pframe), _FALSE);
2315
2316 return _SUCCESS;
2317
2318 }
2319
2320 _non_rc_device:
2321
2322 return _SUCCESS;
2323
2324 #endif /* CONFIG_AUTO_AP_MODE */
2325
2326
2327 #ifdef CONFIG_CONCURRENT_MODE
2328 if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) &&
2329 rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING | WIFI_UNDER_SURVEY)) {
2330 /* don't process probe req */
2331 return _SUCCESS;
2332 }
2333 #endif
2334
2335 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
2336 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
2337
2338
2339 /* check (wildcard) SSID */
2340 if (p != NULL) {
2341 if (is_valid_p2p_probereq == _TRUE)
2342 goto _issue_probersp;
2343
2344 if ((ielen != 0 && _FALSE == _rtw_memcmp((void *)(p + 2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
2345 || (ielen == 0 && pmlmeinfo->hidden_ssid_mode))
2346 goto exit;
2347
2348 #ifdef CONFIG_RTW_MESH
2349 if (MLME_IS_MESH(padapter)) {
2350 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, WLAN_EID_MESH_ID, (int *)&ielen,
2351 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
2352
2353 if (!p)
2354 goto exit;
2355 if (ielen != 0 && _rtw_memcmp((void *)(p + 2), (void *)cur->mesh_id.Ssid, cur->mesh_id.SsidLength) == _FALSE)
2356 goto exit;
2357 }
2358 #endif
2359
2360 _issue_probersp:
2361 if (((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE &&
2362 pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
2363 /* RTW_INFO("+issue_probersp during ap mode\n"); */
2364 issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
2365 }
2366
2367 }
2368
2369 exit:
2370 return _SUCCESS;
2371
2372 }
2373
OnProbeRsp(_adapter * padapter,union recv_frame * precv_frame)2374 unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
2375 {
2376 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2377 u8 *pframe = precv_frame->u.hdr.rx_data;
2378 #ifdef CONFIG_P2P
2379 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2380 #endif
2381
2382
2383 #ifdef CONFIG_P2P
2384 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
2385 if (_TRUE == pwdinfo->tx_prov_disc_info.benable) {
2386 if (_rtw_memcmp(pwdinfo->tx_prov_disc_info.peerIFAddr, get_addr2_ptr(pframe), ETH_ALEN)) {
2387 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
2388 pwdinfo->tx_prov_disc_info.benable = _FALSE;
2389 issue_p2p_provision_request(padapter,
2390 pwdinfo->tx_prov_disc_info.ssid.Ssid,
2391 pwdinfo->tx_prov_disc_info.ssid.SsidLength,
2392 pwdinfo->tx_prov_disc_info.peerDevAddr);
2393 } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
2394 pwdinfo->tx_prov_disc_info.benable = _FALSE;
2395 issue_p2p_provision_request(padapter,
2396 NULL,
2397 0,
2398 pwdinfo->tx_prov_disc_info.peerDevAddr);
2399 }
2400 }
2401 }
2402 return _SUCCESS;
2403 } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
2404 if (_TRUE == pwdinfo->nego_req_info.benable) {
2405 RTW_INFO("[%s] P2P State is GONEGO ING!\n", __FUNCTION__);
2406 if (_rtw_memcmp(pwdinfo->nego_req_info.peerDevAddr, get_addr2_ptr(pframe), ETH_ALEN)) {
2407 pwdinfo->nego_req_info.benable = _FALSE;
2408 issue_p2p_GO_request(padapter, pwdinfo->nego_req_info.peerDevAddr);
2409 }
2410 }
2411 } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) {
2412 if (_TRUE == pwdinfo->invitereq_info.benable) {
2413 RTW_INFO("[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__);
2414 if (_rtw_memcmp(pwdinfo->invitereq_info.peer_macaddr, get_addr2_ptr(pframe), ETH_ALEN)) {
2415 pwdinfo->invitereq_info.benable = _FALSE;
2416 issue_p2p_invitation_request(padapter, pwdinfo->invitereq_info.peer_macaddr);
2417 }
2418 }
2419 }
2420 #endif
2421
2422
2423 if ((mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
2424 || (MLME_IS_MESH(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE))
2425 #ifdef CONFIG_RTW_REPEATER_SON
2426 || (padapter->rtw_rson_scanstage == RSON_SCAN_PROCESS)
2427 #endif
2428 ) {
2429 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2430
2431 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)
2432 && (pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2433 ) {
2434 if (!rtw_check_bcn_info(padapter, pframe, precv_frame->u.hdr.len)) {
2435 RTW_PRINT(FUNC_ADPT_FMT" ap has changed, disconnect now\n", FUNC_ADPT_ARG(padapter));
2436 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0, _FALSE);
2437 }
2438 }
2439
2440 rtw_mi_report_survey_event(padapter, precv_frame);
2441 return _SUCCESS;
2442 }
2443
2444 #if 0 /* move to validate_recv_mgnt_frame */
2445 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) {
2446 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
2447 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
2448 if (psta != NULL)
2449 psta->sta_stats.rx_mgnt_pkts++;
2450 }
2451 }
2452 #endif
2453
2454 return _SUCCESS;
2455
2456 }
2457
2458 /* for 11n Logo 4.2.31/4.2.32 */
2459 #ifdef CONFIG_AP_MODE
rtw_check_legacy_ap(_adapter * padapter,u8 * pframe,u32 len)2460 static void rtw_check_legacy_ap(_adapter *padapter, u8 *pframe, u32 len)
2461 {
2462 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2463 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2464
2465 if (!padapter->registrypriv.wifi_spec)
2466 return;
2467
2468 if(!MLME_IS_AP(padapter))
2469 return;
2470
2471 if (pmlmeext->bstart_bss == _TRUE) {
2472 int left;
2473 unsigned char *pos;
2474 struct rtw_ieee802_11_elems elems;
2475 #ifdef CONFIG_80211N_HT
2476 u16 cur_op_mode;
2477 #endif
2478 /* checking IEs */
2479 left = len - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_;
2480 pos = pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_;
2481 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) {
2482 RTW_INFO("%s: parse fail for "MAC_FMT"\n", __func__, MAC_ARG(GetAddr3Ptr(pframe)));
2483 return;
2484 }
2485 #ifdef CONFIG_80211N_HT
2486 cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
2487 #endif
2488 /* for legacy ap */
2489 if (elems.ht_capabilities == NULL && elems.ht_capabilities_len == 0) {
2490
2491 if (0)
2492 RTW_INFO("%s: "MAC_FMT" is legacy ap\n", __func__, MAC_ARG(GetAddr3Ptr(pframe)));
2493
2494 ATOMIC_SET(&pmlmepriv->olbc, _TRUE);
2495 ATOMIC_SET(&pmlmepriv->olbc_ht, _TRUE);
2496 }
2497 }
2498 }
2499 #endif /* CONFIG_AP_MODE */
2500
OnBeacon(_adapter * padapter,union recv_frame * precv_frame)2501 unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
2502 {
2503 struct sta_info *psta;
2504 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2505 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2506 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2507 struct sta_priv *pstapriv = &padapter->stapriv;
2508 u8 *pframe = precv_frame->u.hdr.rx_data;
2509 uint len = precv_frame->u.hdr.len;
2510 WLAN_BSSID_EX *pbss;
2511 int ret = _SUCCESS;
2512 #ifdef CONFIG_TDLS
2513 struct sta_info *ptdls_sta;
2514 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
2515 #ifdef CONFIG_TDLS_CH_SW
2516 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
2517 #endif
2518 #endif /* CONFIG_TDLS */
2519 #ifdef CONFIG_LAYER2_ROAMING
2520 _irqL irqL;
2521 #endif
2522
2523 if (validate_beacon_len(pframe, len) == _FALSE)
2524 return _SUCCESS;
2525
2526 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)
2527 || (MLME_IS_MESH(padapter) && check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
2528 ) {
2529 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)
2530 && (pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2531 ) {
2532 if (!rtw_check_bcn_info(padapter, pframe, len)) {
2533 RTW_PRINT(FUNC_ADPT_FMT" ap has changed, disconnect now\n", FUNC_ADPT_ARG(padapter));
2534 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0, _FALSE);
2535 }
2536 }
2537
2538 rtw_mi_report_survey_event(padapter, precv_frame);
2539 return _SUCCESS;
2540 }
2541
2542 #ifdef CONFIG_WRITE_BCN_LEN_TO_FW
2543 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
2544 && (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) {
2545 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
2546
2547 if (pmlmeinfo->last_bcn_len != pattrib->pkt_len) {
2548 pmlmeinfo->last_bcn_len = pattrib->pkt_len;
2549 rtw_write_bcnlen_to_fw_cmd(padapter, pattrib->pkt_len);
2550 }
2551 }
2552 #endif
2553
2554 #ifdef CONFIG_RTW_REPEATER_SON
2555 if (padapter->rtw_rson_scanstage == RSON_SCAN_PROCESS)
2556 rtw_mi_report_survey_event(padapter, precv_frame);
2557 #endif
2558
2559 #ifdef CONFIG_AP_MODE
2560 rtw_check_legacy_ap(padapter, pframe, len);
2561 #endif
2562
2563 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) {
2564 if ((pmlmeinfo->state & WIFI_FW_AUTH_NULL)
2565 && (rtw_sta_linking_test_wait_done() || pmlmeext->join_abort)
2566 ) {
2567 if (rtw_sta_linking_test_force_fail() || pmlmeext->join_abort) {
2568 set_link_timer(pmlmeext, 1);
2569 return _SUCCESS;
2570 }
2571 #ifdef CONFIG_LAYER2_ROAMING
2572 _enter_critical_bh(&pmlmepriv->clnt_auth_lock, &irqL);
2573 #endif
2574 /* we should update current network before auth, or some IE is wrong */
2575 pbss = (WLAN_BSSID_EX *)rtw_malloc(sizeof(WLAN_BSSID_EX));
2576 if (pbss) {
2577 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
2578 struct beacon_keys recv_beacon;
2579
2580 update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
2581
2582 /* update bcn keys */
2583 if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
2584 RTW_INFO("%s: beacon keys ready\n", __func__);
2585 _rtw_memcpy(&pmlmepriv->cur_beacon_keys,
2586 &recv_beacon, sizeof(recv_beacon));
2587 if (is_hidden_ssid(recv_beacon.ssid, recv_beacon.ssid_len)) {
2588 _rtw_memcpy(pmlmepriv->cur_beacon_keys.ssid, pmlmeinfo->network.Ssid.Ssid, IW_ESSID_MAX_SIZE);
2589 pmlmepriv->cur_beacon_keys.ssid_len = pmlmeinfo->network.Ssid.SsidLength;
2590 }
2591 } else {
2592 RTW_ERR("%s: get beacon keys failed\n", __func__);
2593 _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon));
2594 }
2595 #ifdef CONFIG_BCN_CNT_CONFIRM_HDL
2596 pmlmepriv->new_beacon_cnts = 0;
2597 #endif
2598 }
2599 rtw_mfree((u8 *)pbss, sizeof(WLAN_BSSID_EX));
2600 }
2601
2602 /* check the vendor of the assoc AP */
2603 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct rtw_ieee80211_hdr_3addr), len - sizeof(struct rtw_ieee80211_hdr_3addr));
2604
2605 rtw_phydm_update_ap_vendor_ie(padapter);
2606
2607 /* update TSF Value */
2608 update_TSF(pmlmeext, pframe, len);
2609 pmlmeext->bcn_cnt = 0;
2610 pmlmeext->last_bcn_cnt = 0;
2611
2612 #ifdef CONFIG_P2P_PS
2613 /* Comment by YiWei , in wifi p2p spec the "3.3 P2P Power Management" , "These mechanisms are available in a P2P Group in which only P2P Devices are associated." */
2614 /* process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)); */
2615 #endif /* CONFIG_P2P_PS */
2616
2617 #if defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)
2618 if (padapter->registrypriv.wifi_spec) {
2619 if (process_p2p_cross_connect_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)) == _FALSE) {
2620 if (rtw_mi_buddy_check_mlmeinfo_state(padapter, WIFI_FW_AP_STATE)) {
2621 RTW_PRINT("no issue auth, P2P cross-connect does not permit\n ");
2622 return _SUCCESS;
2623 }
2624 }
2625 }
2626 #endif /* CONFIG_P2P CONFIG_P2P and CONFIG_CONCURRENT_MODE */
2627
2628 /* start auth */
2629 start_clnt_auth(padapter);
2630 #ifdef CONFIG_LAYER2_ROAMING
2631 _exit_critical_bh(&pmlmepriv->clnt_auth_lock, &irqL);
2632 #endif
2633 return _SUCCESS;
2634 }
2635
2636 if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
2637 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
2638 if (psta != NULL) {
2639 #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
2640 /* Merge from 8712 FW code */
2641 if (cmp_pkt_chnl_diff(padapter, pframe, len) != 0) {
2642 /* join wrong channel, deauth and reconnect */
2643 issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
2644
2645 report_del_sta_event(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL, _TRUE, _FALSE);
2646 pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
2647 return _SUCCESS;
2648 }
2649 #endif /* CONFIG_PATCH_JOIN_WRONG_CHANNEL */
2650 #ifdef CONFIG_RTW_80211R
2651 rtw_ft_update_bcn(padapter, precv_frame);
2652 #endif
2653 ret = rtw_check_bcn_info(padapter, pframe, len);
2654 if (!ret) {
2655 RTW_PRINT(FUNC_ADPT_FMT" ap has changed, disconnect now\n", FUNC_ADPT_ARG(padapter));
2656 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0, _FALSE);
2657 return _SUCCESS;
2658 }
2659 /* update WMM, ERP in the beacon */
2660 /* todo: the timer is used instead of the number of the beacon received */
2661 if ((sta_rx_pkts(psta) & 0xf) == 0) {
2662 /* RTW_INFO("update_bcn_info\n"); */
2663 update_beacon_info(padapter, pframe, len, psta);
2664 }
2665
2666 pmlmepriv->cur_network_scanned->network.Rssi = precv_frame->u.hdr.attrib.phy_info.recv_signal_power;
2667 pmlmeext->bcn_cnt++;
2668 #ifdef CONFIG_BCN_RECV_TIME
2669 rtw_rx_bcn_time_update(padapter, len, precv_frame->u.hdr.attrib.data_rate);
2670 #endif
2671 #ifdef CONFIG_TDLS
2672 #ifdef CONFIG_TDLS_CH_SW
2673 if (rtw_tdls_is_chsw_allowed(padapter) == _TRUE) {
2674 /* Send TDLS Channel Switch Request when receiving Beacon */
2675 if ((padapter->tdlsinfo.chsw_info.ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) && (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE)
2676 && (pmlmeext->cur_channel == rtw_get_oper_ch(padapter))) {
2677 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, padapter->tdlsinfo.chsw_info.addr);
2678 if (ptdls_sta != NULL) {
2679 if (ptdls_sta->tdls_sta_state | TDLS_LINKED_STATE)
2680 _set_timer(&ptdls_sta->stay_on_base_chnl_timer, TDLS_CH_SW_STAY_ON_BASE_CHNL_TIMEOUT);
2681 }
2682 }
2683 }
2684 #endif
2685 #endif /* CONFIG_TDLS */
2686
2687 #if CONFIG_DFS
2688 process_csa_ie(padapter
2689 , pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_
2690 , len - (WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_));
2691 #endif
2692
2693 #ifdef CONFIG_80211D
2694 process_country_ie(padapter
2695 , pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_
2696 , len - (WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_));
2697 #endif
2698
2699 #ifdef CONFIG_P2P_PS
2700 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
2701 #endif /* CONFIG_P2P_PS */
2702
2703 if (pmlmeext->tsf_update_required && pmlmeext->en_hw_update_tsf)
2704 rtw_enable_hw_update_tsf_cmd(padapter);
2705
2706 #if 0 /* move to validate_recv_mgnt_frame */
2707 psta->sta_stats.rx_mgnt_pkts++;
2708 #endif
2709 }
2710
2711 } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
2712 u8 rate_set[16];
2713 u8 rate_num = 0;
2714
2715 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
2716 if (psta != NULL) {
2717 /*
2718 * update WMM, ERP in the beacon
2719 * todo: the timer is used instead of the number of the beacon received
2720 */
2721 if ((sta_rx_pkts(psta) & 0xf) == 0)
2722 update_beacon_info(padapter, pframe, len, psta);
2723
2724 if (pmlmeext->tsf_update_required && pmlmeext->en_hw_update_tsf)
2725 rtw_enable_hw_update_tsf_cmd(padapter);
2726 } else {
2727 rtw_ies_get_supported_rate(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_, rate_set, &rate_num);
2728 if (rate_num == 0) {
2729 RTW_INFO(FUNC_ADPT_FMT" RX beacon with no supported rate\n", FUNC_ADPT_ARG(padapter));
2730 goto _END_ONBEACON_;
2731 }
2732
2733 psta = rtw_alloc_stainfo(pstapriv, get_addr2_ptr(pframe));
2734 if (psta == NULL) {
2735 RTW_INFO(FUNC_ADPT_FMT" Exceed the upper limit of supported clients\n", FUNC_ADPT_ARG(padapter));
2736 goto _END_ONBEACON_;
2737 }
2738
2739 psta->expire_to = pstapriv->adhoc_expire_to;
2740
2741 _rtw_memcpy(psta->bssrateset, rate_set, rate_num);
2742 psta->bssratelen = rate_num;
2743
2744 /* update TSF Value */
2745 update_TSF(pmlmeext, pframe, len);
2746
2747 /* report sta add event */
2748 report_add_sta_event(padapter, get_addr2_ptr(pframe));
2749 }
2750 }
2751 }
2752
2753 _END_ONBEACON_:
2754
2755 return _SUCCESS;
2756
2757 }
2758
2759 #ifdef CONFIG_AP_MODE
rtw_get_sta_num_by_state(_adapter * padapter,u32 state)2760 static u32 rtw_get_sta_num_by_state(_adapter *padapter, u32 state)
2761 {
2762 _irqL irqL;
2763 _list *plist, *phead;
2764 u32 index, sta_num = 0;
2765 struct sta_info *psta = NULL;
2766 struct sta_priv *pstapriv = &(padapter->stapriv);
2767
2768 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
2769 for (index = 0; index < NUM_STA; index++) {
2770 phead = &(pstapriv->sta_hash[index]);
2771 plist = get_next(phead);
2772 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
2773 psta = LIST_CONTAINOR(plist, struct sta_info , hash_list);
2774 if ((psta->state & (state)))
2775 sta_num++;
2776 plist = get_next(plist);
2777 }
2778 }
2779 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
2780
2781 /* RTW_INFO("%s : waiting for %u sta under linking \n", __func__, sta_num); */
2782 return sta_num;
2783 }
2784
rtw_defs_attack_chk(_adapter * padapter)2785 static u8 rtw_defs_attack_chk(_adapter *padapter)
2786 {
2787 struct mlme_priv *mlme = &(padapter->mlmepriv);
2788 u8 is_reject = _FALSE;
2789 u32 sta_limit = 0;
2790 u32 stime = rtw_systime_to_ms(rtw_get_current_time());
2791 static u32 ptime = 0;
2792
2793 /* RTW_INFO("%s : ptime=%u, stime=%u, diff=%u\n", __func__, ptime, stime, (stime - ptime)); */
2794 if ((ptime > 0) && ((stime - ptime) < mlme->defs_lmt_time)) {
2795 sta_limit = rtw_get_sta_num_by_state(padapter, WIFI_FW_LINKING_STATE);
2796 if (sta_limit >= mlme->defs_lmt_sta)
2797 is_reject = _TRUE;
2798 }
2799
2800 ptime = stime;
2801 /* RTW_INFO("%s : current linking num=%u\n", __func__, sta_limit); */
2802 return is_reject;
2803 }
2804 #endif
2805
OnAuth(_adapter * padapter,union recv_frame * precv_frame)2806 unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
2807 {
2808 #ifdef CONFIG_AP_MODE
2809 _irqL irqL;
2810 unsigned int auth_mode, seq, ie_len;
2811 unsigned char *sa, *p;
2812 u16 algorithm;
2813 int status;
2814 static struct sta_info stat;
2815 struct sta_info *pstat = NULL;
2816 struct sta_priv *pstapriv = &padapter->stapriv;
2817 struct security_priv *psecuritypriv = &padapter->securitypriv;
2818 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2819 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2820 u8 *pframe = precv_frame->u.hdr.rx_data;
2821 uint len = precv_frame->u.hdr.len;
2822 u8 offset = 0;
2823
2824
2825 #ifdef CONFIG_CONCURRENT_MODE
2826 if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) &&
2827 rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING | WIFI_UNDER_SURVEY)) {
2828 /* don't process auth request; */
2829 return _SUCCESS;
2830 }
2831 #endif /* CONFIG_CONCURRENT_MODE */
2832
2833 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
2834 return _FAIL;
2835
2836 if (!MLME_IS_ASOC(padapter))
2837 return _SUCCESS;
2838
2839 #if defined(CONFIG_IOCTL_CFG80211) && defined(CONFIG_RTW_MESH)
2840 if (MLME_IS_MESH(padapter))
2841 return rtw_mesh_on_auth(padapter, precv_frame);
2842 #endif
2843
2844 RTW_INFO("+OnAuth from "MAC_FMT"\n", MAC_ARG(get_addr2_ptr(pframe)));
2845
2846 sa = get_addr2_ptr(pframe);
2847
2848 auth_mode = psecuritypriv->dot11AuthAlgrthm;
2849
2850 if (GetPrivacy(pframe)) {
2851 u8 *iv;
2852 struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib);
2853
2854 prxattrib->hdrlen = WLAN_HDR_A3_LEN;
2855 prxattrib->encrypt = _WEP40_;
2856
2857 iv = pframe + prxattrib->hdrlen;
2858 prxattrib->key_index = ((iv[3] >> 6) & 0x3);
2859
2860 prxattrib->iv_len = 4;
2861 prxattrib->icv_len = 4;
2862
2863 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
2864
2865 offset = 4;
2866 }
2867
2868 algorithm = le16_to_cpu(*(u16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
2869 seq = le16_to_cpu(*(u16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
2870
2871 RTW_INFO("auth alg=%x, seq=%X\n", algorithm, seq);
2872
2873 if (rtw_check_invalid_mac_address(sa, _FALSE)){
2874 RTW_INFO("%s : reject invalid AUTH-req "MAC_FMT"\n",
2875 __func__, MAC_ARG(get_addr2_ptr(pframe)));
2876 return _FAIL;
2877 }
2878
2879 if(rtw_defs_attack_chk(padapter)) {
2880 struct sta_info *_psta;
2881 _psta = rtw_get_stainfo(pstapriv, sa);
2882 if ((_psta == NULL) || !(_psta->state & WIFI_FW_ASSOC_SUCCESS)) {
2883 status = _STATS_REFUSED_TEMPORARILY_;
2884 RTW_ERR("%s : refused temporarily for sa "MAC_FMT" !\n", __func__, MAC_ARG(sa));
2885 goto auth_fail;
2886 }
2887 }
2888
2889 if (rtw_ap_linking_test_force_auth_fail()) {
2890 status = rtw_ap_linking_test_force_auth_fail();
2891 RTW_INFO(FUNC_ADPT_FMT" force auth fail with status:%u\n"
2892 , FUNC_ADPT_ARG(padapter), status);
2893 goto auth_fail;
2894 }
2895
2896 if ((auth_mode == 2) && (algorithm != WLAN_AUTH_SAE) &&
2897 (psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) &&
2898 (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_))
2899 auth_mode = 0;
2900
2901 if ((algorithm > 0 && auth_mode == 0) || /* rx a shared-key auth but shared not enabled */
2902 (algorithm == 0 && auth_mode == 1)) { /* rx a open-system auth but shared-key is enabled */
2903 RTW_INFO("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
2904 algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
2905
2906 status = _STATS_NO_SUPP_ALG_;
2907
2908 goto auth_fail;
2909 }
2910
2911 #if CONFIG_RTW_MACADDR_ACL
2912 if (rtw_access_ctrl(padapter, sa) == _FALSE) {
2913 status = _STATS_UNABLE_HANDLE_STA_;
2914 goto auth_fail;
2915 }
2916 #endif
2917
2918 pstat = rtw_get_stainfo(pstapriv, sa);
2919 if (pstat == NULL) {
2920
2921 /* allocate a new one */
2922 RTW_INFO("going to alloc stainfo for sa="MAC_FMT"\n", MAC_ARG(sa));
2923 pstat = rtw_alloc_stainfo(pstapriv, sa);
2924 if (pstat == NULL) {
2925 RTW_INFO(" Exceed the upper limit of supported clients...\n");
2926 status = _STATS_UNABLE_HANDLE_STA_;
2927 goto auth_fail;
2928 }
2929
2930 pstat->state = WIFI_FW_AUTH_NULL;
2931 pstat->auth_seq = 0;
2932
2933 /* pstat->flags = 0; */
2934 /* pstat->capability = 0; */
2935 } else {
2936 #ifdef CONFIG_IEEE80211W
2937 if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
2938 || !(pstat->flags & WLAN_STA_MFP))
2939 #endif /* CONFIG_IEEE80211W */
2940 {
2941
2942 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2943 if (rtw_is_list_empty(&pstat->asoc_list) == _FALSE) {
2944 rtw_list_delete(&pstat->asoc_list);
2945 pstapriv->asoc_list_cnt--;
2946 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
2947 if (pstat->tbtx_enable)
2948 pstapriv->tbtx_asoc_list_cnt--;
2949 #endif
2950 if (pstat->expire_to > 0)
2951 ;/* TODO: STA re_auth within expire_to */
2952 }
2953 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2954
2955 if (seq == 1)
2956 ; /* TODO: STA re_auth and auth timeout */
2957
2958 }
2959 }
2960
2961 #ifdef CONFIG_IEEE80211W
2962 if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
2963 || !(pstat->flags & WLAN_STA_MFP))
2964 #endif /* CONFIG_IEEE80211W */
2965 {
2966 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2967 if (rtw_is_list_empty(&pstat->auth_list)) {
2968
2969 rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
2970 pstapriv->auth_list_cnt++;
2971 }
2972 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2973 }
2974
2975 if (pstat->auth_seq == 0)
2976 pstat->expire_to = pstapriv->auth_to;
2977
2978 #ifdef CONFIG_IOCTL_CFG80211
2979 if (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_AUTH) == _TRUE) {
2980 if ((algorithm == WLAN_AUTH_SAE) &&
2981 (auth_mode == dot11AuthAlgrthm_8021X)) {
2982 pstat->authalg = algorithm;
2983
2984 rtw_cfg80211_rx_mframe(padapter, precv_frame, NULL);
2985 return _SUCCESS;
2986 }
2987 }
2988 #endif /* CONFIG_IOCTL_CFG80211 */
2989
2990 if ((pstat->auth_seq + 1) != seq) {
2991 RTW_INFO("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2992 seq, pstat->auth_seq + 1);
2993 status = _STATS_OUT_OF_AUTH_SEQ_;
2994 goto auth_fail;
2995 }
2996
2997 if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3)) {
2998 if (seq == 1) {
2999 #ifdef CONFIG_IEEE80211W
3000 if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
3001 || !(pstat->flags & WLAN_STA_MFP))
3002 #endif /* CONFIG_IEEE80211W */
3003 {
3004 pstat->state &= ~WIFI_FW_AUTH_NULL;
3005 pstat->state |= WIFI_FW_AUTH_SUCCESS;
3006 pstat->expire_to = pstapriv->assoc_to;
3007 }
3008 pstat->authalg = algorithm;
3009 } else {
3010 RTW_INFO("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
3011 seq, pstat->auth_seq + 1);
3012 status = _STATS_OUT_OF_AUTH_SEQ_;
3013 goto auth_fail;
3014 }
3015 } else { /* shared system or auto authentication */
3016 if (seq == 1) {
3017 /* prepare for the challenging txt... */
3018
3019 /* get_random_bytes((void *)pstat->chg_txt, 128); */ /* TODO: */
3020 _rtw_memset((void *)pstat->chg_txt, 78, 128);
3021 #ifdef CONFIG_IEEE80211W
3022 if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
3023 || !(pstat->flags & WLAN_STA_MFP))
3024 #endif /* CONFIG_IEEE80211W */
3025 {
3026 pstat->state &= ~WIFI_FW_AUTH_NULL;
3027 pstat->state |= WIFI_FW_AUTH_STATE;
3028 }
3029 pstat->authalg = algorithm;
3030 pstat->auth_seq = 2;
3031 } else if (seq == 3) {
3032 /* checking for challenging txt... */
3033 RTW_INFO("checking for challenging txt...\n");
3034
3035 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
3036 len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
3037
3038 if ((p == NULL) || (ie_len <= 0)) {
3039 RTW_INFO("auth rejected because challenge failure!(1)\n");
3040 status = _STATS_CHALLENGE_FAIL_;
3041 goto auth_fail;
3042 }
3043
3044 if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128)) {
3045 #ifdef CONFIG_IEEE80211W
3046 if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
3047 || !(pstat->flags & WLAN_STA_MFP))
3048 #endif /* CONFIG_IEEE80211W */
3049 {
3050 pstat->state &= (~WIFI_FW_AUTH_STATE);
3051 pstat->state |= WIFI_FW_AUTH_SUCCESS;
3052 /* challenging txt is correct... */
3053 pstat->expire_to = pstapriv->assoc_to;
3054 }
3055 } else {
3056 RTW_INFO("auth rejected because challenge failure!\n");
3057 status = _STATS_CHALLENGE_FAIL_;
3058 goto auth_fail;
3059 }
3060 } else {
3061 RTW_INFO("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
3062 seq, pstat->auth_seq + 1);
3063 status = _STATS_OUT_OF_AUTH_SEQ_;
3064 goto auth_fail;
3065 }
3066 }
3067
3068
3069 /* Now, we are going to issue_auth... */
3070 pstat->auth_seq = seq + 1;
3071
3072 #ifdef CONFIG_NATIVEAP_MLME
3073 issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
3074 #endif
3075
3076 if ((pstat->state & WIFI_FW_AUTH_SUCCESS) || (pstat->state & WIFI_FW_ASSOC_SUCCESS))
3077 pstat->auth_seq = 0;
3078
3079
3080 return _SUCCESS;
3081
3082 auth_fail:
3083
3084 if (pstat)
3085 rtw_free_stainfo(padapter , pstat);
3086
3087 pstat = &stat;
3088 _rtw_memset((char *)pstat, '\0', sizeof(stat));
3089 pstat->auth_seq = 2;
3090 _rtw_memcpy(pstat->cmn.mac_addr, sa, ETH_ALEN);
3091
3092 #ifdef CONFIG_NATIVEAP_MLME
3093 issue_auth(padapter, pstat, (unsigned short)status);
3094 #endif
3095
3096 #endif /* CONFIG_AP_MODE */
3097 return _FAIL;
3098
3099 }
3100
OnAuthClient(_adapter * padapter,union recv_frame * precv_frame)3101 unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
3102 {
3103 unsigned int seq, len, status, algthm, offset;
3104 unsigned char *p;
3105 unsigned int go2asoc = 0;
3106 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3107 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3108 u8 *pframe = precv_frame->u.hdr.rx_data;
3109 uint pkt_len = precv_frame->u.hdr.len;
3110
3111 RTW_INFO("%s\n", __FUNCTION__);
3112
3113 #ifdef CONFIG_IOCTL_CFG80211
3114 if (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_AUTH) == _TRUE) {
3115 if (rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE)) {
3116 if (rtw_cached_pmkid(padapter, get_my_bssid(&pmlmeinfo->network)) != -1) {
3117 RTW_INFO("SAE: PMKSA cache entry found\n");
3118 goto normal;
3119 }
3120 rtw_cfg80211_rx_mframe(padapter, precv_frame, NULL);
3121 return _SUCCESS;
3122 }
3123 }
3124
3125 normal:
3126 #endif /* CONFIG_IOCTL_CFG80211 */
3127
3128 /* check A1 matches or not */
3129 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3130 return _SUCCESS;
3131
3132 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE) || pmlmeext->join_abort)
3133 return _SUCCESS;
3134
3135 offset = (GetPrivacy(pframe)) ? 4 : 0;
3136
3137 algthm = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
3138 seq = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
3139 status = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
3140
3141 if (status != 0) {
3142 RTW_INFO("clnt auth fail, status: %d\n", status);
3143 if (status == 13) { /* && pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
3144 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
3145 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
3146 else
3147 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
3148 /* pmlmeinfo->reauth_count = 0; */
3149 }
3150
3151 pmlmeinfo->auth_status = status;
3152 set_link_timer(pmlmeext, 1);
3153 goto authclnt_fail;
3154 }
3155
3156 if (seq == 2) {
3157 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
3158 /* legendary shared system */
3159 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
3160 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
3161
3162 if (p == NULL) {
3163 /* RTW_INFO("marc: no challenge text?\n"); */
3164 goto authclnt_fail;
3165 }
3166
3167 if (len > sizeof(pmlmeinfo->chg_txt)) {
3168 goto authclnt_fail;
3169 }
3170
3171 _rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
3172 pmlmeinfo->auth_seq = 3;
3173 issue_auth(padapter, NULL, 0);
3174 set_link_timer(pmlmeext, REAUTH_TO);
3175
3176 return _SUCCESS;
3177 } else {
3178 /* open, or 802.11r FTAA system */
3179 go2asoc = 1;
3180 }
3181 } else if (seq == 4) {
3182 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
3183 go2asoc = 1;
3184 else
3185 goto authclnt_fail;
3186 } else {
3187 /* this is also illegal */
3188 /* RTW_INFO("marc: clnt auth failed due to illegal seq=%x\n", seq); */
3189 goto authclnt_fail;
3190 }
3191
3192 if (go2asoc) {
3193 #ifdef CONFIG_RTW_80211R
3194 if (rtw_ft_update_auth_rsp_ies(padapter, pframe, pkt_len))
3195 return _SUCCESS;
3196 #endif
3197 RTW_PRINT("auth success, start assoc\n");
3198 start_clnt_assoc(padapter);
3199 return _SUCCESS;
3200 }
3201
3202 authclnt_fail:
3203
3204 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
3205
3206 return _FAIL;
3207
3208 }
3209
OnAssocReq(_adapter * padapter,union recv_frame * precv_frame)3210 unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
3211 {
3212 #ifdef CONFIG_AP_MODE
3213 _irqL irqL;
3214 u16 listen_interval;
3215 struct rtw_ieee802_11_elems elems;
3216 struct sta_info *pstat;
3217 unsigned char reassoc, *pos;
3218 int left;
3219 unsigned short status = _STATS_SUCCESSFUL_;
3220 unsigned short frame_type, ie_offset = 0;
3221 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3222 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3223 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
3224 struct sta_priv *pstapriv = &padapter->stapriv;
3225 u8 *pframe = precv_frame->u.hdr.rx_data;
3226 uint pkt_len = precv_frame->u.hdr.len;
3227 #ifdef CONFIG_P2P
3228 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3229 u8 p2p_status_code = P2P_STATUS_SUCCESS;
3230 u8 *p2pie;
3231 u32 p2pielen = 0;
3232 #endif /* CONFIG_P2P */
3233 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
3234 u8 sta_tbtx_enable = _FALSE;
3235 #endif
3236
3237 #ifdef CONFIG_CONCURRENT_MODE
3238 if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) &&
3239 rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING | WIFI_UNDER_SURVEY)) {
3240 /* don't process assoc request; */
3241 return _SUCCESS;
3242 }
3243 #endif /* CONFIG_CONCURRENT_MODE */
3244
3245 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
3246 return _FAIL;
3247
3248 if (rtw_check_invalid_mac_address(get_addr2_ptr(pframe), _FALSE)) {
3249 RTW_INFO("%s : reject invalid ASSOC-req "MAC_FMT"\n",
3250 __func__, MAC_ARG(get_addr2_ptr(pframe)));
3251 return _FAIL;
3252 }
3253
3254 frame_type = get_frame_sub_type(pframe);
3255 if (frame_type == WIFI_ASSOCREQ) {
3256 reassoc = 0;
3257 ie_offset = _ASOCREQ_IE_OFFSET_;
3258 } else { /* WIFI_REASSOCREQ */
3259 reassoc = 1;
3260 ie_offset = _REASOCREQ_IE_OFFSET_;
3261 }
3262
3263
3264 if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
3265 RTW_INFO("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
3266 "\n", reassoc, (unsigned long)pkt_len);
3267 return _FAIL;
3268 }
3269
3270 pstat = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3271 if (pstat == (struct sta_info *)NULL) {
3272 status = _RSON_CLS2_;
3273 goto asoc_class2_error;
3274 }
3275
3276 RTW_INFO("%s from "MAC_FMT"\n", __FUNCTION__, MAC_ARG(get_addr2_ptr(pframe)));
3277
3278 if (pstat->authalg == WLAN_AUTH_SAE) {
3279 /* WPA3-SAE */
3280 if (((pstat->state) & WIFI_FW_AUTH_NULL)) {
3281 /* TODO:
3282 Queue AssocReq and Proccess
3283 by external auth trigger. */
3284 RTW_INFO("%s: wait external auth trigger\n", __func__);
3285 return _SUCCESS;
3286 }
3287 }
3288
3289 /* check if this stat has been successfully authenticated/assocated */
3290 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) {
3291 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) {
3292 status = _RSON_CLS2_;
3293 goto asoc_class2_error;
3294 } else {
3295 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
3296 pstat->state |= WIFI_FW_ASSOC_STATE;
3297 }
3298 } else {
3299 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
3300 pstat->state |= WIFI_FW_ASSOC_STATE;
3301 }
3302
3303 #if 0/* todo:tkip_countermeasures */
3304 if (hapd->tkip_countermeasures) {
3305 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
3306 goto fail;
3307 }
3308 #endif
3309
3310 if (rtw_ap_linking_test_force_asoc_fail()) {
3311 status = rtw_ap_linking_test_force_asoc_fail();
3312 RTW_INFO(FUNC_ADPT_FMT" force asoc fail with status:%u\n"
3313 , FUNC_ADPT_ARG(padapter), status);
3314 goto OnAssocReqFail;
3315 }
3316
3317 /* now parse all ieee802_11 ie to point to elems */
3318 left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
3319 pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
3320 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) {
3321 RTW_INFO("STA " MAC_FMT " sent invalid association request\n",
3322 MAC_ARG(pstat->cmn.mac_addr));
3323 status = _STATS_FAILURE_;
3324 goto OnAssocReqFail;
3325 }
3326
3327 rtw_ap_parse_sta_capability(padapter, pstat, pframe + WLAN_HDR_A3_LEN);
3328
3329 listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN + 2);
3330 #if 0/* todo: */
3331 /* check listen_interval */
3332 if (listen_interval > hapd->conf->max_listen_interval) {
3333 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
3334 HOSTAPD_LEVEL_DEBUG,
3335 "Too large Listen Interval (%d)",
3336 listen_interval);
3337 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
3338 goto fail;
3339 }
3340
3341 pstat->listen_interval = listen_interval;
3342 #endif
3343
3344 /* now we should check all the fields... */
3345 /* checking SSID */
3346 if (elems.ssid == NULL
3347 || elems.ssid_len == 0
3348 || elems.ssid_len != cur->Ssid.SsidLength
3349 || _rtw_memcmp(elems.ssid, cur->Ssid.Ssid, cur->Ssid.SsidLength) == _FALSE
3350 ) {
3351 status = _STATS_FAILURE_;
3352 goto OnAssocReqFail;
3353 }
3354
3355 /* (Extended) Supported rates */
3356 status = rtw_ap_parse_sta_supported_rates(padapter, pstat
3357 , pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
3358 if (status != _STATS_SUCCESSFUL_)
3359 goto OnAssocReqFail;
3360
3361 /* check RSN/WPA/WPS */
3362 status = rtw_ap_parse_sta_security_ie(padapter, pstat, &elems);
3363 if (status != _STATS_SUCCESSFUL_)
3364 goto OnAssocReqFail;
3365
3366 /* check if there is WMM IE & support WWM-PS */
3367 rtw_ap_parse_sta_wmm_ie(padapter, pstat
3368 , pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
3369
3370 #ifdef CONFIG_RTS_FULL_BW
3371 /*check vendor IE*/
3372 rtw_parse_sta_vendor_ie_8812(padapter, pstat
3373 , pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
3374 #endif/*CONFIG_RTS_FULL_BW*/
3375
3376 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
3377 if (elems.tbtx_cap && elems.tbtx_cap_len != 0) {
3378 if(rtw_is_tbtx_capabilty(elems.tbtx_cap, elems.tbtx_cap_len)) {
3379 sta_tbtx_enable = _TRUE;
3380 }
3381 }
3382
3383 #endif
3384
3385 rtw_ap_parse_sta_ht_ie(padapter, pstat, &elems);
3386 rtw_ap_parse_sta_vht_ie(padapter, pstat, &elems);
3387
3388 if (((pstat->flags & WLAN_STA_HT) || (pstat->flags & WLAN_STA_VHT)) &&
3389 ((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
3390 (pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) {
3391
3392 RTW_INFO("(V)HT: " MAC_FMT " tried to use TKIP with (V)HT association\n", MAC_ARG(pstat->cmn.mac_addr));
3393
3394 pstat->flags &= ~WLAN_STA_HT;
3395 pstat->flags &= ~WLAN_STA_VHT;
3396 /*status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
3397 * goto OnAssocReqFail;
3398 */
3399 }
3400
3401 #ifdef CONFIG_P2P
3402 pstat->is_p2p_device = _FALSE;
3403 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
3404 p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen);
3405 if (p2pie) {
3406 pstat->is_p2p_device = _TRUE;
3407 p2p_status_code = (u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat);
3408 if (p2p_status_code > 0) {
3409 pstat->p2p_status_code = p2p_status_code;
3410 status = _STATS_CAP_FAIL_;
3411 goto OnAssocReqFail;
3412 }
3413 }
3414 #ifdef CONFIG_WFD
3415 rtw_process_wfd_ies(padapter, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, __func__);
3416 #endif
3417 }
3418 pstat->p2p_status_code = p2p_status_code;
3419 #endif /* CONFIG_P2P */
3420
3421 rtw_ap_parse_sta_multi_ap_ie(padapter, pstat, pos, left);
3422
3423 #ifdef CONFIG_RTW_REPEATER_SON
3424 if (rtw_rson_ap_check_sta(padapter, pframe, pkt_len, ie_offset))
3425 goto OnAssocReqFail;
3426 #endif
3427
3428 /* TODO: identify_proprietary_vendor_ie(); */
3429 /* Realtek proprietary IE */
3430 /* identify if this is Broadcom sta */
3431 /* identify if this is ralink sta */
3432 /* Customer proprietary IE */
3433
3434 #ifdef CONFIG_RTW_80211K
3435 rtw_ap_parse_sta_rm_en_cap(padapter, pstat, &elems);
3436 #endif
3437
3438 /* AID assignment */
3439 if (pstat->cmn.aid > 0)
3440 RTW_INFO(FUNC_ADPT_FMT" use old AID=%d for "MAC_FMT"\n",
3441 FUNC_ADPT_ARG(padapter), pstat->cmn.aid, MAC_ARG(pstat->cmn.mac_addr));
3442 else {
3443 if (!rtw_aid_alloc(padapter, pstat)) {
3444 RTW_INFO(FUNC_ADPT_FMT" no room for more AIDs for "MAC_FMT"\n",
3445 FUNC_ADPT_ARG(padapter), MAC_ARG(pstat->cmn.mac_addr));
3446 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
3447 goto OnAssocReqFail;
3448 }
3449 RTW_INFO(FUNC_ADPT_FMT" allocate new AID=%d for "MAC_FMT"\n",
3450 FUNC_ADPT_ARG(padapter), pstat->cmn.aid, MAC_ARG(pstat->cmn.mac_addr));
3451 }
3452
3453 pstat->state &= (~WIFI_FW_ASSOC_STATE);
3454 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
3455 /* RTW_INFO("==================%s, %d, (%x), bpairwise_key_installed=%d, MAC:"MAC_FMT"\n"
3456 , __func__, __LINE__, pstat->state, pstat->bpairwise_key_installed, MAC_ARG(pstat->cmn.mac_addr)); */
3457 #ifdef CONFIG_IEEE80211W
3458 if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
3459 || !(pstat->flags & WLAN_STA_MFP))
3460 #endif /* CONFIG_IEEE80211W */
3461 {
3462 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
3463 if (!rtw_is_list_empty(&pstat->auth_list)) {
3464 rtw_list_delete(&pstat->auth_list);
3465 pstapriv->auth_list_cnt--;
3466 }
3467 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
3468
3469 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3470 if (rtw_is_list_empty(&pstat->asoc_list)) {
3471 pstat->expire_to = pstapriv->expire_to;
3472 rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
3473 pstapriv->asoc_list_cnt++;
3474 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
3475 if (sta_tbtx_enable) {
3476 pstat->tbtx_enable = _TRUE;
3477 pstapriv->tbtx_asoc_list_cnt++;
3478 }
3479 #endif
3480 }
3481 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3482 }
3483
3484 /* now the station is qualified to join our BSS... */
3485 if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) {
3486 #ifdef CONFIG_NATIVEAP_MLME
3487 #ifdef CONFIG_IEEE80211W
3488 if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
3489 || !(pstat->flags & WLAN_STA_MFP))
3490 #endif /* CONFIG_IEEE80211W */
3491 {
3492 /* .1 bss_cap_update & sta_info_update */
3493 bss_cap_update_on_sta_join(padapter, pstat);
3494 sta_info_update(padapter, pstat);
3495 }
3496 #ifdef CONFIG_IEEE80211W
3497 if (pstat->bpairwise_key_installed == _TRUE && (pstat->flags & WLAN_STA_MFP))
3498 status = _STATS_REFUSED_TEMPORARILY_;
3499 #endif /* CONFIG_IEEE80211W */
3500 /* .2 issue assoc rsp before notify station join event. */
3501 if (frame_type == WIFI_ASSOCREQ)
3502 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
3503 else
3504 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
3505
3506 #ifdef CONFIG_IOCTL_CFG80211
3507 _enter_critical_bh(&pstat->lock, &irqL);
3508 if (pstat->passoc_req) {
3509 rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
3510 pstat->passoc_req = NULL;
3511 pstat->assoc_req_len = 0;
3512 }
3513
3514 pstat->passoc_req = rtw_zmalloc(pkt_len);
3515 if (pstat->passoc_req) {
3516 _rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
3517 pstat->assoc_req_len = pkt_len;
3518 }
3519 _exit_critical_bh(&pstat->lock, &irqL);
3520 #endif /* CONFIG_IOCTL_CFG80211 */
3521 #ifdef CONFIG_IEEE80211W
3522 if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
3523 || !(pstat->flags & WLAN_STA_MFP))
3524 #endif /* CONFIG_IEEE80211W */
3525 {
3526 /* .3-(1) report sta add event */
3527 report_add_sta_event(padapter, pstat->cmn.mac_addr);
3528 }
3529 #ifdef CONFIG_IEEE80211W
3530 if (pstat->bpairwise_key_installed == _TRUE && (pstat->flags & WLAN_STA_MFP)) {
3531 RTW_INFO(MAC_FMT"\n", MAC_ARG(pstat->cmn.mac_addr));
3532 issue_action_SA_Query(padapter, pstat->cmn.mac_addr, 0, 0, IEEE80211W_RIGHT_KEY);
3533 }
3534 #endif /* CONFIG_IEEE80211W */
3535 #endif /* CONFIG_NATIVEAP_MLME */
3536 }
3537
3538 return _SUCCESS;
3539
3540 asoc_class2_error:
3541
3542 #ifdef CONFIG_NATIVEAP_MLME
3543 issue_deauth(padapter, (void *)get_addr2_ptr(pframe), status);
3544 #endif
3545
3546 return _FAIL;
3547
3548 OnAssocReqFail:
3549
3550
3551 #ifdef CONFIG_NATIVEAP_MLME
3552 /* pstat->cmn.aid = 0; */
3553 if (frame_type == WIFI_ASSOCREQ)
3554 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
3555 else
3556 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
3557 #endif
3558
3559
3560 #endif /* CONFIG_AP_MODE */
3561
3562 return _FAIL;
3563
3564 }
3565
3566 #if defined(CONFIG_LAYER2_ROAMING) && defined(CONFIG_RTW_80211K)
rtw_roam_nb_discover(_adapter * padapter,u8 bfroce)3567 void rtw_roam_nb_discover(_adapter *padapter, u8 bfroce)
3568 {
3569 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3570 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3571 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3572 struct sta_priv *pstapriv = &padapter->stapriv;
3573 struct sta_info *psta;
3574 u8 nb_req_issue = _FALSE;
3575
3576 if (!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
3577 return;
3578
3579 if (!rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE))
3580 return;
3581
3582 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
3583 if (!psta)
3584 return;
3585
3586 if (bfroce || (!pmlmepriv->nb_info.nb_rpt_is_same))
3587 nb_req_issue = _TRUE;
3588
3589 if (nb_req_issue && (psta->rm_en_cap[0] & RTW_RRM_NB_RPT_EN))
3590 rm_add_nb_req(padapter, psta);
3591 }
3592 #endif
3593
OnAssocRsp(_adapter * padapter,union recv_frame * precv_frame)3594 unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
3595 {
3596 uint i;
3597 int res;
3598 unsigned short status;
3599 PNDIS_802_11_VARIABLE_IEs pIE;
3600 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3601 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3602 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3603 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
3604 u8 *pframe = precv_frame->u.hdr.rx_data;
3605 uint pkt_len = precv_frame->u.hdr.len;
3606 #ifdef CONFIG_WAPI_SUPPORT
3607 PNDIS_802_11_VARIABLE_IEs pWapiIE = NULL;
3608 #endif
3609
3610 RTW_INFO("%s\n", __FUNCTION__);
3611
3612 /* check A1 matches or not */
3613 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3614 return _SUCCESS;
3615
3616 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)) || pmlmeext->join_abort)
3617 return _SUCCESS;
3618
3619 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
3620 return _SUCCESS;
3621
3622 _cancel_timer_ex(&pmlmeext->link_timer);
3623
3624 /* status */
3625 status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2));
3626 if (status > 0) {
3627 RTW_INFO("assoc reject, status code: %d\n", status);
3628 pmlmeinfo->state = WIFI_FW_NULL_STATE;
3629 res = -4;
3630 goto report_assoc_result;
3631 }
3632
3633 /* get capabilities */
3634 pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3635
3636 /* set slot time */
3637 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20;
3638
3639 /* AID */
3640 res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4)) & 0x3fff);
3641
3642 /* check aid value */
3643 if (res < 1 || res > 2007) {
3644 RTW_INFO("assoc reject, aid: %d\n", res);
3645 pmlmeinfo->state = WIFI_FW_NULL_STATE;
3646 res = -4;
3647 goto report_assoc_result;
3648 }
3649
3650 /* following are moved to join event callback function */
3651 /* to handle HT, WMM, rate adaptive, update MAC reg */
3652 /* for not to handle the synchronous IO in the tasklet */
3653 for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) {
3654 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
3655
3656 switch (pIE->ElementID) {
3657 case _VENDOR_SPECIFIC_IE_:
3658 if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6)) /* WMM */
3659 WMM_param_handler(padapter, pIE);
3660 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
3661 else if (_rtw_memcmp(pIE->data, WFD_OUI, 4)) /* WFD */
3662 rtw_process_wfd_ie(padapter, (u8 *)pIE, pIE->Length, __func__);
3663 #endif
3664 break;
3665
3666 #ifdef CONFIG_WAPI_SUPPORT
3667 case _WAPI_IE_:
3668 pWapiIE = pIE;
3669 break;
3670 #endif
3671
3672 case _HT_CAPABILITY_IE_: /* HT caps */
3673 HT_caps_handler(padapter, pIE);
3674 #ifdef ROKU_PRIVATE
3675 HT_caps_handler_infra_ap(padapter, pIE);
3676 #endif /* ROKU_PRIVATE */
3677 break;
3678
3679 case _HT_EXTRA_INFO_IE_: /* HT info */
3680 HT_info_handler(padapter, pIE);
3681 break;
3682
3683 #ifdef CONFIG_80211AC_VHT
3684 case EID_VHTCapability:
3685 VHT_caps_handler(padapter, pIE);
3686 #ifdef ROKU_PRIVATE
3687 VHT_caps_handler_infra_ap(padapter, pIE);
3688 #endif /* ROKU_PRIVATE */
3689 break;
3690
3691 case EID_VHTOperation:
3692 VHT_operation_handler(padapter, pIE);
3693 break;
3694 #endif
3695
3696 case _ERPINFO_IE_:
3697 ERP_IE_handler(padapter, pIE);
3698 break;
3699 #ifdef CONFIG_TDLS
3700 case WLAN_EID_EXT_CAP:
3701 if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
3702 padapter->tdlsinfo.ap_prohibited = _TRUE;
3703 if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
3704 padapter->tdlsinfo.ch_switch_prohibited = _TRUE;
3705 break;
3706 #endif /* CONFIG_TDLS */
3707
3708 #ifdef CONFIG_RTW_80211K
3709 case _EID_RRM_EN_CAP_IE_:
3710 RM_IE_handler(padapter, pIE);
3711 break;
3712 #endif
3713
3714 #ifdef ROKU_PRIVATE
3715 /* Infra mode, used to store AP's info , Parse the supported rates from AssocRsp */
3716 case _SUPPORTEDRATES_IE_:
3717 Supported_rate_infra_ap(padapter, pIE);
3718 break;
3719
3720 case _EXT_SUPPORTEDRATES_IE_:
3721 Extended_Supported_rate_infra_ap(padapter, pIE);
3722 break;
3723 #endif /* ROKU_PRIVATE */
3724 default:
3725 break;
3726 }
3727
3728 i += (pIE->Length + 2);
3729 }
3730
3731 #ifdef CONFIG_WAPI_SUPPORT
3732 rtw_wapi_on_assoc_ok(padapter, pWapiIE);
3733 #endif
3734
3735 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
3736 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
3737
3738 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
3739 UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
3740
3741 report_assoc_result:
3742 if (res > 0)
3743 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
3744 else
3745 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
3746
3747 report_join_res(padapter, res, status);
3748
3749 #if defined(CONFIG_LAYER2_ROAMING) && defined(CONFIG_RTW_80211K)
3750 rtw_roam_nb_discover(padapter, _TRUE);
3751 #endif
3752 return _SUCCESS;
3753 }
3754
OnDeAuth(_adapter * padapter,union recv_frame * precv_frame)3755 unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
3756 {
3757 unsigned short reason;
3758 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3759 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3760 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3761 u8 *pframe = precv_frame->u.hdr.rx_data;
3762 #ifdef CONFIG_P2P
3763 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3764 #endif /* CONFIG_P2P */
3765
3766 /* check A3 */
3767 if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3768 return _SUCCESS;
3769
3770 RTW_INFO(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3771
3772 #ifdef CONFIG_P2P
3773 if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
3774 _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
3775 _set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
3776 }
3777 #endif /* CONFIG_P2P */
3778
3779 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3780
3781 #ifdef CONFIG_AP_MODE
3782 if (MLME_IS_AP(padapter)) {
3783 _irqL irqL;
3784 struct sta_info *psta;
3785 struct sta_priv *pstapriv = &padapter->stapriv;
3786
3787 /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
3788 /* rtw_free_stainfo(padapter, psta); */
3789 /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
3790
3791 RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3792 , FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe));
3793
3794 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3795 if (psta) {
3796 u8 updated = _FALSE;
3797
3798 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3799 if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
3800 rtw_list_delete(&psta->asoc_list);
3801 pstapriv->asoc_list_cnt--;
3802 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
3803 if (psta->tbtx_enable)
3804 pstapriv->tbtx_asoc_list_cnt--;
3805 #endif
3806 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3807
3808 }
3809 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3810
3811 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3812 }
3813
3814
3815 return _SUCCESS;
3816 } else
3817 #endif
3818 if (!MLME_IS_MESH(padapter)) {
3819 int ignore_received_deauth = 0;
3820
3821 /* Commented by Albert 20130604 */
3822 /* Before sending the auth frame to start the STA/GC mode connection with AP/GO, */
3823 /* we will send the deauth first. */
3824 /* However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. */
3825 /* Added the following code to avoid this case. */
3826 if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) ||
3827 (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)) {
3828 if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA)
3829 ignore_received_deauth = 1;
3830 else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
3831 /* TODO: 802.11r */
3832 ignore_received_deauth = 1;
3833 }
3834 }
3835
3836 RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM, ignore=%d\n"
3837 , FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe), ignore_received_deauth);
3838
3839 if (0 == ignore_received_deauth)
3840 receive_disconnect(padapter, get_addr2_ptr(pframe), reason, _FALSE);
3841 }
3842 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3843 return _SUCCESS;
3844
3845 }
3846
OnDisassoc(_adapter * padapter,union recv_frame * precv_frame)3847 unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
3848 {
3849 unsigned short reason;
3850 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3851 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3852 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3853 u8 *pframe = precv_frame->u.hdr.rx_data;
3854 #ifdef CONFIG_P2P
3855 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3856 #endif /* CONFIG_P2P */
3857
3858 /* check A3 */
3859 if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3860 return _SUCCESS;
3861
3862 RTW_INFO(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3863
3864 #ifdef CONFIG_P2P
3865 if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
3866 _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
3867 _set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
3868 }
3869 #endif /* CONFIG_P2P */
3870
3871 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3872
3873 #ifdef CONFIG_AP_MODE
3874 if (MLME_IS_AP(padapter)) {
3875 _irqL irqL;
3876 struct sta_info *psta;
3877 struct sta_priv *pstapriv = &padapter->stapriv;
3878
3879 /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
3880 /* rtw_free_stainfo(padapter, psta); */
3881 /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
3882
3883 RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3884 , FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe));
3885
3886 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3887 if (psta) {
3888 u8 updated = _FALSE;
3889
3890 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3891 if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
3892 rtw_list_delete(&psta->asoc_list);
3893 pstapriv->asoc_list_cnt--;
3894 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
3895 if (psta->tbtx_enable)
3896 pstapriv->tbtx_asoc_list_cnt--;
3897 #endif
3898 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3899
3900 }
3901 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3902
3903 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3904 }
3905
3906 return _SUCCESS;
3907 } else
3908 #endif
3909 if (!MLME_IS_MESH(padapter)) {
3910 RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3911 , FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe));
3912
3913 #ifdef CONFIG_RTW_WNM
3914 if (rtw_wnm_try_btm_roam_imnt(padapter) > 0)
3915 #endif
3916 receive_disconnect(padapter, get_addr2_ptr(pframe), reason, _FALSE);
3917 }
3918 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3919 return _SUCCESS;
3920
3921 }
3922
OnAtim(_adapter * padapter,union recv_frame * precv_frame)3923 unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
3924 {
3925 RTW_INFO("%s\n", __FUNCTION__);
3926 return _SUCCESS;
3927 }
3928
on_action_spct_ch_switch(_adapter * padapter,struct sta_info * psta,u8 * ies,uint ies_len)3929 unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
3930 {
3931 unsigned int ret = _FAIL;
3932 struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
3933 struct mlme_ext_info *pmlmeinfo = &(mlmeext->mlmext_info);
3934
3935 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
3936 ret = _SUCCESS;
3937 goto exit;
3938 }
3939
3940 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
3941
3942 int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
3943 int ch_offset = -1;
3944 u8 bwmode;
3945 struct ieee80211_info_element *ie;
3946
3947 RTW_INFO(FUNC_NDEV_FMT" from "MAC_FMT"\n",
3948 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->cmn.mac_addr));
3949
3950 for_each_ie(ie, ies, ies_len) {
3951 if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
3952 ch_switch_mode = ie->data[0];
3953 ch = ie->data[1];
3954 ch_switch_cnt = ie->data[2];
3955 RTW_INFO("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
3956 ch_switch_mode, ch, ch_switch_cnt);
3957 } else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
3958 ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
3959 RTW_INFO("ch_offset:%d\n", ch_offset);
3960 }
3961 }
3962
3963 if (ch == -1)
3964 return _SUCCESS;
3965
3966 if (ch_offset == -1)
3967 bwmode = mlmeext->cur_bwmode;
3968 else
3969 bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
3970 CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40;
3971
3972 ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
3973
3974 /* todo:
3975 * 1. the decision of channel switching
3976 * 2. things after channel switching
3977 */
3978
3979 ret = rtw_set_chbw_cmd(padapter, ch, bwmode, ch_offset, 0);
3980 }
3981
3982 exit:
3983 return ret;
3984 }
3985
on_action_spct(_adapter * padapter,union recv_frame * precv_frame)3986 unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
3987 {
3988 unsigned int ret = _FAIL;
3989 struct sta_info *psta = NULL;
3990 struct sta_priv *pstapriv = &padapter->stapriv;
3991 u8 *pframe = precv_frame->u.hdr.rx_data;
3992 uint frame_len = precv_frame->u.hdr.len;
3993 u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3994 u8 category;
3995 u8 action;
3996
3997 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3998
3999 if (!psta)
4000 goto exit;
4001
4002 category = frame_body[0];
4003 if (category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
4004 goto exit;
4005
4006 action = frame_body[1];
4007
4008 RTW_INFO(FUNC_ADPT_FMT" action:%u\n", FUNC_ADPT_ARG(padapter), action);
4009
4010 switch (action) {
4011 case RTW_WLAN_ACTION_SPCT_MSR_REQ:
4012 case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
4013 case RTW_WLAN_ACTION_SPCT_TPC_REQ:
4014 case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
4015 break;
4016 case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
4017 #ifdef CONFIG_SPCT_CH_SWITCH
4018 ret = on_action_spct_ch_switch(padapter, psta
4019 , frame_body + 2, frame_len - (frame_body - pframe) - 2);
4020 #elif CONFIG_DFS
4021 if (MLME_IS_STA(padapter) && MLME_IS_ASOC(padapter)) {
4022 process_csa_ie(padapter
4023 , frame_body + 2, frame_len - (frame_body - pframe) - 2);
4024 }
4025 #endif
4026 break;
4027 default:
4028 break;
4029 }
4030
4031 exit:
4032 return ret;
4033 }
4034
OnAction_qos(_adapter * padapter,union recv_frame * precv_frame)4035 unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
4036 {
4037 return _SUCCESS;
4038 }
4039
OnAction_dls(_adapter * padapter,union recv_frame * precv_frame)4040 unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
4041 {
4042 return _SUCCESS;
4043 }
4044
4045 #ifdef CONFIG_RTW_WNM
on_action_wnm(_adapter * adapter,union recv_frame * rframe)4046 unsigned int on_action_wnm(_adapter *adapter, union recv_frame *rframe)
4047 {
4048 unsigned int ret = _FAIL;
4049 struct sta_info *sta = NULL;
4050 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
4051 struct sta_priv *stapriv = &(adapter->stapriv);
4052 u8 *frame = rframe->u.hdr.rx_data;
4053 u32 frame_len = rframe->u.hdr.len;
4054 u8 *frame_body = (u8 *)(frame + sizeof(struct rtw_ieee80211_hdr_3addr));
4055 u32 frame_body_len = frame_len - sizeof(struct rtw_ieee80211_hdr_3addr);
4056 u8 category, action;
4057 int cnt = 0;
4058 char msg[16];
4059
4060 sta = rtw_get_stainfo(stapriv, get_addr2_ptr(frame));
4061 if (!sta)
4062 goto exit;
4063
4064 category = frame_body[0];
4065 if (category != RTW_WLAN_CATEGORY_WNM)
4066 goto exit;
4067
4068 action = frame_body[1];
4069
4070 switch (action) {
4071 #ifdef CONFIG_RTW_80211R
4072 case RTW_WLAN_ACTION_WNM_BTM_REQ:
4073 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
4074 RTW_INFO("WNM: BSS Transition Management Request recv.\n");
4075 rtw_wnm_process_btm_req(adapter, frame_body, frame_body_len);
4076 }
4077 ret = _SUCCESS;
4078 break;
4079 #endif
4080 case RTW_WLAN_ACTION_WNM_BTM_RSP:
4081 if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) &&
4082 (pmlmepriv->nb_info.features & RTW_WNM_FEATURE_BTM_REQ_EN)) {
4083 struct btm_rsp_hdr rsp;
4084 u32 sz;
4085
4086 RTW_INFO("WNM: BSS Transition Management Response recv.\n");
4087 sz = rtw_wnm_btm_rsp_candidates_sz_get(adapter,
4088 frame_body, frame_body_len);
4089 _rtw_memset(&rsp, 0, sizeof(rsp));
4090
4091 if (sz > 0)
4092 rsp.pcandidates = rtw_zmalloc(sz);
4093
4094 rtw_wnm_process_btm_rsp(adapter, frame_body, frame_body_len, &rsp);
4095 /* TODO : handle candidates info in rsp.pcandidates for upper-layer services */
4096 #ifdef CONFIG_PLATFORM_CMAP_INTFS
4097 cmap_intfs_nl_btm_resp_event(adapter, sta->cmn.mac_addr,
4098 adapter_mac_addr(adapter),
4099 rsp.status, rsp.bssid,
4100 rsp.pcandidates,
4101 rsp.candidates_num);
4102 #endif
4103 if (0 && rsp.pcandidates && (rsp.candidates_num > 0))
4104 RTW_INFO_DUMP("pcandidates : ", rsp.pcandidates, sz);
4105
4106 if ((sz > 0) && (rsp.pcandidates != NULL))
4107 rtw_mfree(rsp.pcandidates, sz);
4108 }
4109 fallthrough;
4110 /* fall through */
4111 default:
4112 #ifdef CONFIG_IOCTL_CFG80211
4113 cnt += sprintf((msg + cnt), "ACT_WNM %u", action);
4114 rtw_cfg80211_rx_action(adapter, rframe, msg);
4115 #endif
4116 ret = _SUCCESS;
4117 break;
4118 }
4119
4120 exit:
4121 return ret;
4122 }
4123 #endif /* CONFIG_RTW_WNM */
4124
4125 /**
4126 * rtw_rx_ampdu_size - Get the target RX AMPDU buffer size for the specific @adapter
4127 * @adapter: the adapter to get target RX AMPDU buffer size
4128 *
4129 * Returns: the target RX AMPDU buffer size
4130 */
rtw_rx_ampdu_size(_adapter * adapter)4131 u8 rtw_rx_ampdu_size(_adapter *adapter)
4132 {
4133 u8 size;
4134 HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
4135
4136 #ifdef CONFIG_BT_COEXIST
4137 if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(adapter) == _TRUE) {
4138 size = rtw_btcoex_GetAMPDUSize(adapter);
4139 goto exit;
4140 }
4141 #endif
4142
4143 /* for scan */
4144 if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
4145 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
4146 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size != RX_AMPDU_SIZE_INVALID
4147 ) {
4148 size = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size;
4149 goto exit;
4150 }
4151
4152 /* default value based on max_rx_ampdu_factor */
4153 if (adapter->driver_rx_ampdu_factor != 0xFF)
4154 max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)adapter->driver_rx_ampdu_factor;
4155 else
4156 rtw_hal_get_def_var(adapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
4157
4158 /* In Maximum A-MPDU Length Exponent subfield of A-MPDU Parameters field of HT Capabilities element,
4159 the unit of max_rx_ampdu_factor are octets. 8K, 16K, 32K, 64K is right.
4160 But the buffer size subfield of Block Ack Parameter Set field in ADDBA action frame indicates
4161 the number of buffers available for this particular TID. Each buffer is equal to max. size of
4162 MSDU or AMSDU.
4163 The size variable means how many MSDUs or AMSDUs, it's not Kbytes.
4164 */
4165 if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
4166 size = 64;
4167 else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
4168 size = 32;
4169 else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
4170 size = 16;
4171 else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
4172 size = 8;
4173 else
4174 size = 64;
4175
4176 exit:
4177
4178 if (size > 127)
4179 size = 127;
4180
4181 return size;
4182 }
4183
4184 /**
4185 * rtw_rx_ampdu_is_accept - Get the permission if RX AMPDU should be set up for the specific @adapter
4186 * @adapter: the adapter to get the permission if RX AMPDU should be set up
4187 *
4188 * Returns: accept or not
4189 */
rtw_rx_ampdu_is_accept(_adapter * adapter)4190 bool rtw_rx_ampdu_is_accept(_adapter *adapter)
4191 {
4192 bool accept;
4193
4194 if (adapter->fix_rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID) {
4195 accept = adapter->fix_rx_ampdu_accept;
4196 goto exit;
4197 }
4198
4199 #ifdef CONFIG_BT_COEXIST
4200 if (rtw_btcoex_IsBTCoexRejectAMPDU(adapter) == _TRUE) {
4201 accept = _FALSE;
4202 goto exit;
4203 }
4204 #endif
4205
4206 /* for scan */
4207 if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
4208 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
4209 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
4210 ) {
4211 accept = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept;
4212 goto exit;
4213 }
4214
4215 /* default value for other cases */
4216 accept = adapter->mlmeextpriv.mlmext_info.bAcceptAddbaReq;
4217
4218 exit:
4219 return accept;
4220 }
4221
4222 /**
4223 * rtw_rx_ampdu_set_size - Set the target RX AMPDU buffer size for the specific @adapter and specific @reason
4224 * @adapter: the adapter to set target RX AMPDU buffer size
4225 * @size: the target RX AMPDU buffer size to set
4226 * @reason: reason for the target RX AMPDU buffer size setting
4227 *
4228 * Returns: whether the target RX AMPDU buffer size is changed
4229 */
rtw_rx_ampdu_set_size(_adapter * adapter,u8 size,u8 reason)4230 bool rtw_rx_ampdu_set_size(_adapter *adapter, u8 size, u8 reason)
4231 {
4232 bool is_adj = _FALSE;
4233 struct mlme_ext_priv *mlmeext;
4234 struct mlme_ext_info *mlmeinfo;
4235
4236 mlmeext = &adapter->mlmeextpriv;
4237 mlmeinfo = &mlmeext->mlmext_info;
4238
4239 if (reason == RX_AMPDU_DRV_FIXED) {
4240 if (adapter->fix_rx_ampdu_size != size) {
4241 adapter->fix_rx_ampdu_size = size;
4242 is_adj = _TRUE;
4243 RTW_INFO(FUNC_ADPT_FMT" fix_rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
4244 }
4245 } else if (reason == RX_AMPDU_DRV_SCAN) {
4246 struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
4247
4248 if (ss->rx_ampdu_size != size) {
4249 ss->rx_ampdu_size = size;
4250 is_adj = _TRUE;
4251 RTW_INFO(FUNC_ADPT_FMT" ss.rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
4252 }
4253 }
4254
4255 return is_adj;
4256 }
4257
4258 /**
4259 * rtw_rx_ampdu_set_accept - Set the permission if RX AMPDU should be set up for the specific @adapter and specific @reason
4260 * @adapter: the adapter to set if RX AMPDU should be set up
4261 * @accept: if RX AMPDU should be set up
4262 * @reason: reason for the permission if RX AMPDU should be set up
4263 *
4264 * Returns: whether the permission if RX AMPDU should be set up is changed
4265 */
rtw_rx_ampdu_set_accept(_adapter * adapter,u8 accept,u8 reason)4266 bool rtw_rx_ampdu_set_accept(_adapter *adapter, u8 accept, u8 reason)
4267 {
4268 bool is_adj = _FALSE;
4269 struct mlme_ext_priv *mlmeext;
4270 struct mlme_ext_info *mlmeinfo;
4271
4272 mlmeext = &adapter->mlmeextpriv;
4273 mlmeinfo = &mlmeext->mlmext_info;
4274
4275 if (reason == RX_AMPDU_DRV_FIXED) {
4276 if (adapter->fix_rx_ampdu_accept != accept) {
4277 adapter->fix_rx_ampdu_accept = accept;
4278 is_adj = _TRUE;
4279 RTW_INFO(FUNC_ADPT_FMT" fix_rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
4280 }
4281 } else if (reason == RX_AMPDU_DRV_SCAN) {
4282 if (adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != accept) {
4283 adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept = accept;
4284 is_adj = _TRUE;
4285 RTW_INFO(FUNC_ADPT_FMT" ss.rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
4286 }
4287 }
4288
4289 return is_adj;
4290 }
4291
4292 /**
4293 * rx_ampdu_apply_sta_tid - Apply RX AMPDU setting to the specific @sta and @tid
4294 * @adapter: the adapter to which @sta belongs
4295 * @sta: the sta to be checked
4296 * @tid: the tid to be checked
4297 * @accept: the target permission if RX AMPDU should be set up
4298 * @size: the target RX AMPDU buffer size
4299 *
4300 * Returns:
4301 * 0: no canceled
4302 * 1: canceled by no permission
4303 * 2: canceled by different buffer size
4304 * 3: canceled by potential mismatched status
4305 *
4306 * Blocking function, may sleep
4307 */
rx_ampdu_apply_sta_tid(_adapter * adapter,struct sta_info * sta,u8 tid,u8 accept,u8 size)4308 u8 rx_ampdu_apply_sta_tid(_adapter *adapter, struct sta_info *sta, u8 tid, u8 accept, u8 size)
4309 {
4310 u8 ret = 0;
4311 struct recv_reorder_ctrl *reorder_ctl = &sta->recvreorder_ctrl[tid];
4312
4313 if (reorder_ctl->enable == _FALSE) {
4314 if (reorder_ctl->ampdu_size != RX_AMPDU_SIZE_INVALID) {
4315 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 1);
4316 ret = 3;
4317 }
4318 goto exit;
4319 }
4320
4321 if (accept == _FALSE) {
4322 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
4323 ret = 1;
4324 } else if (reorder_ctl->ampdu_size != size) {
4325 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
4326 ret = 2;
4327 }
4328
4329 exit:
4330 return ret;
4331 }
4332
rx_ampdu_size_sta_limit(_adapter * adapter,struct sta_info * sta)4333 u8 rx_ampdu_size_sta_limit(_adapter *adapter, struct sta_info *sta)
4334 {
4335 u8 sz_limit = 0xFF;
4336
4337 #ifdef CONFIG_80211N_HT
4338 struct registry_priv *regsty = adapter_to_regsty(adapter);
4339 struct mlme_priv *mlme = &adapter->mlmepriv;
4340 struct mlme_ext_info *mlmeinfo = &adapter->mlmeextpriv.mlmext_info;
4341 s8 nss = -1;
4342 u8 bw = rtw_min(sta->cmn.bw_mode, adapter->mlmeextpriv.cur_bwmode);
4343
4344 #ifdef CONFIG_80211AC_VHT
4345 if (is_supported_vht(sta->wireless_mode)) {
4346 nss = rtw_min(rtw_vht_mcsmap_to_nss(mlme->vhtpriv.vht_mcs_map)
4347 , rtw_vht_mcsmap_to_nss(sta->vhtpriv.vht_mcs_map));
4348 } else
4349 #endif
4350 if (is_supported_ht(sta->wireless_mode)) {
4351 nss = rtw_min(rtw_ht_mcsset_to_nss(mlmeinfo->HT_caps.u.HT_cap_element.MCS_rate)
4352 , rtw_ht_mcsset_to_nss(sta->htpriv.ht_cap.supp_mcs_set));
4353 }
4354
4355 if (nss >= 1)
4356 sz_limit = regsty->rx_ampdu_sz_limit_by_nss_bw[nss - 1][bw];
4357 #endif /* CONFIG_80211N_HT */
4358
4359 return sz_limit;
4360 }
4361
4362 /**
4363 * rx_ampdu_apply_sta - Apply RX AMPDU setting to the specific @sta
4364 * @adapter: the adapter to which @sta belongs
4365 * @sta: the sta to be checked
4366 * @accept: the target permission if RX AMPDU should be set up
4367 * @size: the target RX AMPDU buffer size
4368 *
4369 * Returns: number of the RX AMPDU assciation canceled for applying current target setting
4370 *
4371 * Blocking function, may sleep
4372 */
rx_ampdu_apply_sta(_adapter * adapter,struct sta_info * sta,u8 accept,u8 size)4373 u8 rx_ampdu_apply_sta(_adapter *adapter, struct sta_info *sta, u8 accept, u8 size)
4374 {
4375 u8 change_cnt = 0;
4376 int i;
4377
4378 for (i = 0; i < TID_NUM; i++) {
4379 if (rx_ampdu_apply_sta_tid(adapter, sta, i, accept, size) != 0)
4380 change_cnt++;
4381 }
4382
4383 return change_cnt;
4384 }
4385
4386 /**
4387 * rtw_rx_ampdu_apply - Apply the current target RX AMPDU setting for the specific @adapter
4388 * @adapter: the adapter to be applied
4389 *
4390 * Returns: number of the RX AMPDU assciation canceled for applying current target setting
4391 */
rtw_rx_ampdu_apply(_adapter * adapter)4392 u16 rtw_rx_ampdu_apply(_adapter *adapter)
4393 {
4394 u16 adj_cnt = 0;
4395 struct sta_info *sta;
4396 u8 accept = rtw_rx_ampdu_is_accept(adapter);
4397 u8 size;
4398
4399 if (adapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID)
4400 size = adapter->fix_rx_ampdu_size;
4401 else
4402 size = rtw_rx_ampdu_size(adapter);
4403
4404 if (MLME_IS_STA(adapter)) {
4405 sta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
4406 if (sta) {
4407 u8 sta_size = size;
4408
4409 if (adapter->fix_rx_ampdu_size == RX_AMPDU_SIZE_INVALID)
4410 sta_size = rtw_min(size, rx_ampdu_size_sta_limit(adapter, sta));
4411 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, sta_size);
4412 }
4413 /* TODO: TDLS peer */
4414 #ifdef CONFIG_AP_MODE
4415 } else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
4416 _irqL irqL;
4417 _list *phead, *plist;
4418 u8 peer_num = 0;
4419 char peers[NUM_STA];
4420 struct sta_priv *pstapriv = &adapter->stapriv;
4421 int i;
4422
4423 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
4424
4425 phead = &pstapriv->asoc_list;
4426 plist = get_next(phead);
4427
4428 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
4429 int stainfo_offset;
4430
4431 sta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
4432 plist = get_next(plist);
4433
4434 stainfo_offset = rtw_stainfo_offset(pstapriv, sta);
4435 if (stainfo_offset_valid(stainfo_offset))
4436 peers[peer_num++] = stainfo_offset;
4437 }
4438
4439 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
4440
4441 for (i = 0; i < peer_num; i++) {
4442 sta = rtw_get_stainfo_by_offset(pstapriv, peers[i]);
4443 if (sta) {
4444 u8 sta_size = size;
4445
4446 if (adapter->fix_rx_ampdu_size == RX_AMPDU_SIZE_INVALID)
4447 sta_size = rtw_min(size, rx_ampdu_size_sta_limit(adapter, sta));
4448 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, sta_size);
4449 }
4450 }
4451 #endif /* CONFIG_AP_MODE */
4452 }
4453
4454 /* TODO: ADHOC */
4455
4456 return adj_cnt;
4457 }
4458
OnAction_back(_adapter * padapter,union recv_frame * precv_frame)4459 unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
4460 {
4461 u8 *addr;
4462 struct sta_info *psta = NULL;
4463 struct recv_reorder_ctrl *preorder_ctrl;
4464 unsigned char *frame_body;
4465 unsigned char category, action;
4466 unsigned short tid, status, reason_code = 0;
4467 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4468 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4469 u8 *pframe = precv_frame->u.hdr.rx_data;
4470 struct sta_priv *pstapriv = &padapter->stapriv;
4471 struct registry_priv *pregpriv = &padapter->registrypriv;
4472
4473 #ifdef CONFIG_80211N_HT
4474
4475 RTW_INFO("%s\n", __FUNCTION__);
4476
4477 /* check RA matches or not */
4478 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
4479 return _SUCCESS;
4480
4481 #if 0
4482 /* check A1 matches or not */
4483 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
4484 return _SUCCESS;
4485 #endif
4486
4487 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
4488 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
4489 return _SUCCESS;
4490
4491 addr = get_addr2_ptr(pframe);
4492 psta = rtw_get_stainfo(pstapriv, addr);
4493
4494 if (psta == NULL)
4495 return _SUCCESS;
4496
4497 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
4498
4499 category = frame_body[0];
4500 if (category == RTW_WLAN_CATEGORY_BACK) { /* representing Block Ack */
4501 #ifdef CONFIG_TDLS
4502 if ((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
4503 (psta->htpriv.ht_option == _TRUE) &&
4504 (psta->htpriv.ampdu_enable == _TRUE))
4505 RTW_INFO("Recv [%s] from direc link\n", __FUNCTION__);
4506 else
4507 #endif /* CONFIG_TDLS */
4508 if (!pmlmeinfo->HT_enable)
4509 return _SUCCESS;
4510
4511 action = frame_body[1];
4512 RTW_INFO("%s, action=%d\n", __FUNCTION__, action);
4513 switch (action) {
4514 case RTW_WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
4515
4516 _rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
4517 /* process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe)); */
4518 process_addba_req(padapter, (u8 *)&(pmlmeinfo->ADDBA_req), addr);
4519
4520 break;
4521
4522 case RTW_WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
4523
4524 /* status = frame_body[3] | (frame_body[4] << 8); */ /* endian issue */
4525 status = RTW_GET_LE16(&frame_body[3]);
4526 tid = ((frame_body[5] >> 2) & 0x7);
4527 if (status == 0) {
4528 /* successful */
4529 RTW_INFO("agg_enable for TID=%d\n", tid);
4530 psta->htpriv.agg_enable_bitmap |= 1 << tid;
4531 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
4532 /* amsdu in ampdu */
4533 if (pregpriv->tx_ampdu_amsdu == 0)
4534 psta->htpriv.tx_amsdu_enable = _FALSE;
4535 else if (pregpriv->tx_ampdu_amsdu == 1)
4536 psta->htpriv.tx_amsdu_enable = _TRUE;
4537 else {
4538 if (frame_body[5] & 1)
4539 psta->htpriv.tx_amsdu_enable = _TRUE;
4540 }
4541 } else
4542 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
4543
4544 #ifdef CONFIG_AP_MODE
4545 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
4546 RTW_INFO("%s alive check - rx ADDBA response\n", __func__);
4547 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
4548 psta->expire_to = pstapriv->expire_to;
4549 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
4550 }
4551 #endif
4552
4553 /* RTW_INFO("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap); */
4554 break;
4555
4556 case RTW_WLAN_ACTION_DELBA: /* DELBA */
4557 if ((frame_body[3] & BIT(3)) == 0) {
4558 psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
4559 psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
4560
4561 /* reason_code = frame_body[4] | (frame_body[5] << 8); */
4562 reason_code = RTW_GET_LE16(&frame_body[4]);
4563 } else if ((frame_body[3] & BIT(3)) == BIT(3)) {
4564 tid = (frame_body[3] >> 4) & 0x0F;
4565
4566 preorder_ctrl = &psta->recvreorder_ctrl[tid];
4567 preorder_ctrl->enable = _FALSE;
4568 preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
4569 }
4570
4571 RTW_INFO("%s(): DELBA: %x(%x)\n", __FUNCTION__, pmlmeinfo->agg_enable_bitmap, reason_code);
4572 /* todo: how to notify the host while receiving DELETE BA */
4573 break;
4574
4575 default:
4576 break;
4577 }
4578 }
4579 #endif /* CONFIG_80211N_HT */
4580 return _SUCCESS;
4581 }
4582
4583 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
rtw_build_vendor_ie(_adapter * padapter,unsigned char ** pframe,u8 mgmt_frame_tyte)4584 u32 rtw_build_vendor_ie(_adapter *padapter , unsigned char **pframe , u8 mgmt_frame_tyte)
4585 {
4586 int vendor_ie_num = 0;
4587 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4588 u32 len = 0;
4589
4590 for (vendor_ie_num = 0 ; vendor_ie_num < WLAN_MAX_VENDOR_IE_NUM ; vendor_ie_num++) {
4591 if (pmlmepriv->vendor_ielen[vendor_ie_num] > 0 && pmlmepriv->vendor_ie_mask[vendor_ie_num] & mgmt_frame_tyte) {
4592 _rtw_memcpy(*pframe , pmlmepriv->vendor_ie[vendor_ie_num] , pmlmepriv->vendor_ielen[vendor_ie_num]);
4593 *pframe += pmlmepriv->vendor_ielen[vendor_ie_num];
4594 len += pmlmepriv->vendor_ielen[vendor_ie_num];
4595 }
4596 }
4597
4598 return len;
4599 }
4600 #endif
4601
4602 #ifdef CONFIG_P2P
get_reg_classes_full_count(struct p2p_channels * channel_list)4603 int get_reg_classes_full_count(struct p2p_channels *channel_list)
4604 {
4605 int cnt = 0;
4606 int i;
4607
4608 for (i = 0; i < channel_list->reg_classes; i++)
4609 cnt += channel_list->reg_class[i].channels;
4610
4611 return cnt;
4612 }
4613
issue_p2p_GO_request(_adapter * padapter,u8 * raddr)4614 void issue_p2p_GO_request(_adapter *padapter, u8 *raddr)
4615 {
4616 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
4617 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4618 u8 action = P2P_PUB_ACTION_ACTION;
4619 u32 p2poui = cpu_to_be32(P2POUI);
4620 u8 oui_subtype = P2P_GO_NEGO_REQ;
4621 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
4622 u8 wpsielen = 0, p2pielen = 0;
4623 u16 len_channellist_attr = 0;
4624 #ifdef CONFIG_WFD
4625 u32 wfdielen = 0;
4626 #endif
4627
4628 struct xmit_frame *pmgntframe;
4629 struct pkt_attrib *pattrib;
4630 unsigned char *pframe;
4631 struct rtw_ieee80211_hdr *pwlanhdr;
4632 unsigned short *fctrl;
4633 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4634 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4635 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4636
4637
4638 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4639 if (pmgntframe == NULL)
4640 return;
4641
4642 RTW_INFO("[%s] In\n", __FUNCTION__);
4643 /* update attribute */
4644 pattrib = &pmgntframe->attrib;
4645 update_mgntframe_attrib(padapter, pattrib);
4646
4647 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4648
4649 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4650 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4651
4652 fctrl = &(pwlanhdr->frame_ctl);
4653 *(fctrl) = 0;
4654
4655 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4656 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4657 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4658
4659 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4660 pmlmeext->mgnt_seq++;
4661 set_frame_sub_type(pframe, WIFI_ACTION);
4662
4663 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4664 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4665
4666 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4667 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4668 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4669 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4670 pwdinfo->negotiation_dialog_token = 1; /* Initialize the dialog value */
4671 pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
4672
4673
4674
4675 /* WPS Section */
4676 wpsielen = 0;
4677 /* WPS OUI */
4678 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
4679 wpsielen += 4;
4680
4681 /* WPS version */
4682 /* Type: */
4683 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
4684 wpsielen += 2;
4685
4686 /* Length: */
4687 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4688 wpsielen += 2;
4689
4690 /* Value: */
4691 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4692
4693 /* Device Password ID */
4694 /* Type: */
4695 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
4696 wpsielen += 2;
4697
4698 /* Length: */
4699 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
4700 wpsielen += 2;
4701
4702 /* Value: */
4703
4704 if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN)
4705 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
4706 else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN)
4707 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
4708 else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC)
4709 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
4710
4711 wpsielen += 2;
4712
4713 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
4714
4715
4716 /* P2P IE Section. */
4717
4718 /* P2P OUI */
4719 p2pielen = 0;
4720 p2pie[p2pielen++] = 0x50;
4721 p2pie[p2pielen++] = 0x6F;
4722 p2pie[p2pielen++] = 0x9A;
4723 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
4724
4725 /* Commented by Albert 20110306 */
4726 /* According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes */
4727 /* 1. P2P Capability */
4728 /* 2. Group Owner Intent */
4729 /* 3. Configuration Timeout */
4730 /* 4. Listen Channel */
4731 /* 5. Extended Listen Timing */
4732 /* 6. Intended P2P Interface Address */
4733 /* 7. Channel List */
4734 /* 8. P2P Device Info */
4735 /* 9. Operating Channel */
4736
4737
4738 /* P2P Capability */
4739 /* Type: */
4740 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
4741
4742 /* Length: */
4743 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4744 p2pielen += 2;
4745
4746 /* Value: */
4747 /* Device Capability Bitmap, 1 byte */
4748 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
4749
4750 /* Group Capability Bitmap, 1 byte */
4751 if (pwdinfo->persistent_supported)
4752 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4753 else
4754 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
4755
4756
4757 /* Group Owner Intent */
4758 /* Type: */
4759 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
4760
4761 /* Length: */
4762 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4763 p2pielen += 2;
4764
4765 /* Value: */
4766 /* Todo the tie breaker bit. */
4767 p2pie[p2pielen++] = ((pwdinfo->intent << 1) & 0xFE);
4768
4769 /* Configuration Timeout */
4770 /* Type: */
4771 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
4772
4773 /* Length: */
4774 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4775 p2pielen += 2;
4776
4777 /* Value: */
4778 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
4779 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
4780
4781
4782 /* Listen Channel */
4783 /* Type: */
4784 p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
4785
4786 /* Length: */
4787 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4788 p2pielen += 2;
4789
4790 /* Value: */
4791 /* Country String */
4792 p2pie[p2pielen++] = 'X';
4793 p2pie[p2pielen++] = 'X';
4794
4795 /* The third byte should be set to 0x04. */
4796 /* Described in the "Operating Channel Attribute" section. */
4797 p2pie[p2pielen++] = 0x04;
4798
4799 /* Operating Class */
4800 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
4801
4802 /* Channel Number */
4803 p2pie[p2pielen++] = pwdinfo->listen_channel; /* listening channel number */
4804
4805
4806 /* Extended Listen Timing ATTR */
4807 /* Type: */
4808 p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
4809
4810 /* Length: */
4811 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
4812 p2pielen += 2;
4813
4814 /* Value: */
4815 /* Availability Period */
4816 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
4817 p2pielen += 2;
4818
4819 /* Availability Interval */
4820 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
4821 p2pielen += 2;
4822
4823
4824 /* Intended P2P Interface Address */
4825 /* Type: */
4826 p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
4827
4828 /* Length: */
4829 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
4830 p2pielen += 2;
4831
4832 /* Value: */
4833 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4834 p2pielen += ETH_ALEN;
4835
4836
4837 /* Channel List */
4838 /* Type: */
4839 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
4840
4841 /* Length: */
4842 /* Country String(3) */
4843 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
4844 /* + number of channels in all classes */
4845 len_channellist_attr = 3
4846 + (1 + 1) * (u16)(ch_list->reg_classes)
4847 + get_reg_classes_full_count(ch_list);
4848
4849 #ifdef CONFIG_CONCURRENT_MODE
4850 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4851 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
4852 else
4853 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4854 #else
4855
4856 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4857
4858 #endif
4859 p2pielen += 2;
4860
4861 /* Value: */
4862 /* Country String */
4863 p2pie[p2pielen++] = 'X';
4864 p2pie[p2pielen++] = 'X';
4865
4866 /* The third byte should be set to 0x04. */
4867 /* Described in the "Operating Channel Attribute" section. */
4868 p2pie[p2pielen++] = 0x04;
4869
4870 /* Channel Entry List */
4871
4872 #ifdef CONFIG_CONCURRENT_MODE
4873 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
4874 u8 union_ch = rtw_mi_get_union_chan(padapter);
4875
4876 /* Operating Class */
4877 if (union_ch > 14) {
4878 if (union_ch >= 149)
4879 p2pie[p2pielen++] = 0x7c;
4880 else
4881 p2pie[p2pielen++] = 0x73;
4882 } else
4883 p2pie[p2pielen++] = 0x51;
4884
4885
4886 /* Number of Channels */
4887 /* Just support 1 channel and this channel is AP's channel */
4888 p2pie[p2pielen++] = 1;
4889
4890 /* Channel List */
4891 p2pie[p2pielen++] = union_ch;
4892 } else
4893 #endif /* CONFIG_CONCURRENT_MODE */
4894 {
4895 int i, j;
4896 for (j = 0; j < ch_list->reg_classes; j++) {
4897 /* Operating Class */
4898 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
4899
4900 /* Number of Channels */
4901 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
4902
4903 /* Channel List */
4904 for (i = 0; i < ch_list->reg_class[j].channels; i++)
4905 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
4906 }
4907 }
4908
4909 /* Device Info */
4910 /* Type: */
4911 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
4912
4913 /* Length: */
4914 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
4915 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
4916 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
4917 p2pielen += 2;
4918
4919 /* Value: */
4920 /* P2P Device Address */
4921 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4922 p2pielen += ETH_ALEN;
4923
4924 /* Config Method */
4925 /* This field should be big endian. Noted by P2P specification. */
4926
4927 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
4928
4929 p2pielen += 2;
4930
4931 /* Primary Device Type */
4932 /* Category ID */
4933 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4934 p2pielen += 2;
4935
4936 /* OUI */
4937 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
4938 p2pielen += 4;
4939
4940 /* Sub Category ID */
4941 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4942 p2pielen += 2;
4943
4944 /* Number of Secondary Device Types */
4945 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
4946
4947 /* Device Name */
4948 /* Type: */
4949 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4950 p2pielen += 2;
4951
4952 /* Length: */
4953 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
4954 p2pielen += 2;
4955
4956 /* Value: */
4957 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
4958 p2pielen += pwdinfo->device_name_len;
4959
4960
4961 /* Operating Channel */
4962 /* Type: */
4963 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
4964
4965 /* Length: */
4966 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4967 p2pielen += 2;
4968
4969 /* Value: */
4970 /* Country String */
4971 p2pie[p2pielen++] = 'X';
4972 p2pie[p2pielen++] = 'X';
4973
4974 /* The third byte should be set to 0x04. */
4975 /* Described in the "Operating Channel Attribute" section. */
4976 p2pie[p2pielen++] = 0x04;
4977
4978 /* Operating Class */
4979 if (pwdinfo->operating_channel <= 14) {
4980 /* Operating Class */
4981 p2pie[p2pielen++] = 0x51;
4982 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
4983 /* Operating Class */
4984 p2pie[p2pielen++] = 0x73;
4985 } else {
4986 /* Operating Class */
4987 p2pie[p2pielen++] = 0x7c;
4988 }
4989
4990 /* Channel Number */
4991 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
4992
4993 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
4994
4995 #ifdef CONFIG_WFD
4996 wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
4997 pframe += wfdielen;
4998 pattrib->pktlen += wfdielen;
4999 #endif
5000
5001 pattrib->last_txcmdsz = pattrib->pktlen;
5002
5003 dump_mgntframe(padapter, pmgntframe);
5004
5005 return;
5006
5007 }
5008
5009
issue_p2p_GO_response(_adapter * padapter,u8 * raddr,u8 * frame_body,uint len,u8 result)5010 void issue_p2p_GO_response(_adapter *padapter, u8 *raddr, u8 *frame_body, uint len, u8 result)
5011 {
5012 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
5013 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5014 u8 action = P2P_PUB_ACTION_ACTION;
5015 u32 p2poui = cpu_to_be32(P2POUI);
5016 u8 oui_subtype = P2P_GO_NEGO_RESP;
5017 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
5018 u8 p2pielen = 0;
5019 uint wpsielen = 0;
5020 u16 wps_devicepassword_id = 0x0000;
5021 uint wps_devicepassword_id_len = 0;
5022 u16 len_channellist_attr = 0;
5023
5024 struct xmit_frame *pmgntframe;
5025 struct pkt_attrib *pattrib;
5026 unsigned char *pframe;
5027 struct rtw_ieee80211_hdr *pwlanhdr;
5028 unsigned short *fctrl;
5029 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5030 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5031 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5032
5033 #ifdef CONFIG_WFD
5034 u32 wfdielen = 0;
5035 #endif
5036
5037 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5038 if (pmgntframe == NULL)
5039 return;
5040
5041 RTW_INFO("[%s] In, result = %d\n", __FUNCTION__, result);
5042 /* update attribute */
5043 pattrib = &pmgntframe->attrib;
5044 update_mgntframe_attrib(padapter, pattrib);
5045
5046 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5047
5048 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5049 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5050
5051 fctrl = &(pwlanhdr->frame_ctl);
5052 *(fctrl) = 0;
5053
5054 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5055 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5056 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
5057
5058 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5059 pmlmeext->mgnt_seq++;
5060 set_frame_sub_type(pframe, WIFI_ACTION);
5061
5062 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5063 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5064
5065 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5066 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5067 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5068 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5069 pwdinfo->negotiation_dialog_token = frame_body[7]; /* The Dialog Token of provisioning discovery request frame. */
5070 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
5071
5072 /* Commented by Albert 20110328 */
5073 /* Try to get the device password ID from the WPS IE of group negotiation request frame */
5074 /* WiFi Direct test plan 5.1.15 */
5075 rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
5076 wps_devicepassword_id_len = sizeof(wps_devicepassword_id);
5077 rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8 *) &wps_devicepassword_id, &wps_devicepassword_id_len);
5078 wps_devicepassword_id = be16_to_cpu(wps_devicepassword_id);
5079
5080 _rtw_memset(wpsie, 0x00, 255);
5081 wpsielen = 0;
5082
5083 /* WPS Section */
5084 wpsielen = 0;
5085 /* WPS OUI */
5086 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
5087 wpsielen += 4;
5088
5089 /* WPS version */
5090 /* Type: */
5091 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5092 wpsielen += 2;
5093
5094 /* Length: */
5095 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5096 wpsielen += 2;
5097
5098 /* Value: */
5099 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
5100
5101 /* Device Password ID */
5102 /* Type: */
5103 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
5104 wpsielen += 2;
5105
5106 /* Length: */
5107 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
5108 wpsielen += 2;
5109
5110 /* Value: */
5111 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
5112 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
5113 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
5114 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
5115 else
5116 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
5117 wpsielen += 2;
5118
5119 /* Commented by Kurt 20120113 */
5120 /* If some device wants to do p2p handshake without sending prov_disc_req */
5121 /* We have to get peer_req_cm from here. */
5122 if (_rtw_memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) {
5123 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
5124 _rtw_memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
5125 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
5126 _rtw_memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
5127 else
5128 _rtw_memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
5129 }
5130
5131 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
5132
5133
5134 /* P2P IE Section. */
5135
5136 /* P2P OUI */
5137 p2pielen = 0;
5138 p2pie[p2pielen++] = 0x50;
5139 p2pie[p2pielen++] = 0x6F;
5140 p2pie[p2pielen++] = 0x9A;
5141 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
5142
5143 /* Commented by Albert 20100908 */
5144 /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
5145 /* 1. Status */
5146 /* 2. P2P Capability */
5147 /* 3. Group Owner Intent */
5148 /* 4. Configuration Timeout */
5149 /* 5. Operating Channel */
5150 /* 6. Intended P2P Interface Address */
5151 /* 7. Channel List */
5152 /* 8. Device Info */
5153 /* 9. Group ID ( Only GO ) */
5154
5155
5156 /* ToDo: */
5157
5158 /* P2P Status */
5159 /* Type: */
5160 p2pie[p2pielen++] = P2P_ATTR_STATUS;
5161
5162 /* Length: */
5163 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5164 p2pielen += 2;
5165
5166 /* Value: */
5167 p2pie[p2pielen++] = result;
5168
5169 /* P2P Capability */
5170 /* Type: */
5171 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
5172
5173 /* Length: */
5174 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5175 p2pielen += 2;
5176
5177 /* Value: */
5178 /* Device Capability Bitmap, 1 byte */
5179
5180 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
5181 /* Commented by Albert 2011/03/08 */
5182 /* According to the P2P specification */
5183 /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
5184 p2pie[p2pielen++] = 0;
5185 } else {
5186 /* Be group owner or meet the error case */
5187 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
5188 }
5189
5190 /* Group Capability Bitmap, 1 byte */
5191 if (pwdinfo->persistent_supported)
5192 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
5193 else
5194 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
5195
5196 /* Group Owner Intent */
5197 /* Type: */
5198 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
5199
5200 /* Length: */
5201 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5202 p2pielen += 2;
5203
5204 /* Value: */
5205 if (pwdinfo->peer_intent & 0x01) {
5206 /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
5207 p2pie[p2pielen++] = (pwdinfo->intent << 1);
5208 } else {
5209 /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
5210 p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
5211 }
5212
5213
5214 /* Configuration Timeout */
5215 /* Type: */
5216 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
5217
5218 /* Length: */
5219 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5220 p2pielen += 2;
5221
5222 /* Value: */
5223 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
5224 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
5225
5226 /* Operating Channel */
5227 /* Type: */
5228 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5229
5230 /* Length: */
5231 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5232 p2pielen += 2;
5233
5234 /* Value: */
5235 /* Country String */
5236 p2pie[p2pielen++] = 'X';
5237 p2pie[p2pielen++] = 'X';
5238
5239 /* The third byte should be set to 0x04. */
5240 /* Described in the "Operating Channel Attribute" section. */
5241 p2pie[p2pielen++] = 0x04;
5242
5243 /* Operating Class */
5244 if (pwdinfo->operating_channel <= 14) {
5245 /* Operating Class */
5246 p2pie[p2pielen++] = 0x51;
5247 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
5248 /* Operating Class */
5249 p2pie[p2pielen++] = 0x73;
5250 } else {
5251 /* Operating Class */
5252 p2pie[p2pielen++] = 0x7c;
5253 }
5254
5255 /* Channel Number */
5256 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
5257
5258 /* Intended P2P Interface Address */
5259 /* Type: */
5260 p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
5261
5262 /* Length: */
5263 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
5264 p2pielen += 2;
5265
5266 /* Value: */
5267 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5268 p2pielen += ETH_ALEN;
5269
5270 /* Channel List */
5271 /* Type: */
5272 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5273
5274 /* Country String(3) */
5275 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
5276 /* + number of channels in all classes */
5277 len_channellist_attr = 3
5278 + (1 + 1) * (u16)ch_list->reg_classes
5279 + get_reg_classes_full_count(ch_list);
5280
5281 #ifdef CONFIG_CONCURRENT_MODE
5282 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5283 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
5284 else
5285 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5286 #else
5287 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5288
5289 #endif
5290 p2pielen += 2;
5291
5292 /* Value: */
5293 /* Country String */
5294 p2pie[p2pielen++] = 'X';
5295 p2pie[p2pielen++] = 'X';
5296
5297 /* The third byte should be set to 0x04. */
5298 /* Described in the "Operating Channel Attribute" section. */
5299 p2pie[p2pielen++] = 0x04;
5300
5301 /* Channel Entry List */
5302
5303 #ifdef CONFIG_CONCURRENT_MODE
5304 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
5305
5306 u8 union_chan = rtw_mi_get_union_chan(padapter);
5307
5308 /*Operating Class*/
5309 if (union_chan > 14) {
5310 if (union_chan >= 149)
5311 p2pie[p2pielen++] = 0x7c;
5312 else
5313 p2pie[p2pielen++] = 0x73;
5314
5315 } else
5316 p2pie[p2pielen++] = 0x51;
5317
5318 /* Number of Channels
5319 Just support 1 channel and this channel is AP's channel*/
5320 p2pie[p2pielen++] = 1;
5321
5322 /*Channel List*/
5323 p2pie[p2pielen++] = union_chan;
5324 } else
5325 #endif /* CONFIG_CONCURRENT_MODE */
5326 {
5327 int i, j;
5328 for (j = 0; j < ch_list->reg_classes; j++) {
5329 /* Operating Class */
5330 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
5331
5332 /* Number of Channels */
5333 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
5334
5335 /* Channel List */
5336 for (i = 0; i < ch_list->reg_class[j].channels; i++)
5337 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
5338 }
5339 }
5340
5341 /* Device Info */
5342 /* Type: */
5343 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
5344
5345 /* Length: */
5346 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
5347 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
5348 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
5349 p2pielen += 2;
5350
5351 /* Value: */
5352 /* P2P Device Address */
5353 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5354 p2pielen += ETH_ALEN;
5355
5356 /* Config Method */
5357 /* This field should be big endian. Noted by P2P specification. */
5358
5359 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
5360
5361 p2pielen += 2;
5362
5363 /* Primary Device Type */
5364 /* Category ID */
5365 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5366 p2pielen += 2;
5367
5368 /* OUI */
5369 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
5370 p2pielen += 4;
5371
5372 /* Sub Category ID */
5373 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5374 p2pielen += 2;
5375
5376 /* Number of Secondary Device Types */
5377 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
5378
5379 /* Device Name */
5380 /* Type: */
5381 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5382 p2pielen += 2;
5383
5384 /* Length: */
5385 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
5386 p2pielen += 2;
5387
5388 /* Value: */
5389 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
5390 p2pielen += pwdinfo->device_name_len;
5391
5392 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5393 /* Group ID Attribute */
5394 /* Type: */
5395 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
5396
5397 /* Length: */
5398 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
5399 p2pielen += 2;
5400
5401 /* Value: */
5402 /* p2P Device Address */
5403 _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
5404 p2pielen += ETH_ALEN;
5405
5406 /* SSID */
5407 _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
5408 p2pielen += pwdinfo->nego_ssidlen;
5409
5410 }
5411
5412 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
5413
5414 #ifdef CONFIG_WFD
5415 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
5416 pframe += wfdielen;
5417 pattrib->pktlen += wfdielen;
5418 #endif
5419
5420 pattrib->last_txcmdsz = pattrib->pktlen;
5421
5422 dump_mgntframe(padapter, pmgntframe);
5423
5424 return;
5425
5426 }
5427
issue_p2p_GO_confirm(_adapter * padapter,u8 * raddr,u8 result)5428 void issue_p2p_GO_confirm(_adapter *padapter, u8 *raddr, u8 result)
5429 {
5430
5431 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5432 u8 action = P2P_PUB_ACTION_ACTION;
5433 u32 p2poui = cpu_to_be32(P2POUI);
5434 u8 oui_subtype = P2P_GO_NEGO_CONF;
5435 u8 p2pie[255] = { 0x00 };
5436 u8 p2pielen = 0;
5437
5438 struct xmit_frame *pmgntframe;
5439 struct pkt_attrib *pattrib;
5440 unsigned char *pframe;
5441 struct rtw_ieee80211_hdr *pwlanhdr;
5442 unsigned short *fctrl;
5443 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5444 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5445 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5446 #ifdef CONFIG_WFD
5447 u32 wfdielen = 0;
5448 #endif
5449
5450 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5451 if (pmgntframe == NULL)
5452 return;
5453
5454 RTW_INFO("[%s] In\n", __FUNCTION__);
5455 /* update attribute */
5456 pattrib = &pmgntframe->attrib;
5457 update_mgntframe_attrib(padapter, pattrib);
5458
5459 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5460
5461 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5462 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5463
5464 fctrl = &(pwlanhdr->frame_ctl);
5465 *(fctrl) = 0;
5466
5467 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5468 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5469 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
5470
5471 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5472 pmlmeext->mgnt_seq++;
5473 set_frame_sub_type(pframe, WIFI_ACTION);
5474
5475 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5476 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5477
5478 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5479 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5480 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5481 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5482 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
5483
5484
5485
5486 /* P2P IE Section. */
5487
5488 /* P2P OUI */
5489 p2pielen = 0;
5490 p2pie[p2pielen++] = 0x50;
5491 p2pie[p2pielen++] = 0x6F;
5492 p2pie[p2pielen++] = 0x9A;
5493 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
5494
5495 /* Commented by Albert 20110306 */
5496 /* According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes */
5497 /* 1. Status */
5498 /* 2. P2P Capability */
5499 /* 3. Operating Channel */
5500 /* 4. Channel List */
5501 /* 5. Group ID ( if this WiFi is GO ) */
5502
5503 /* P2P Status */
5504 /* Type: */
5505 p2pie[p2pielen++] = P2P_ATTR_STATUS;
5506
5507 /* Length: */
5508 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5509 p2pielen += 2;
5510
5511 /* Value: */
5512 p2pie[p2pielen++] = result;
5513
5514 /* P2P Capability */
5515 /* Type: */
5516 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
5517
5518 /* Length: */
5519 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5520 p2pielen += 2;
5521
5522 /* Value: */
5523 /* Device Capability Bitmap, 1 byte */
5524 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
5525
5526 /* Group Capability Bitmap, 1 byte */
5527 if (pwdinfo->persistent_supported)
5528 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
5529 else
5530 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
5531
5532
5533 /* Operating Channel */
5534 /* Type: */
5535 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5536
5537 /* Length: */
5538 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5539 p2pielen += 2;
5540
5541 /* Value: */
5542 /* Country String */
5543 p2pie[p2pielen++] = 'X';
5544 p2pie[p2pielen++] = 'X';
5545
5546 /* The third byte should be set to 0x04. */
5547 /* Described in the "Operating Channel Attribute" section. */
5548 p2pie[p2pielen++] = 0x04;
5549
5550
5551 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
5552 if (pwdinfo->peer_operating_ch <= 14) {
5553 /* Operating Class */
5554 p2pie[p2pielen++] = 0x51;
5555 } else if ((pwdinfo->peer_operating_ch >= 36) && (pwdinfo->peer_operating_ch <= 48)) {
5556 /* Operating Class */
5557 p2pie[p2pielen++] = 0x73;
5558 } else {
5559 /* Operating Class */
5560 p2pie[p2pielen++] = 0x7c;
5561 }
5562
5563 p2pie[p2pielen++] = pwdinfo->peer_operating_ch;
5564 } else {
5565 if (pwdinfo->operating_channel <= 14) {
5566 /* Operating Class */
5567 p2pie[p2pielen++] = 0x51;
5568 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
5569 /* Operating Class */
5570 p2pie[p2pielen++] = 0x73;
5571 } else {
5572 /* Operating Class */
5573 p2pie[p2pielen++] = 0x7c;
5574 }
5575
5576 /* Channel Number */
5577 p2pie[p2pielen++] = pwdinfo->operating_channel; /* Use the listen channel as the operating channel */
5578 }
5579
5580
5581 /* Channel List */
5582 /* Type: */
5583 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5584
5585 *(u16 *)(p2pie + p2pielen) = 6;
5586 p2pielen += 2;
5587
5588 /* Country String */
5589 p2pie[p2pielen++] = 'X';
5590 p2pie[p2pielen++] = 'X';
5591
5592 /* The third byte should be set to 0x04. */
5593 /* Described in the "Operating Channel Attribute" section. */
5594 p2pie[p2pielen++] = 0x04;
5595
5596 /* Value: */
5597 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
5598 if (pwdinfo->peer_operating_ch <= 14) {
5599 /* Operating Class */
5600 p2pie[p2pielen++] = 0x51;
5601 } else if ((pwdinfo->peer_operating_ch >= 36) && (pwdinfo->peer_operating_ch <= 48)) {
5602 /* Operating Class */
5603 p2pie[p2pielen++] = 0x73;
5604 } else {
5605 /* Operating Class */
5606 p2pie[p2pielen++] = 0x7c;
5607 }
5608 p2pie[p2pielen++] = 1;
5609 p2pie[p2pielen++] = pwdinfo->peer_operating_ch;
5610 } else {
5611 if (pwdinfo->operating_channel <= 14) {
5612 /* Operating Class */
5613 p2pie[p2pielen++] = 0x51;
5614 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
5615 /* Operating Class */
5616 p2pie[p2pielen++] = 0x73;
5617 } else {
5618 /* Operating Class */
5619 p2pie[p2pielen++] = 0x7c;
5620 }
5621
5622 /* Channel Number */
5623 p2pie[p2pielen++] = 1;
5624 p2pie[p2pielen++] = pwdinfo->operating_channel; /* Use the listen channel as the operating channel */
5625 }
5626
5627 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5628 /* Group ID Attribute */
5629 /* Type: */
5630 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
5631
5632 /* Length: */
5633 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
5634 p2pielen += 2;
5635
5636 /* Value: */
5637 /* p2P Device Address */
5638 _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
5639 p2pielen += ETH_ALEN;
5640
5641 /* SSID */
5642 _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
5643 p2pielen += pwdinfo->nego_ssidlen;
5644 }
5645
5646 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
5647
5648 #ifdef CONFIG_WFD
5649 wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
5650 pframe += wfdielen;
5651 pattrib->pktlen += wfdielen;
5652 #endif
5653
5654 pattrib->last_txcmdsz = pattrib->pktlen;
5655
5656 dump_mgntframe(padapter, pmgntframe);
5657
5658 return;
5659
5660 }
5661
issue_p2p_invitation_request(_adapter * padapter,u8 * raddr)5662 void issue_p2p_invitation_request(_adapter *padapter, u8 *raddr)
5663 {
5664 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
5665 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5666 u8 action = P2P_PUB_ACTION_ACTION;
5667 u32 p2poui = cpu_to_be32(P2POUI);
5668 u8 oui_subtype = P2P_INVIT_REQ;
5669 u8 p2pie[255] = { 0x00 };
5670 u8 p2pielen = 0;
5671 u8 dialogToken = 3;
5672 u16 len_channellist_attr = 0;
5673 #ifdef CONFIG_WFD
5674 u32 wfdielen = 0;
5675 #endif
5676
5677 struct xmit_frame *pmgntframe;
5678 struct pkt_attrib *pattrib;
5679 unsigned char *pframe;
5680 struct rtw_ieee80211_hdr *pwlanhdr;
5681 unsigned short *fctrl;
5682 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5683 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5684 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5685
5686
5687 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5688 if (pmgntframe == NULL)
5689 return;
5690
5691 /* update attribute */
5692 pattrib = &pmgntframe->attrib;
5693 update_mgntframe_attrib(padapter, pattrib);
5694
5695 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5696
5697 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5698 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5699
5700 fctrl = &(pwlanhdr->frame_ctl);
5701 *(fctrl) = 0;
5702
5703 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5704 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5705 _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
5706
5707 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5708 pmlmeext->mgnt_seq++;
5709 set_frame_sub_type(pframe, WIFI_ACTION);
5710
5711 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5712 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5713
5714 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5715 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5716 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5717 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5718 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5719
5720 /* P2P IE Section. */
5721
5722 /* P2P OUI */
5723 p2pielen = 0;
5724 p2pie[p2pielen++] = 0x50;
5725 p2pie[p2pielen++] = 0x6F;
5726 p2pie[p2pielen++] = 0x9A;
5727 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
5728
5729 /* Commented by Albert 20101011 */
5730 /* According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes */
5731 /* 1. Configuration Timeout */
5732 /* 2. Invitation Flags */
5733 /* 3. Operating Channel ( Only GO ) */
5734 /* 4. P2P Group BSSID ( Should be included if I am the GO ) */
5735 /* 5. Channel List */
5736 /* 6. P2P Group ID */
5737 /* 7. P2P Device Info */
5738
5739 /* Configuration Timeout */
5740 /* Type: */
5741 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
5742
5743 /* Length: */
5744 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5745 p2pielen += 2;
5746
5747 /* Value: */
5748 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
5749 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
5750
5751 /* Invitation Flags */
5752 /* Type: */
5753 p2pie[p2pielen++] = P2P_ATTR_INVITATION_FLAGS;
5754
5755 /* Length: */
5756 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5757 p2pielen += 2;
5758
5759 /* Value: */
5760 p2pie[p2pielen++] = P2P_INVITATION_FLAGS_PERSISTENT;
5761
5762
5763 /* Operating Channel */
5764 /* Type: */
5765 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5766
5767 /* Length: */
5768 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5769 p2pielen += 2;
5770
5771 /* Value: */
5772 /* Country String */
5773 p2pie[p2pielen++] = 'X';
5774 p2pie[p2pielen++] = 'X';
5775
5776 /* The third byte should be set to 0x04. */
5777 /* Described in the "Operating Channel Attribute" section. */
5778 p2pie[p2pielen++] = 0x04;
5779
5780 /* Operating Class */
5781 if (pwdinfo->invitereq_info.operating_ch <= 14)
5782 p2pie[p2pielen++] = 0x51;
5783 else if ((pwdinfo->invitereq_info.operating_ch >= 36) && (pwdinfo->invitereq_info.operating_ch <= 48))
5784 p2pie[p2pielen++] = 0x73;
5785 else
5786 p2pie[p2pielen++] = 0x7c;
5787
5788 /* Channel Number */
5789 p2pie[p2pielen++] = pwdinfo->invitereq_info.operating_ch; /* operating channel number */
5790
5791 if (_rtw_memcmp(adapter_mac_addr(padapter), pwdinfo->invitereq_info.go_bssid, ETH_ALEN)) {
5792 /* P2P Group BSSID */
5793 /* Type: */
5794 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
5795
5796 /* Length: */
5797 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
5798 p2pielen += 2;
5799
5800 /* Value: */
5801 /* P2P Device Address for GO */
5802 _rtw_memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
5803 p2pielen += ETH_ALEN;
5804 }
5805
5806 /* Channel List */
5807 /* Type: */
5808 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5809
5810
5811 /* Length: */
5812 /* Country String(3) */
5813 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
5814 /* + number of channels in all classes */
5815 len_channellist_attr = 3
5816 + (1 + 1) * (u16)ch_list->reg_classes
5817 + get_reg_classes_full_count(ch_list);
5818
5819 #ifdef CONFIG_CONCURRENT_MODE
5820 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5821 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
5822 else
5823 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5824 #else
5825 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5826 #endif
5827 p2pielen += 2;
5828
5829 /* Value: */
5830 /* Country String */
5831 p2pie[p2pielen++] = 'X';
5832 p2pie[p2pielen++] = 'X';
5833
5834 /* The third byte should be set to 0x04. */
5835 /* Described in the "Operating Channel Attribute" section. */
5836 p2pie[p2pielen++] = 0x04;
5837
5838 /* Channel Entry List */
5839 #ifdef CONFIG_CONCURRENT_MODE
5840 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
5841 u8 union_ch = rtw_mi_get_union_chan(padapter);
5842
5843 /* Operating Class */
5844 if (union_ch > 14) {
5845 if (union_ch >= 149)
5846 p2pie[p2pielen++] = 0x7c;
5847 else
5848 p2pie[p2pielen++] = 0x73;
5849 } else
5850 p2pie[p2pielen++] = 0x51;
5851
5852
5853 /* Number of Channels */
5854 /* Just support 1 channel and this channel is AP's channel */
5855 p2pie[p2pielen++] = 1;
5856
5857 /* Channel List */
5858 p2pie[p2pielen++] = union_ch;
5859 } else
5860 #endif /* CONFIG_CONCURRENT_MODE */
5861 {
5862 int i, j;
5863 for (j = 0; j < ch_list->reg_classes; j++) {
5864 /* Operating Class */
5865 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
5866
5867 /* Number of Channels */
5868 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
5869
5870 /* Channel List */
5871 for (i = 0; i < ch_list->reg_class[j].channels; i++)
5872 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
5873 }
5874 }
5875
5876
5877 /* P2P Group ID */
5878 /* Type: */
5879 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
5880
5881 /* Length: */
5882 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(6 + pwdinfo->invitereq_info.ssidlen);
5883 p2pielen += 2;
5884
5885 /* Value: */
5886 /* P2P Device Address for GO */
5887 _rtw_memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
5888 p2pielen += ETH_ALEN;
5889
5890 /* SSID */
5891 _rtw_memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen);
5892 p2pielen += pwdinfo->invitereq_info.ssidlen;
5893
5894
5895 /* Device Info */
5896 /* Type: */
5897 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
5898
5899 /* Length: */
5900 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
5901 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
5902 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
5903 p2pielen += 2;
5904
5905 /* Value: */
5906 /* P2P Device Address */
5907 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5908 p2pielen += ETH_ALEN;
5909
5910 /* Config Method */
5911 /* This field should be big endian. Noted by P2P specification. */
5912 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
5913 p2pielen += 2;
5914
5915 /* Primary Device Type */
5916 /* Category ID */
5917 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5918 p2pielen += 2;
5919
5920 /* OUI */
5921 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
5922 p2pielen += 4;
5923
5924 /* Sub Category ID */
5925 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5926 p2pielen += 2;
5927
5928 /* Number of Secondary Device Types */
5929 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
5930
5931 /* Device Name */
5932 /* Type: */
5933 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5934 p2pielen += 2;
5935
5936 /* Length: */
5937 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
5938 p2pielen += 2;
5939
5940 /* Value: */
5941 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
5942 p2pielen += pwdinfo->device_name_len;
5943
5944 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
5945
5946 #ifdef CONFIG_WFD
5947 wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
5948 pframe += wfdielen;
5949 pattrib->pktlen += wfdielen;
5950 #endif
5951
5952 pattrib->last_txcmdsz = pattrib->pktlen;
5953
5954 dump_mgntframe(padapter, pmgntframe);
5955
5956 return;
5957
5958 }
5959
issue_p2p_invitation_response(_adapter * padapter,u8 * raddr,u8 dialogToken,u8 status_code)5960 void issue_p2p_invitation_response(_adapter *padapter, u8 *raddr, u8 dialogToken, u8 status_code)
5961 {
5962 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
5963 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5964 u8 action = P2P_PUB_ACTION_ACTION;
5965 u32 p2poui = cpu_to_be32(P2POUI);
5966 u8 oui_subtype = P2P_INVIT_RESP;
5967 u8 p2pie[255] = { 0x00 };
5968 u8 p2pielen = 0;
5969 u16 len_channellist_attr = 0;
5970 #ifdef CONFIG_WFD
5971 u32 wfdielen = 0;
5972 #endif
5973
5974 struct xmit_frame *pmgntframe;
5975 struct pkt_attrib *pattrib;
5976 unsigned char *pframe;
5977 struct rtw_ieee80211_hdr *pwlanhdr;
5978 unsigned short *fctrl;
5979 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5980 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5981 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5982
5983
5984 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5985 if (pmgntframe == NULL)
5986 return;
5987
5988 /* update attribute */
5989 pattrib = &pmgntframe->attrib;
5990 update_mgntframe_attrib(padapter, pattrib);
5991
5992 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5993
5994 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5995 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5996
5997 fctrl = &(pwlanhdr->frame_ctl);
5998 *(fctrl) = 0;
5999
6000 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
6001 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6002 _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
6003
6004 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6005 pmlmeext->mgnt_seq++;
6006 set_frame_sub_type(pframe, WIFI_ACTION);
6007
6008 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6009 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6010
6011 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
6012 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
6013 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
6014 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
6015 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
6016
6017 /* P2P IE Section. */
6018
6019 /* P2P OUI */
6020 p2pielen = 0;
6021 p2pie[p2pielen++] = 0x50;
6022 p2pie[p2pielen++] = 0x6F;
6023 p2pie[p2pielen++] = 0x9A;
6024 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
6025
6026 /* Commented by Albert 20101005 */
6027 /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
6028 /* 1. Status */
6029 /* 2. Configuration Timeout */
6030 /* 3. Operating Channel ( Only GO ) */
6031 /* 4. P2P Group BSSID ( Only GO ) */
6032 /* 5. Channel List */
6033
6034 /* P2P Status */
6035 /* Type: */
6036 p2pie[p2pielen++] = P2P_ATTR_STATUS;
6037
6038 /* Length: */
6039 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
6040 p2pielen += 2;
6041
6042 /* Value: */
6043 /* When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */
6044 /* Sent the event receiving the P2P Invitation Req frame to DMP UI. */
6045 /* DMP had to compare the MAC address to find out the profile. */
6046 /* So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */
6047 /* If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req */
6048 /* to NB to rebuild the persistent group. */
6049 p2pie[p2pielen++] = status_code;
6050
6051 /* Configuration Timeout */
6052 /* Type: */
6053 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
6054
6055 /* Length: */
6056 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
6057 p2pielen += 2;
6058
6059 /* Value: */
6060 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
6061 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
6062
6063 if (status_code == P2P_STATUS_SUCCESS) {
6064 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6065 /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
6066 /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
6067 /* First one is operating channel attribute. */
6068 /* Second one is P2P Group BSSID attribute. */
6069
6070 /* Operating Channel */
6071 /* Type: */
6072 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
6073
6074 /* Length: */
6075 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
6076 p2pielen += 2;
6077
6078 /* Value: */
6079 /* Country String */
6080 p2pie[p2pielen++] = 'X';
6081 p2pie[p2pielen++] = 'X';
6082
6083 /* The third byte should be set to 0x04. */
6084 /* Described in the "Operating Channel Attribute" section. */
6085 p2pie[p2pielen++] = 0x04;
6086
6087 /* Operating Class */
6088 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
6089
6090 /* Channel Number */
6091 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
6092
6093
6094 /* P2P Group BSSID */
6095 /* Type: */
6096 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
6097
6098 /* Length: */
6099 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
6100 p2pielen += 2;
6101
6102 /* Value: */
6103 /* P2P Device Address for GO */
6104 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
6105 p2pielen += ETH_ALEN;
6106
6107 }
6108
6109 /* Channel List */
6110 /* Type: */
6111 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
6112
6113 /* Length: */
6114 /* Country String(3) */
6115 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
6116 /* + number of channels in all classes */
6117 len_channellist_attr = 3
6118 + (1 + 1) * (u16)ch_list->reg_classes
6119 + get_reg_classes_full_count(ch_list);
6120
6121 #ifdef CONFIG_CONCURRENT_MODE
6122 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
6123 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
6124 else
6125 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
6126 #else
6127 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
6128 #endif
6129 p2pielen += 2;
6130
6131 /* Value: */
6132 /* Country String */
6133 p2pie[p2pielen++] = 'X';
6134 p2pie[p2pielen++] = 'X';
6135
6136 /* The third byte should be set to 0x04. */
6137 /* Described in the "Operating Channel Attribute" section. */
6138 p2pie[p2pielen++] = 0x04;
6139
6140 /* Channel Entry List */
6141 #ifdef CONFIG_CONCURRENT_MODE
6142 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
6143 u8 union_ch = rtw_mi_get_union_chan(padapter);
6144
6145 /* Operating Class */
6146 if (union_ch > 14) {
6147 if (union_ch >= 149)
6148 p2pie[p2pielen++] = 0x7c;
6149 else
6150 p2pie[p2pielen++] = 0x73;
6151 } else
6152 p2pie[p2pielen++] = 0x51;
6153
6154
6155 /* Number of Channels */
6156 /* Just support 1 channel and this channel is AP's channel */
6157 p2pie[p2pielen++] = 1;
6158
6159 /* Channel List */
6160 p2pie[p2pielen++] = union_ch;
6161 } else
6162 #endif /* CONFIG_CONCURRENT_MODE */
6163 {
6164 int i, j;
6165 for (j = 0; j < ch_list->reg_classes; j++) {
6166 /* Operating Class */
6167 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
6168
6169 /* Number of Channels */
6170 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
6171
6172 /* Channel List */
6173 for (i = 0; i < ch_list->reg_class[j].channels; i++)
6174 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
6175 }
6176 }
6177 }
6178
6179 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
6180
6181 #ifdef CONFIG_WFD
6182 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
6183 pframe += wfdielen;
6184 pattrib->pktlen += wfdielen;
6185 #endif
6186
6187 pattrib->last_txcmdsz = pattrib->pktlen;
6188
6189 dump_mgntframe(padapter, pmgntframe);
6190
6191 return;
6192
6193 }
6194
issue_p2p_provision_request(_adapter * padapter,u8 * pssid,u8 ussidlen,u8 * pdev_raddr)6195 void issue_p2p_provision_request(_adapter *padapter, u8 *pssid, u8 ussidlen, u8 *pdev_raddr)
6196 {
6197 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
6198 u8 action = P2P_PUB_ACTION_ACTION;
6199 u8 dialogToken = 1;
6200 u32 p2poui = cpu_to_be32(P2POUI);
6201 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
6202 u8 wpsie[100] = { 0x00 };
6203 u8 wpsielen = 0;
6204 u32 p2pielen = 0;
6205 #ifdef CONFIG_WFD
6206 u32 wfdielen = 0;
6207 #endif
6208
6209 struct xmit_frame *pmgntframe;
6210 struct pkt_attrib *pattrib;
6211 unsigned char *pframe;
6212 struct rtw_ieee80211_hdr *pwlanhdr;
6213 unsigned short *fctrl;
6214 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6215 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6216 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6217
6218
6219 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
6220 if (pmgntframe == NULL)
6221 return;
6222
6223 RTW_INFO("[%s] In\n", __FUNCTION__);
6224 /* update attribute */
6225 pattrib = &pmgntframe->attrib;
6226 update_mgntframe_attrib(padapter, pattrib);
6227
6228 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6229
6230 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6231 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6232
6233 fctrl = &(pwlanhdr->frame_ctl);
6234 *(fctrl) = 0;
6235
6236 _rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
6237 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6238 _rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
6239
6240 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6241 pmlmeext->mgnt_seq++;
6242 set_frame_sub_type(pframe, WIFI_ACTION);
6243
6244 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6245 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6246
6247 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
6248 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
6249 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
6250 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
6251 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
6252
6253 p2pielen = build_prov_disc_request_p2p_ie(pwdinfo, pframe, pssid, ussidlen, pdev_raddr);
6254
6255 pframe += p2pielen;
6256 pattrib->pktlen += p2pielen;
6257
6258 wpsielen = 0;
6259 /* WPS OUI */
6260 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6261 wpsielen += 4;
6262
6263 /* WPS version */
6264 /* Type: */
6265 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6266 wpsielen += 2;
6267
6268 /* Length: */
6269 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6270 wpsielen += 2;
6271
6272 /* Value: */
6273 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
6274
6275 /* Config Method */
6276 /* Type: */
6277 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
6278 wpsielen += 2;
6279
6280 /* Length: */
6281 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
6282 wpsielen += 2;
6283
6284 /* Value: */
6285 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
6286 wpsielen += 2;
6287
6288 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
6289
6290
6291 #ifdef CONFIG_WFD
6292 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
6293 pframe += wfdielen;
6294 pattrib->pktlen += wfdielen;
6295 #endif
6296
6297 pattrib->last_txcmdsz = pattrib->pktlen;
6298
6299 dump_mgntframe(padapter, pmgntframe);
6300
6301 return;
6302
6303 }
6304
6305
is_matched_in_profilelist(u8 * peermacaddr,struct profile_info * profileinfo)6306 u8 is_matched_in_profilelist(u8 *peermacaddr, struct profile_info *profileinfo)
6307 {
6308 u8 i, match_result = 0;
6309
6310 RTW_INFO("[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
6311 peermacaddr[0], peermacaddr[1], peermacaddr[2], peermacaddr[3], peermacaddr[4], peermacaddr[5]);
6312
6313 for (i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++) {
6314 RTW_INFO("[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
6315 profileinfo->peermac[0], profileinfo->peermac[1], profileinfo->peermac[2], profileinfo->peermac[3], profileinfo->peermac[4], profileinfo->peermac[5]);
6316 if (_rtw_memcmp(peermacaddr, profileinfo->peermac, ETH_ALEN)) {
6317 match_result = 1;
6318 RTW_INFO("[%s] Match!\n", __FUNCTION__);
6319 break;
6320 }
6321 }
6322
6323 return match_result ;
6324 }
6325
issue_probersp_p2p(_adapter * padapter,unsigned char * da)6326 void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
6327 {
6328 struct xmit_frame *pmgntframe;
6329 struct pkt_attrib *pattrib;
6330 unsigned char *pframe;
6331 struct rtw_ieee80211_hdr *pwlanhdr;
6332 unsigned short *fctrl;
6333 unsigned char *mac;
6334 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6335 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6336 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6337 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
6338 u16 beacon_interval = 100;
6339 u16 capInfo = 0;
6340 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6341 u8 wpsie[255] = { 0x00 };
6342 u32 wpsielen = 0, p2pielen = 0;
6343 #ifdef CONFIG_WFD
6344 u32 wfdielen = 0;
6345 #endif
6346
6347 /* RTW_INFO("%s\n", __FUNCTION__); */
6348
6349 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
6350 if (pmgntframe == NULL)
6351 return;
6352
6353 /* update attribute */
6354 pattrib = &pmgntframe->attrib;
6355 update_mgntframe_attrib(padapter, pattrib);
6356
6357 if (IS_CCK_RATE(pattrib->rate)) {
6358 /* force OFDM 6M rate */
6359 pattrib->rate = MGN_6M;
6360 pattrib->raid = rtw_get_mgntframe_raid(padapter, WIRELESS_11G);
6361 }
6362
6363 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6364
6365 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6366 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6367
6368 mac = adapter_mac_addr(padapter);
6369
6370 fctrl = &(pwlanhdr->frame_ctl);
6371 *(fctrl) = 0;
6372 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6373 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6374
6375 /* Use the device address for BSSID field. */
6376 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6377
6378 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6379 pmlmeext->mgnt_seq++;
6380 set_frame_sub_type(fctrl, WIFI_PROBERSP);
6381
6382 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6383 pattrib->pktlen = pattrib->hdrlen;
6384 pframe += pattrib->hdrlen;
6385
6386 /* timestamp will be inserted by hardware */
6387 pframe += 8;
6388 pattrib->pktlen += 8;
6389
6390 /* beacon interval: 2 bytes */
6391 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6392 pframe += 2;
6393 pattrib->pktlen += 2;
6394
6395 /* capability info: 2 bytes */
6396 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6397 capInfo |= cap_ShortPremble;
6398 capInfo |= cap_ShortSlot;
6399
6400 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6401 pframe += 2;
6402 pattrib->pktlen += 2;
6403
6404
6405 /* SSID */
6406 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
6407
6408 /* supported rates... */
6409 /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6410 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
6411
6412 /* DS parameter set */
6413 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
6414
6415 #ifdef CONFIG_IOCTL_CFG80211
6416 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
6417 if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6418 /* WPS IE */
6419 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6420 pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
6421 pframe += pmlmepriv->wps_probe_resp_ie_len;
6422
6423 /* P2P IE */
6424 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6425 pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6426 pframe += pmlmepriv->p2p_probe_resp_ie_len;
6427 }
6428 } else
6429 #endif /* CONFIG_IOCTL_CFG80211 */
6430 {
6431
6432 /* Todo: WPS IE */
6433 /* Noted by Albert 20100907 */
6434 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6435
6436 wpsielen = 0;
6437 /* WPS OUI */
6438 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6439 wpsielen += 4;
6440
6441 /* WPS version */
6442 /* Type: */
6443 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6444 wpsielen += 2;
6445
6446 /* Length: */
6447 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6448 wpsielen += 2;
6449
6450 /* Value: */
6451 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
6452
6453 /* WiFi Simple Config State */
6454 /* Type: */
6455 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6456 wpsielen += 2;
6457
6458 /* Length: */
6459 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6460 wpsielen += 2;
6461
6462 /* Value: */
6463 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
6464
6465 /* Response Type */
6466 /* Type: */
6467 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6468 wpsielen += 2;
6469
6470 /* Length: */
6471 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6472 wpsielen += 2;
6473
6474 /* Value: */
6475 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6476
6477 /* UUID-E */
6478 /* Type: */
6479 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6480 wpsielen += 2;
6481
6482 /* Length: */
6483 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6484 wpsielen += 2;
6485
6486 /* Value: */
6487 if (pwdinfo->external_uuid == 0) {
6488 _rtw_memset(wpsie + wpsielen, 0x0, 16);
6489 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6490 } else
6491 _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6492 wpsielen += 0x10;
6493
6494 /* Manufacturer */
6495 /* Type: */
6496 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6497 wpsielen += 2;
6498
6499 /* Length: */
6500 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6501 wpsielen += 2;
6502
6503 /* Value: */
6504 _rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6505 wpsielen += 7;
6506
6507 /* Model Name */
6508 /* Type: */
6509 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
6510 wpsielen += 2;
6511
6512 /* Length: */
6513 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
6514 wpsielen += 2;
6515
6516 /* Value: */
6517 _rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
6518 wpsielen += 6;
6519
6520 /* Model Number */
6521 /* Type: */
6522 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
6523 wpsielen += 2;
6524
6525 /* Length: */
6526 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6527 wpsielen += 2;
6528
6529 /* Value: */
6530 wpsie[wpsielen++] = 0x31; /* character 1 */
6531
6532 /* Serial Number */
6533 /* Type: */
6534 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
6535 wpsielen += 2;
6536
6537 /* Length: */
6538 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
6539 wpsielen += 2;
6540
6541 /* Value: */
6542 _rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
6543 wpsielen += ETH_ALEN;
6544
6545 /* Primary Device Type */
6546 /* Type: */
6547 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6548 wpsielen += 2;
6549
6550 /* Length: */
6551 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6552 wpsielen += 2;
6553
6554 /* Value: */
6555 /* Category ID */
6556 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6557 wpsielen += 2;
6558
6559 /* OUI */
6560 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6561 wpsielen += 4;
6562
6563 /* Sub Category ID */
6564 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6565 wpsielen += 2;
6566
6567 /* Device Name */
6568 /* Type: */
6569 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6570 wpsielen += 2;
6571
6572 /* Length: */
6573 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
6574 wpsielen += 2;
6575
6576 /* Value: */
6577 _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
6578 wpsielen += pwdinfo->device_name_len;
6579
6580 /* Config Method */
6581 /* Type: */
6582 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
6583 wpsielen += 2;
6584
6585 /* Length: */
6586 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
6587 wpsielen += 2;
6588
6589 /* Value: */
6590 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
6591 wpsielen += 2;
6592
6593
6594 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
6595
6596
6597 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
6598 pframe += p2pielen;
6599 pattrib->pktlen += p2pielen;
6600 }
6601
6602 #ifdef CONFIG_WFD
6603 wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
6604 pframe += wfdielen;
6605 pattrib->pktlen += wfdielen;
6606 #endif
6607
6608 /* Vendor Specific IE */
6609 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
6610 pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_P2P_PROBERESP_VENDOR_IE_BIT);
6611 #endif
6612
6613 pattrib->last_txcmdsz = pattrib->pktlen;
6614
6615
6616 dump_mgntframe(padapter, pmgntframe);
6617
6618 return;
6619
6620 }
6621
_issue_probereq_p2p(_adapter * padapter,u8 * da,int wait_ack)6622 int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
6623 {
6624 int ret = _FAIL;
6625 struct xmit_frame *pmgntframe;
6626 struct pkt_attrib *pattrib;
6627 unsigned char *pframe;
6628 struct rtw_ieee80211_hdr *pwlanhdr;
6629 unsigned short *fctrl;
6630 unsigned char *mac;
6631 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6632 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6633 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6634 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6635 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
6636 u16 wpsielen = 0, p2pielen = 0;
6637 #ifdef CONFIG_WFD
6638 u32 wfdielen = 0;
6639 #endif
6640
6641 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6642
6643
6644 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
6645 if (pmgntframe == NULL)
6646 goto exit;
6647
6648 /* update attribute */
6649 pattrib = &pmgntframe->attrib;
6650 update_mgntframe_attrib(padapter, pattrib);
6651
6652 if (IS_CCK_RATE(pattrib->rate)) {
6653 /* force OFDM 6M rate */
6654 pattrib->rate = MGN_6M;
6655 pattrib->raid = rtw_get_mgntframe_raid(padapter, WIRELESS_11G);
6656 }
6657
6658 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6659
6660 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6661 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6662
6663 mac = adapter_mac_addr(padapter);
6664
6665 fctrl = &(pwlanhdr->frame_ctl);
6666 *(fctrl) = 0;
6667
6668 if (da) {
6669 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6670 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
6671 } else {
6672 if ((pwdinfo->p2p_info.scan_op_ch_only) || (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
6673 /* This two flags will be set when this is only the P2P client mode. */
6674 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6675 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6676 } else {
6677 /* broadcast probe request frame */
6678 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6679 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
6680 }
6681 }
6682 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6683
6684 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6685 pmlmeext->mgnt_seq++;
6686 set_frame_sub_type(pframe, WIFI_PROBEREQ);
6687
6688 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6689 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6690
6691 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
6692 pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
6693 else
6694 pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
6695 /* Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 ) */
6696 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
6697
6698 #ifdef CONFIG_IOCTL_CFG80211
6699 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
6700 if (pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL) {
6701 /* WPS IE */
6702 _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
6703 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
6704 pframe += pmlmepriv->wps_probe_req_ie_len;
6705
6706 /* P2P IE */
6707 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
6708 pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
6709 pframe += pmlmepriv->p2p_probe_req_ie_len;
6710 }
6711 } else
6712 #endif /* CONFIG_IOCTL_CFG80211 */
6713 {
6714
6715 /* WPS IE */
6716 /* Noted by Albert 20110221 */
6717 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6718
6719 wpsielen = 0;
6720 /* WPS OUI */
6721 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6722 wpsielen += 4;
6723
6724 /* WPS version */
6725 /* Type: */
6726 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6727 wpsielen += 2;
6728
6729 /* Length: */
6730 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6731 wpsielen += 2;
6732
6733 /* Value: */
6734 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
6735
6736 if (pmlmepriv->wps_probe_req_ie == NULL) {
6737 /* UUID-E */
6738 /* Type: */
6739 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6740 wpsielen += 2;
6741
6742 /* Length: */
6743 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6744 wpsielen += 2;
6745
6746 /* Value: */
6747 if (pwdinfo->external_uuid == 0) {
6748 _rtw_memset(wpsie + wpsielen, 0x0, 16);
6749 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6750 } else
6751 _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6752 wpsielen += 0x10;
6753
6754 /* Config Method */
6755 /* Type: */
6756 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
6757 wpsielen += 2;
6758
6759 /* Length: */
6760 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
6761 wpsielen += 2;
6762
6763 /* Value: */
6764 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
6765 wpsielen += 2;
6766 }
6767
6768 /* Device Name */
6769 /* Type: */
6770 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6771 wpsielen += 2;
6772
6773 /* Length: */
6774 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
6775 wpsielen += 2;
6776
6777 /* Value: */
6778 _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
6779 wpsielen += pwdinfo->device_name_len;
6780
6781 /* Primary Device Type */
6782 /* Type: */
6783 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6784 wpsielen += 2;
6785
6786 /* Length: */
6787 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6788 wpsielen += 2;
6789
6790 /* Value: */
6791 /* Category ID */
6792 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_RTK_WIDI);
6793 wpsielen += 2;
6794
6795 /* OUI */
6796 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6797 wpsielen += 4;
6798
6799 /* Sub Category ID */
6800 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_RTK_DMP);
6801 wpsielen += 2;
6802
6803 /* Device Password ID */
6804 /* Type: */
6805 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
6806 wpsielen += 2;
6807
6808 /* Length: */
6809 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
6810 wpsielen += 2;
6811
6812 /* Value: */
6813 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC); /* Registrar-specified */
6814 wpsielen += 2;
6815
6816 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
6817
6818 /* P2P OUI */
6819 p2pielen = 0;
6820 p2pie[p2pielen++] = 0x50;
6821 p2pie[p2pielen++] = 0x6F;
6822 p2pie[p2pielen++] = 0x9A;
6823 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
6824
6825 /* Commented by Albert 20110221 */
6826 /* According to the P2P Specification, the probe request frame should contain 5 P2P attributes */
6827 /* 1. P2P Capability */
6828 /* 2. P2P Device ID if this probe request wants to find the specific P2P device */
6829 /* 3. Listen Channel */
6830 /* 4. Extended Listen Timing */
6831 /* 5. Operating Channel if this WiFi is working as the group owner now */
6832
6833 /* P2P Capability */
6834 /* Type: */
6835 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
6836
6837 /* Length: */
6838 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
6839 p2pielen += 2;
6840
6841 /* Value: */
6842 /* Device Capability Bitmap, 1 byte */
6843 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
6844
6845 /* Group Capability Bitmap, 1 byte */
6846 if (pwdinfo->persistent_supported)
6847 p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
6848 else
6849 p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
6850
6851 /* Listen Channel */
6852 /* Type: */
6853 p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
6854
6855 /* Length: */
6856 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
6857 p2pielen += 2;
6858
6859 /* Value: */
6860 /* Country String */
6861 p2pie[p2pielen++] = 'X';
6862 p2pie[p2pielen++] = 'X';
6863
6864 /* The third byte should be set to 0x04. */
6865 /* Described in the "Operating Channel Attribute" section. */
6866 p2pie[p2pielen++] = 0x04;
6867
6868 /* Operating Class */
6869 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
6870
6871 /* Channel Number */
6872 p2pie[p2pielen++] = pwdinfo->listen_channel; /* listen channel */
6873
6874
6875 /* Extended Listen Timing */
6876 /* Type: */
6877 p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
6878
6879 /* Length: */
6880 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
6881 p2pielen += 2;
6882
6883 /* Value: */
6884 /* Availability Period */
6885 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
6886 p2pielen += 2;
6887
6888 /* Availability Interval */
6889 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
6890 p2pielen += 2;
6891
6892 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6893 /* Operating Channel (if this WiFi is working as the group owner now) */
6894 /* Type: */
6895 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
6896
6897 /* Length: */
6898 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
6899 p2pielen += 2;
6900
6901 /* Value: */
6902 /* Country String */
6903 p2pie[p2pielen++] = 'X';
6904 p2pie[p2pielen++] = 'X';
6905
6906 /* The third byte should be set to 0x04. */
6907 /* Described in the "Operating Channel Attribute" section. */
6908 p2pie[p2pielen++] = 0x04;
6909
6910 /* Operating Class */
6911 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
6912
6913 /* Channel Number */
6914 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
6915
6916 }
6917
6918 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
6919
6920 }
6921
6922 #ifdef CONFIG_WFD
6923 wfdielen = rtw_append_probe_req_wfd_ie(padapter, pframe);
6924 pframe += wfdielen;
6925 pattrib->pktlen += wfdielen;
6926 #endif
6927
6928 /* Vendor Specific IE */
6929 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
6930 pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_P2P_PROBEREQ_VENDOR_IE_BIT);
6931 #endif
6932
6933 pattrib->last_txcmdsz = pattrib->pktlen;
6934
6935
6936 if (wait_ack)
6937 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
6938 else {
6939 dump_mgntframe(padapter, pmgntframe);
6940 ret = _SUCCESS;
6941 }
6942
6943 exit:
6944 return ret;
6945 }
6946
issue_probereq_p2p(_adapter * adapter,u8 * da)6947 inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
6948 {
6949 _issue_probereq_p2p(adapter, da, _FALSE);
6950 }
6951
6952 /*
6953 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
6954 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
6955 * try_cnt means the maximal TX count to try
6956 */
issue_probereq_p2p_ex(_adapter * adapter,u8 * da,int try_cnt,int wait_ms)6957 int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
6958 {
6959 int ret;
6960 int i = 0;
6961 systime start = rtw_get_current_time();
6962
6963 do {
6964 ret = _issue_probereq_p2p(adapter, da, wait_ms > 0 ? _TRUE : _FALSE);
6965
6966 i++;
6967
6968 if (RTW_CANNOT_RUN(adapter))
6969 break;
6970
6971 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
6972 rtw_msleep_os(wait_ms);
6973
6974 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
6975
6976 if (ret != _FAIL) {
6977 ret = _SUCCESS;
6978 #ifndef DBG_XMIT_ACK
6979 goto exit;
6980 #endif
6981 }
6982
6983 if (try_cnt && wait_ms) {
6984 if (da)
6985 RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
6986 FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
6987 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
6988 else
6989 RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6990 FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
6991 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
6992 }
6993 exit:
6994 return ret;
6995 }
6996
6997 #endif /* CONFIG_P2P */
6998
rtw_action_public_decache(union recv_frame * rframe,u8 token_offset)6999 s32 rtw_action_public_decache(union recv_frame *rframe, u8 token_offset)
7000 {
7001 _adapter *adapter = rframe->u.hdr.adapter;
7002 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
7003 u8 *frame = rframe->u.hdr.rx_data;
7004 u16 seq_ctrl = ((rframe->u.hdr.attrib.seq_num & 0xffff) << 4) | (rframe->u.hdr.attrib.frag_num & 0xf);
7005 u8 token = *(rframe->u.hdr.rx_data + sizeof(struct rtw_ieee80211_hdr_3addr) + token_offset);
7006
7007 if (GetRetry(frame)) {
7008 if ((seq_ctrl == mlmeext->action_public_rxseq)
7009 && (token == mlmeext->action_public_dialog_token)
7010 ) {
7011 RTW_INFO(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
7012 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
7013 return _FAIL;
7014 }
7015 }
7016
7017 /* TODO: per sta seq & token */
7018 mlmeext->action_public_rxseq = seq_ctrl;
7019 mlmeext->action_public_dialog_token = token;
7020
7021 return _SUCCESS;
7022 }
7023
on_action_public_p2p(union recv_frame * precv_frame)7024 unsigned int on_action_public_p2p(union recv_frame *precv_frame)
7025 {
7026 _adapter *padapter = precv_frame->u.hdr.adapter;
7027 u8 *pframe = precv_frame->u.hdr.rx_data;
7028 uint len = precv_frame->u.hdr.len;
7029 u8 *frame_body;
7030 #ifdef CONFIG_P2P
7031 u8 *p2p_ie;
7032 u32 p2p_ielen;
7033 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7034 u8 result = P2P_STATUS_SUCCESS;
7035 u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
7036 u8 *merged_p2pie = NULL;
7037 u32 merged_p2p_ielen = 0;
7038 #ifdef CONFIG_CONCURRENT_MODE
7039 struct roch_info *prochinfo = &padapter->rochinfo;
7040 #endif
7041 #endif /* CONFIG_P2P */
7042
7043 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7044
7045 #ifdef CONFIG_P2P
7046 _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
7047 #ifdef CONFIG_IOCTL_CFG80211
7048 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
7049 rtw_cfg80211_rx_p2p_action_public(padapter, precv_frame);
7050 else
7051 #endif /* CONFIG_IOCTL_CFG80211 */
7052 {
7053 /* Do nothing if the driver doesn't enable the P2P function. */
7054 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
7055 return _SUCCESS;
7056
7057 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
7058
7059 switch (frame_body[6]) { /* OUI Subtype */
7060 case P2P_GO_NEGO_REQ: {
7061 RTW_INFO("[%s] Got GO Nego Req Frame\n", __FUNCTION__);
7062 _rtw_memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
7063
7064 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
7065 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
7066
7067 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) {
7068 /* Commented by Albert 20110526 */
7069 /* In this case, this means the previous nego fail doesn't be reset yet. */
7070 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
7071 /* Restore the previous p2p state */
7072 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
7073 RTW_INFO("[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo));
7074 }
7075 #ifdef CONFIG_CONCURRENT_MODE
7076 if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7077 _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer);
7078 #endif /* CONFIG_CONCURRENT_MODE */
7079
7080 /* Commented by Kurt 20110902 */
7081 /* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
7082 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
7083 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
7084
7085 /* Commented by Kurt 20120113 */
7086 /* Get peer_dev_addr here if peer doesn't issue prov_disc frame. */
7087 if (_rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN))
7088 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, get_addr2_ptr(pframe), ETH_ALEN);
7089
7090 result = process_p2p_group_negotation_req(pwdinfo, frame_body, len);
7091 issue_p2p_GO_response(padapter, get_addr2_ptr(pframe), frame_body, len, result);
7092
7093 /* Commented by Albert 20110718 */
7094 /* No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */
7095 #ifdef CONFIG_CONCURRENT_MODE
7096 /* Commented by Albert 20120107 */
7097 _set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
7098 #else /* CONFIG_CONCURRENT_MODE */
7099 _set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
7100 #endif /* CONFIG_CONCURRENT_MODE */
7101 break;
7102 }
7103 case P2P_GO_NEGO_RESP: {
7104 RTW_INFO("[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
7105
7106 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
7107 /* Commented by Albert 20110425 */
7108 /* The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */
7109 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
7110 pwdinfo->nego_req_info.benable = _FALSE;
7111 result = process_p2p_group_negotation_resp(pwdinfo, frame_body, len);
7112 issue_p2p_GO_confirm(pwdinfo->padapter, get_addr2_ptr(pframe), result);
7113 if (P2P_STATUS_SUCCESS == result) {
7114 if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) {
7115 pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch;
7116 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
7117 pwdinfo->p2p_info.operation_ch[1] = 1; /* Check whether GO is operating in channel 1; */
7118 pwdinfo->p2p_info.operation_ch[2] = 6; /* Check whether GO is operating in channel 6; */
7119 pwdinfo->p2p_info.operation_ch[3] = 11; /* Check whether GO is operating in channel 11; */
7120 #endif /* CONFIG_P2P_OP_CHK_SOCIAL_CH */
7121 pwdinfo->p2p_info.scan_op_ch_only = 1;
7122 _set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH);
7123 }
7124 }
7125
7126 /* Reset the dialog token for group negotiation frames. */
7127 pwdinfo->negotiation_dialog_token = 1;
7128
7129 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
7130 _set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
7131 } else
7132 RTW_INFO("[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
7133
7134 break;
7135 }
7136 case P2P_GO_NEGO_CONF: {
7137 RTW_INFO("[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
7138 result = process_p2p_group_negotation_confirm(pwdinfo, frame_body, len);
7139 if (P2P_STATUS_SUCCESS == result) {
7140 if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) {
7141 pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch;
7142 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
7143 pwdinfo->p2p_info.operation_ch[1] = 1; /* Check whether GO is operating in channel 1; */
7144 pwdinfo->p2p_info.operation_ch[2] = 6; /* Check whether GO is operating in channel 6; */
7145 pwdinfo->p2p_info.operation_ch[3] = 11; /* Check whether GO is operating in channel 11; */
7146 #endif /* CONFIG_P2P_OP_CHK_SOCIAL_CH */
7147 pwdinfo->p2p_info.scan_op_ch_only = 1;
7148 _set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH);
7149 }
7150 }
7151 break;
7152 }
7153 case P2P_INVIT_REQ: {
7154 /* Added by Albert 2010/10/05 */
7155 /* Received the P2P Invite Request frame. */
7156
7157 RTW_INFO("[%s] Got invite request frame!\n", __FUNCTION__);
7158 p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
7159 if (p2p_ie) {
7160 /* Parse the necessary information from the P2P Invitation Request frame. */
7161 /* For example: The MAC address of sending this P2P Invitation Request frame. */
7162 u32 attr_contentlen = 0;
7163 u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7164 struct group_id_info group_id;
7165 u8 invitation_flag = 0;
7166
7167 merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_);
7168
7169 merged_p2pie = rtw_zmalloc(merged_p2p_ielen + 2); /* 2 is for EID and Length */
7170 if (merged_p2pie == NULL) {
7171 RTW_INFO("[%s] Malloc p2p ie fail\n", __FUNCTION__);
7172 goto exit;
7173 }
7174 _rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);
7175
7176 merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
7177
7178 attr_contentlen = sizeof(invitation_flag);
7179 rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
7180 if (attr_contentlen) {
7181
7182 attr_contentlen = sizeof(pwdinfo->p2p_peer_interface_addr);
7183 rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
7184 /* Commented by Albert 20120510 */
7185 /* Copy to the pwdinfo->p2p_peer_interface_addr. */
7186 /* So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command. */
7187 /* #> iwpriv wlan0 p2p_get peer_ifa */
7188 /* After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */
7189
7190 if (attr_contentlen) {
7191 RTW_INFO("[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
7192 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
7193 pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
7194 pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
7195 }
7196
7197 if (invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT) {
7198 /* Re-invoke the persistent group. */
7199
7200 _rtw_memset(&group_id, 0x00, sizeof(struct group_id_info));
7201 attr_contentlen = sizeof(struct group_id_info);
7202 rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *) &group_id, &attr_contentlen);
7203 if (attr_contentlen) {
7204 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN)) {
7205 /* The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */
7206 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO);
7207 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
7208 status_code = P2P_STATUS_SUCCESS;
7209 } else {
7210 /* The p2p device sending this p2p invitation request wants to be the persistent GO. */
7211 if (is_matched_in_profilelist(pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[0])) {
7212 u8 operatingch_info[5] = { 0x00 };
7213 attr_contentlen = sizeof(operatingch_info);
7214 if (rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info,
7215 &attr_contentlen)) {
7216 if (rtw_chset_search_ch(adapter_to_chset(padapter), (u32)operatingch_info[4]) >= 0) {
7217 /* The operating channel is acceptable for this device. */
7218 pwdinfo->rx_invitereq_info.operation_ch[0] = operatingch_info[4];
7219 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
7220 pwdinfo->rx_invitereq_info.operation_ch[1] = 1; /* Check whether GO is operating in channel 1; */
7221 pwdinfo->rx_invitereq_info.operation_ch[2] = 6; /* Check whether GO is operating in channel 6; */
7222 pwdinfo->rx_invitereq_info.operation_ch[3] = 11; /* Check whether GO is operating in channel 11; */
7223 #endif /* CONFIG_P2P_OP_CHK_SOCIAL_CH */
7224 pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
7225 _set_timer(&pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH);
7226 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
7227 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
7228 status_code = P2P_STATUS_SUCCESS;
7229 } else {
7230 /* The operating channel isn't supported by this device. */
7231 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
7232 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
7233 status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
7234 _set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
7235 }
7236 } else {
7237 /* Commented by Albert 20121130 */
7238 /* Intel will use the different P2P IE to store the operating channel information */
7239 /* Workaround for Intel WiDi 3.5 */
7240 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
7241 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
7242 status_code = P2P_STATUS_SUCCESS;
7243 }
7244 } else {
7245 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
7246 status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
7247 }
7248 }
7249 } else {
7250 RTW_INFO("[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__);
7251 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7252 }
7253 } else {
7254 /* Received the invitation to join a P2P group. */
7255
7256 _rtw_memset(&group_id, 0x00, sizeof(struct group_id_info));
7257 attr_contentlen = sizeof(struct group_id_info);
7258 rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *) &group_id, &attr_contentlen);
7259 if (attr_contentlen) {
7260 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN)) {
7261 /* In this case, the GO can't be myself. */
7262 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
7263 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7264 } else {
7265 /* The p2p device sending this p2p invitation request wants to join an existing P2P group */
7266 /* Commented by Albert 2012/06/28 */
7267 /* In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */
7268 /* The peer device address should be the destination address for the provisioning discovery request. */
7269 /* Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */
7270 /* The peer interface address should be the address for WPS mac address */
7271 _rtw_memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN);
7272 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
7273 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN);
7274 status_code = P2P_STATUS_SUCCESS;
7275 }
7276 } else {
7277 RTW_INFO("[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__);
7278 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7279 }
7280 }
7281 } else {
7282 RTW_INFO("[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__);
7283 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7284 }
7285
7286 RTW_INFO("[%s] status_code = %d\n", __FUNCTION__, status_code);
7287
7288 pwdinfo->inviteresp_info.token = frame_body[7];
7289 issue_p2p_invitation_response(padapter, get_addr2_ptr(pframe), pwdinfo->inviteresp_info.token, status_code);
7290 _set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
7291 }
7292 break;
7293 }
7294 case P2P_INVIT_RESP: {
7295 u8 attr_content = 0x00;
7296 u32 attr_contentlen = 0;
7297
7298 RTW_INFO("[%s] Got invite response frame!\n", __FUNCTION__);
7299 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
7300 p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
7301 if (p2p_ie) {
7302 attr_contentlen = sizeof(attr_content);
7303 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
7304
7305 if (attr_contentlen == 1) {
7306 RTW_INFO("[%s] Status = %d\n", __FUNCTION__, attr_content);
7307 pwdinfo->invitereq_info.benable = _FALSE;
7308
7309 if (attr_content == P2P_STATUS_SUCCESS) {
7310 if (_rtw_memcmp(pwdinfo->invitereq_info.go_bssid, adapter_mac_addr(padapter), ETH_ALEN))
7311 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
7312 else
7313 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
7314
7315 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_OK);
7316 } else {
7317 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
7318 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
7319 }
7320 } else {
7321 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
7322 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
7323 }
7324 } else {
7325 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
7326 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
7327 }
7328
7329 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL))
7330 _set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
7331 break;
7332 }
7333 case P2P_DEVDISC_REQ:
7334
7335 process_p2p_devdisc_req(pwdinfo, pframe, len);
7336
7337 break;
7338
7339 case P2P_DEVDISC_RESP:
7340
7341 process_p2p_devdisc_resp(pwdinfo, pframe, len);
7342
7343 break;
7344
7345 case P2P_PROVISION_DISC_REQ:
7346 RTW_INFO("[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__);
7347 process_p2p_provdisc_req(pwdinfo, pframe, len);
7348 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, get_addr2_ptr(pframe), ETH_ALEN);
7349
7350 /* 20110902 Kurt */
7351 /* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
7352 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
7353 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
7354
7355 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
7356 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
7357 break;
7358
7359 case P2P_PROVISION_DISC_RESP:
7360 /* Commented by Albert 20110707 */
7361 /* Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */
7362 RTW_INFO("[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__);
7363 /* Commented by Albert 20110426 */
7364 /* The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */
7365 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
7366 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
7367 process_p2p_provdisc_resp(pwdinfo, pframe);
7368 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
7369 break;
7370
7371 }
7372 }
7373
7374
7375 exit:
7376
7377 if (merged_p2pie)
7378 rtw_mfree(merged_p2pie, merged_p2p_ielen + 2);
7379 #endif /* CONFIG_P2P */
7380 return _SUCCESS;
7381 }
7382
on_action_public_vendor(union recv_frame * precv_frame)7383 unsigned int on_action_public_vendor(union recv_frame *precv_frame)
7384 {
7385 unsigned int ret = _FAIL;
7386 u8 *pframe = precv_frame->u.hdr.rx_data;
7387 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7388 _adapter *adapter = precv_frame->u.hdr.adapter;
7389 int cnt = 0;
7390 char msg[64];
7391
7392 if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
7393 if (rtw_action_public_decache(precv_frame, 7) == _FAIL)
7394 goto exit;
7395
7396 if (!hal_chk_wl_func(precv_frame->u.hdr.adapter, WL_FUNC_MIRACAST))
7397 rtw_rframe_del_wfd_ie(precv_frame, 8);
7398
7399 ret = on_action_public_p2p(precv_frame);
7400 } else if (_rtw_memcmp(frame_body + 2, DPP_OUI, 4) == _TRUE) {
7401 u8 dpp_type = frame_body[7];
7402
7403 #ifdef CONFIG_IOCTL_CFG80211
7404 cnt += sprintf((msg + cnt), "DPP(type:%u)", dpp_type);
7405 rtw_cfg80211_rx_action(adapter, precv_frame, msg);
7406 #endif
7407 }
7408
7409 exit:
7410 return ret;
7411 }
7412
on_action_public_default(union recv_frame * precv_frame,u8 action)7413 unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
7414 {
7415 unsigned int ret = _FAIL;
7416 u8 *pframe = precv_frame->u.hdr.rx_data;
7417 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7418 u8 token;
7419 _adapter *adapter = precv_frame->u.hdr.adapter;
7420 int cnt = 0;
7421 char msg[64];
7422
7423 token = frame_body[2];
7424
7425 if (rtw_action_public_decache(precv_frame, 2) == _FAIL)
7426 goto exit;
7427
7428 #ifdef CONFIG_IOCTL_CFG80211
7429 cnt += sprintf((msg + cnt), "%s(token:%u)", action_public_str(action), token);
7430 rtw_cfg80211_rx_action(adapter, precv_frame, msg);
7431 #endif
7432
7433 ret = _SUCCESS;
7434
7435 exit:
7436 return ret;
7437 }
7438
on_action_public(_adapter * padapter,union recv_frame * precv_frame)7439 unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
7440 {
7441 unsigned int ret = _FAIL;
7442 u8 *pframe = precv_frame->u.hdr.rx_data;
7443 uint frame_len = precv_frame->u.hdr.len;
7444 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7445 u8 category, action;
7446
7447 /* check RA matches or broadcast */
7448 if (!(_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN) ||
7449 is_broadcast_mac_addr(GetAddr1Ptr(pframe))))
7450 goto exit;
7451
7452 category = frame_body[0];
7453 if (category != RTW_WLAN_CATEGORY_PUBLIC)
7454 goto exit;
7455
7456 action = frame_body[1];
7457 switch (action) {
7458 case ACT_PUBLIC_BSSCOEXIST:
7459 #ifdef CONFIG_80211N_HT
7460 #ifdef CONFIG_AP_MODE
7461 /*20/40 BSS Coexistence Management frame is a Public Action frame*/
7462 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
7463 rtw_process_public_act_bsscoex(padapter, pframe, frame_len);
7464 #endif /*CONFIG_AP_MODE*/
7465 #endif /*CONFIG_80211N_HT*/
7466 break;
7467 case ACT_PUBLIC_VENDOR:
7468 ret = on_action_public_vendor(precv_frame);
7469 break;
7470 default:
7471 ret = on_action_public_default(precv_frame, action);
7472 break;
7473 }
7474
7475 exit:
7476 return ret;
7477 }
7478
OnAction_ft(_adapter * padapter,union recv_frame * precv_frame)7479 unsigned int OnAction_ft(_adapter *padapter, union recv_frame *precv_frame)
7480 {
7481 #ifdef CONFIG_RTW_80211R
7482 u32 ret = _FAIL;
7483 u32 frame_len = 0;
7484 u8 action_code = 0;
7485 u8 category = 0;
7486 u8 *pframe = NULL;
7487 u8 *pframe_body = NULL;
7488 u8 tgt_addr[ETH_ALEN];
7489 u8 *pie = NULL;
7490 u32 ft_ie_len = 0;
7491 u32 status_code = 0;
7492 struct mlme_ext_priv *pmlmeext = NULL;
7493 struct mlme_ext_info *pmlmeinfo = NULL;
7494 struct mlme_priv *pmlmepriv = NULL;
7495 struct wlan_network *proam_target = NULL;
7496 struct ft_roam_info *pft_roam = NULL;
7497 _irqL irqL;
7498
7499 pmlmeext = &(padapter->mlmeextpriv);
7500 pmlmeinfo = &(pmlmeext->mlmext_info);
7501 pmlmepriv = &(padapter->mlmepriv);
7502 pft_roam = &(pmlmepriv->ft_roam);
7503 pframe = precv_frame->u.hdr.rx_data;
7504 frame_len = precv_frame->u.hdr.len;
7505 pframe_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7506 category = pframe_body[0];
7507
7508 if (category != RTW_WLAN_CATEGORY_FT)
7509 goto exit;
7510
7511 action_code = pframe_body[1];
7512 switch (action_code) {
7513 case RTW_WLAN_ACTION_FT_RSP:
7514 RTW_INFO("FT: RTW_WLAN_ACTION_FT_RSP recv.\n");
7515 if (!_rtw_memcmp(adapter_mac_addr(padapter), &pframe_body[2], ETH_ALEN)) {
7516 RTW_ERR("FT: Unmatched STA MAC Address "MAC_FMT"\n", MAC_ARG(&pframe_body[2]));
7517 goto exit;
7518 }
7519
7520 status_code = le16_to_cpu(*(u16 *)((SIZE_PTR)pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + 14));
7521 if (status_code != 0) {
7522 RTW_ERR("FT: WLAN ACTION FT RESPONSE fail, status: %d\n", status_code);
7523 goto exit;
7524 }
7525
7526 _rtw_memcpy(tgt_addr, &pframe_body[8], ETH_ALEN);
7527 if (is_zero_mac_addr(tgt_addr) || is_broadcast_mac_addr(tgt_addr)) {
7528 RTW_ERR("FT: Invalid Target MAC Address "MAC_FMT"\n", MAC_ARG(tgt_addr));
7529 goto exit;
7530 }
7531
7532 pie = rtw_get_ie(pframe_body, _MDIE_, &ft_ie_len, frame_len);
7533 if (pie) {
7534 if (!_rtw_memcmp(&pft_roam->mdid, pie+2, 2)) {
7535 RTW_ERR("FT: Invalid MDID\n");
7536 goto exit;
7537 }
7538 }
7539
7540 rtw_ft_set_status(padapter, RTW_FT_REQUESTED_STA);
7541 _cancel_timer_ex(&pmlmeext->ft_link_timer);
7542
7543 /*Disconnect current AP*/
7544 receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress, WLAN_REASON_ACTIVE_ROAM, _FALSE);
7545
7546 pft_roam->ft_action_len = frame_len;
7547 _rtw_memcpy(pft_roam->ft_action, pframe, rtw_min(frame_len, RTW_FT_MAX_IE_SZ));
7548 ret = _SUCCESS;
7549 break;
7550 case RTW_WLAN_ACTION_FT_REQ:
7551 case RTW_WLAN_ACTION_FT_CONF:
7552 case RTW_WLAN_ACTION_FT_ACK:
7553 default:
7554 RTW_ERR("FT: Unsupported FT Action!\n");
7555 break;
7556 }
7557
7558 exit:
7559 return ret;
7560 #else
7561 return _SUCCESS;
7562 #endif
7563 }
7564
OnAction_ht(_adapter * padapter,union recv_frame * precv_frame)7565 unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
7566 {
7567 u8 *pframe = precv_frame->u.hdr.rx_data;
7568 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7569 u8 category, action;
7570
7571 /* check RA matches or not */
7572 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7573 goto exit;
7574
7575 category = frame_body[0];
7576 if (category != RTW_WLAN_CATEGORY_HT)
7577 goto exit;
7578
7579 action = frame_body[1];
7580 switch (action) {
7581 case RTW_WLAN_ACTION_HT_SM_PS:
7582 #ifdef CONFIG_80211N_HT
7583 #ifdef CONFIG_AP_MODE
7584 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
7585 rtw_process_ht_action_smps(padapter, get_addr2_ptr(pframe), frame_body[2]);
7586 #endif /*CONFIG_AP_MODE*/
7587 #endif /*CONFIG_80211N_HT*/
7588 break;
7589 case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING:
7590 #ifdef CONFIG_BEAMFORMING
7591 /*RTW_INFO("RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING\n");*/
7592 rtw_beamforming_get_report_frame(padapter, precv_frame);
7593 #endif /*CONFIG_BEAMFORMING*/
7594 break;
7595 default:
7596 break;
7597 }
7598
7599 exit:
7600
7601 return _SUCCESS;
7602 }
7603
7604 #ifdef CONFIG_IEEE80211W
OnAction_sa_query(_adapter * padapter,union recv_frame * precv_frame)7605 unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame)
7606 {
7607 u8 *pframe = precv_frame->u.hdr.rx_data;
7608 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
7609 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7610 struct sta_info *psta;
7611 struct sta_priv *pstapriv = &padapter->stapriv;
7612 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7613 u16 tid;
7614 /* Baron */
7615
7616 RTW_INFO("OnAction_sa_query\n");
7617
7618 switch (pframe[WLAN_HDR_A3_LEN + 1]) {
7619 case 0: /* SA Query req */
7620 _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN + 2], sizeof(u16));
7621 RTW_INFO("OnAction_sa_query request,action=%d, tid=%04x, pframe=%02x-%02x\n"
7622 , pframe[WLAN_HDR_A3_LEN + 1], tid, pframe[WLAN_HDR_A3_LEN + 2], pframe[WLAN_HDR_A3_LEN + 3]);
7623 issue_action_SA_Query(padapter, get_addr2_ptr(pframe), 1, tid, IEEE80211W_RIGHT_KEY);
7624 break;
7625
7626 case 1: /* SA Query rsp */
7627 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
7628 if (psta != NULL)
7629 _cancel_timer_ex(&psta->dot11w_expire_timer);
7630
7631 _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN + 2], sizeof(u16));
7632 RTW_INFO("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN + 1], tid);
7633 break;
7634 default:
7635 break;
7636 }
7637 if (0) {
7638 int pp;
7639 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
7640 for (pp = 0; pp < pattrib->pkt_len; pp++)
7641 printk(" %02x ", pframe[pp]);
7642 printk("\n");
7643 }
7644
7645 return _SUCCESS;
7646 }
7647 #endif /* CONFIG_IEEE80211W */
7648
on_action_rm(_adapter * padapter,union recv_frame * precv_frame)7649 unsigned int on_action_rm(_adapter *padapter, union recv_frame *precv_frame)
7650 {
7651 #ifdef CONFIG_RTW_80211K
7652 return rm_on_action(padapter, precv_frame);
7653 #else
7654 return _SUCCESS;
7655 #endif /* CONFIG_RTW_80211K */
7656 }
7657
OnAction_wmm(_adapter * padapter,union recv_frame * precv_frame)7658 unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
7659 {
7660 return _SUCCESS;
7661 }
7662
OnAction_vht(_adapter * padapter,union recv_frame * precv_frame)7663 unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame)
7664 {
7665 #ifdef CONFIG_80211AC_VHT
7666 u8 *pframe = precv_frame->u.hdr.rx_data;
7667 struct rtw_ieee80211_hdr_3addr *whdr = (struct rtw_ieee80211_hdr_3addr *)pframe;
7668 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7669 u8 category, action;
7670 struct sta_info *psta = NULL;
7671
7672 /* check RA matches or not */
7673 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7674 goto exit;
7675
7676 category = frame_body[0];
7677 if (category != RTW_WLAN_CATEGORY_VHT)
7678 goto exit;
7679
7680 action = frame_body[1];
7681 switch (action) {
7682 case RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING:
7683 #ifdef CONFIG_BEAMFORMING
7684 /*RTW_INFO("RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING\n");*/
7685 rtw_beamforming_get_report_frame(padapter, precv_frame);
7686 #endif /*CONFIG_BEAMFORMING*/
7687 break;
7688 case RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION:
7689 /* CategoryCode(1) + ActionCode(1) + OpModeNotification(1) */
7690 /* RTW_INFO("RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION\n"); */
7691 psta = rtw_get_stainfo(&padapter->stapriv, whdr->addr2);
7692 if (psta)
7693 rtw_process_vht_op_mode_notify(padapter, &frame_body[2], psta);
7694 break;
7695 case RTW_WLAN_ACTION_VHT_GROUPID_MANAGEMENT:
7696 #ifdef CONFIG_BEAMFORMING
7697 #ifdef RTW_BEAMFORMING_VERSION_2
7698 rtw_beamforming_get_vht_gid_mgnt_frame(padapter, precv_frame);
7699 #endif /* RTW_BEAMFORMING_VERSION_2 */
7700 #endif /* CONFIG_BEAMFORMING */
7701 break;
7702 default:
7703 break;
7704 }
7705
7706 exit:
7707 #endif /* CONFIG_80211AC_VHT */
7708
7709 return _SUCCESS;
7710 }
7711
OnAction_p2p(_adapter * padapter,union recv_frame * precv_frame)7712 unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
7713 {
7714 #ifdef CONFIG_P2P
7715 u8 *frame_body;
7716 u8 category, OUI_Subtype, dialogToken = 0;
7717 u8 *pframe = precv_frame->u.hdr.rx_data;
7718 uint len = precv_frame->u.hdr.len;
7719 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7720
7721 /* check RA matches or not */
7722 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7723 return _SUCCESS;
7724
7725 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7726
7727 category = frame_body[0];
7728 if (category != RTW_WLAN_CATEGORY_P2P)
7729 return _SUCCESS;
7730
7731 if (cpu_to_be32(*((u32 *)(frame_body + 1))) != P2POUI)
7732 return _SUCCESS;
7733
7734 #ifdef CONFIG_IOCTL_CFG80211
7735 if (adapter_wdev_data(padapter)->p2p_enabled
7736 && pwdinfo->driver_interface == DRIVER_CFG80211
7737 ) {
7738 rtw_cfg80211_rx_action_p2p(padapter, precv_frame);
7739 return _SUCCESS;
7740 } else
7741 #endif /* CONFIG_IOCTL_CFG80211 */
7742 {
7743 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
7744 OUI_Subtype = frame_body[5];
7745 dialogToken = frame_body[6];
7746
7747 switch (OUI_Subtype) {
7748 case P2P_NOTICE_OF_ABSENCE:
7749
7750 break;
7751
7752 case P2P_PRESENCE_REQUEST:
7753
7754 process_p2p_presence_req(pwdinfo, pframe, len);
7755
7756 break;
7757
7758 case P2P_PRESENCE_RESPONSE:
7759
7760 break;
7761
7762 case P2P_GO_DISC_REQUEST:
7763
7764 break;
7765
7766 default:
7767 break;
7768
7769 }
7770 }
7771 #endif /* CONFIG_P2P */
7772
7773 return _SUCCESS;
7774
7775 }
7776
7777 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
OnAction_tbtx_token(_adapter * padapter,union recv_frame * precv_frame)7778 unsigned int OnAction_tbtx_token(_adapter *padapter, union recv_frame *precv_frame)
7779 {
7780 #define TOKEN_REQ 0x00
7781 #define TOKEN_REL 0x01
7782
7783 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7784 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7785 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7786 struct sta_priv *pstapriv = &padapter->stapriv;
7787 struct sta_info *psta;
7788 u32 xmit_time;
7789 u8 *src=NULL, *pframe = precv_frame->u.hdr.rx_data;
7790 u8 tbtx_action_code;
7791 u8 i, nr_send;
7792 uint tx_duration = 0;
7793
7794 if (padapter->tbtx_capability == _FALSE)
7795 goto exit;
7796
7797 tbtx_action_code = *(pframe + WLAN_HDR_A3_LEN + 1);
7798
7799
7800 switch (tbtx_action_code)
7801 {
7802 case TOKEN_REQ:
7803 // parse duration
7804 tx_duration = le32_to_cpu(*(uint *)(pframe + WLAN_HDR_A3_LEN + 2));
7805 padapter->tbtx_duration = tx_duration/1000; // Mirocsecond to Millisecond
7806 ATOMIC_SET(&padapter->tbtx_tx_pause, _FALSE);
7807 rtw_tx_control_cmd(padapter);
7808 _set_timer(&pmlmeext->tbtx_xmit_timer, padapter->tbtx_duration);
7809 ATOMIC_SET(&padapter->tbtx_remove_tx_pause, _FALSE);
7810 #if defined(CONFIG_SDIO_HCI) && !defined(CONFIG_SDIO_TX_TASKLET)
7811 _rtw_up_sema(&pxmitpriv->SdioXmitSema);
7812 #else
7813 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
7814 #endif
7815 break;
7816 #ifdef CONFIG_AP_MODE
7817 case TOKEN_REL:
7818 src = get_addr2_ptr(pframe);
7819 if (!src)
7820 goto exit;
7821 psta = rtw_get_stainfo(&padapter->stapriv, src);
7822 if (!psta)
7823 goto exit;
7824
7825 if (ATOMIC_READ(&pstapriv->nr_token_keeper) < 1)
7826 goto exit;
7827
7828 for (i=0; i< NR_MAXSTA_INSLOT; i++) {
7829 if (pstapriv->token_holder[i] == psta) {
7830 pstapriv->token_holder[i] = NULL;
7831 //RTW_INFO("macaddr1:" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
7832 ATOMIC_DEC(&pstapriv->nr_token_keeper);
7833 break;
7834 }
7835 }
7836
7837 if (ATOMIC_READ(&pstapriv->nr_token_keeper) == 0)
7838 _set_timer(&pmlmeext->tbtx_token_dispatch_timer, 1);
7839
7840 break;
7841 #endif
7842 default:
7843 RTW_INFO("Undefined Action Code\n");
7844 goto exit;
7845 break;
7846 }
7847
7848 exit:
7849 return _SUCCESS;
7850 }
7851
rtw_issue_action_token_rel(_adapter * padapter)7852 void rtw_issue_action_token_rel(_adapter *padapter)
7853 {
7854
7855 // Todo:
7856 // gen token
7857 /* Token Release Format
7858 Category code : 1 Byte
7859 Action code : 1 Byte */
7860 int ret = _FAIL;
7861 //u16 *fctrl;
7862 u8 val = 0x01;
7863 u8 category = RTW_WLAN_CATEGORY_TBTX;
7864 u8 *pframe;
7865 struct xmit_frame *pmgntframe;
7866 struct pkt_attrib *pattrib;
7867 struct rtw_ieee80211_hdr *pwlanhdr;
7868 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7869 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7870 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7871 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7872 //struct sta_info *psta;
7873 //struct sta_priv *pstapriv = &padapter->stapriv;
7874 //struct registry_priv *pregpriv = &padapter->registrypriv;
7875
7876 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
7877 return;
7878
7879 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
7880 if (pmgntframe == NULL)
7881 return;
7882
7883 /*update attribute */
7884 pattrib = &pmgntframe->attrib;
7885 update_mgntframe_attrib(padapter, pattrib);
7886 pattrib->rate = MGN_24M; /* issue action release using OFDM rate? 20190716 Bruce add */
7887
7888 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7889
7890 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7891 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7892
7893 //fctrl = &(pwlanhdr->frame_ctl);
7894 //*(fctrl) = 0;
7895
7896 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7897 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7898 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7899
7900 // SetSeqNum??
7901 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7902 pmlmeext->mgnt_seq++;
7903 set_frame_sub_type(pframe, WIFI_ACTION);
7904
7905 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7906 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7907
7908 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
7909 pframe = rtw_set_fixed_ie(pframe, 1, &(val), &(pattrib->pktlen));
7910
7911 pattrib->last_txcmdsz = pattrib->pktlen;
7912
7913 dump_mgntframe(padapter, pmgntframe);
7914
7915 //RTW_INFO("%s\n", __func__);
7916
7917 }
7918 #endif
7919
OnAction(_adapter * padapter,union recv_frame * precv_frame)7920 unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
7921 {
7922 int i;
7923 unsigned char category;
7924 struct action_handler *ptable;
7925 unsigned char *frame_body;
7926 u8 *pframe = precv_frame->u.hdr.rx_data;
7927
7928 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7929
7930 category = frame_body[0];
7931
7932 for (i = 0; i < sizeof(OnAction_tbl) / sizeof(struct action_handler); i++) {
7933 ptable = &OnAction_tbl[i];
7934
7935 if (category == ptable->num)
7936 ptable->func(padapter, precv_frame);
7937
7938 }
7939
7940 return _SUCCESS;
7941
7942 }
7943
DoReserved(_adapter * padapter,union recv_frame * precv_frame)7944 unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
7945 {
7946
7947 /* RTW_INFO("rcvd mgt frame(%x, %x)\n", (get_frame_sub_type(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe)); */
7948 return _SUCCESS;
7949 }
7950
_alloc_mgtxmitframe(struct xmit_priv * pxmitpriv,bool once)7951 struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
7952 {
7953 struct xmit_frame *pmgntframe;
7954 struct xmit_buf *pxmitbuf;
7955
7956 if (once)
7957 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
7958 else
7959 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
7960
7961 if (pmgntframe == NULL) {
7962 RTW_INFO(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
7963 goto exit;
7964 }
7965
7966 pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv);
7967 if (pxmitbuf == NULL) {
7968 RTW_INFO(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
7969 rtw_free_xmitframe(pxmitpriv, pmgntframe);
7970 pmgntframe = NULL;
7971 goto exit;
7972 }
7973
7974 pmgntframe->frame_tag = MGNT_FRAMETAG;
7975 pmgntframe->pxmitbuf = pxmitbuf;
7976 pmgntframe->buf_addr = pxmitbuf->pbuf;
7977 pxmitbuf->priv_data = pmgntframe;
7978
7979 exit:
7980 return pmgntframe;
7981
7982 }
7983
alloc_mgtxmitframe(struct xmit_priv * pxmitpriv)7984 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
7985 {
7986 return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
7987 }
7988
alloc_mgtxmitframe_once(struct xmit_priv * pxmitpriv)7989 inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
7990 {
7991 return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
7992 }
7993
7994
7995 /****************************************************************************
7996
7997 Following are some TX fuctions for WiFi MLME
7998
7999 *****************************************************************************/
8000
update_mgnt_tx_rate(_adapter * padapter,u8 rate)8001 void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
8002 {
8003 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8004
8005 pmlmeext->tx_rate = rate;
8006 pmlmeext->tx_rate_section = mgn_rate_to_rs(rate);
8007 /* RTW_INFO("%s(): rate = %x\n",__FUNCTION__, rate); */
8008 }
8009
8010
update_monitor_frame_attrib(_adapter * padapter,struct pkt_attrib * pattrib)8011 void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
8012 {
8013 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
8014 u8 wireless_mode;
8015 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8016 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
8017 struct sta_info *psta = NULL;
8018 struct sta_priv *pstapriv = &padapter->stapriv;
8019
8020 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
8021
8022 pattrib->hdrlen = 24;
8023 pattrib->nr_frags = 1;
8024 pattrib->priority = 7;
8025 pattrib->mac_id = RTW_DEFAULT_MGMT_MACID;
8026 pattrib->qsel = QSLT_MGNT;
8027
8028 pattrib->pktlen = 0;
8029
8030 if (IS_CCK_RATE(pmlmeext->tx_rate))
8031 wireless_mode = WIRELESS_11B;
8032 else
8033 wireless_mode = WIRELESS_11G;
8034
8035 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
8036 #ifdef CONFIG_80211AC_VHT
8037 if (pHalData->rf_type == RF_1T1R)
8038 pattrib->raid = RATEID_IDX_VHT_1SS;
8039 else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R)
8040 pattrib->raid = RATEID_IDX_VHT_2SS;
8041 else if (pHalData->rf_type == RF_3T3R)
8042 pattrib->raid = RATEID_IDX_VHT_3SS;
8043 else
8044 pattrib->raid = RATEID_IDX_BGN_40M_1SS;
8045 #endif
8046
8047 #ifdef CONFIG_80211AC_VHT
8048 pattrib->rate = MGN_VHT1SS_MCS9;
8049 #else
8050 pattrib->rate = MGN_MCS7;
8051 #endif
8052
8053 pattrib->encrypt = _NO_PRIVACY_;
8054 pattrib->bswenc = _FALSE;
8055
8056 pattrib->qos_en = _FALSE;
8057 pattrib->ht_en = 1;
8058 pattrib->bwmode = CHANNEL_WIDTH_20;
8059 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
8060 pattrib->sgi = _FALSE;
8061
8062 pattrib->seqnum = pmlmeext->mgnt_seq;
8063
8064 pattrib->retry_ctrl = _TRUE;
8065
8066 pattrib->mbssid = 0;
8067 pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
8068
8069 }
8070
8071 #ifdef CONFIG_RTW_MGMT_QUEUE
update_mgntframe_subtype(_adapter * padapter,struct xmit_frame * pmgntframe)8072 void update_mgntframe_subtype(_adapter *padapter, struct xmit_frame *pmgntframe)
8073 {
8074 struct pkt_attrib *pattrib = &pmgntframe->attrib;
8075 u8 *pframe;
8076 u8 subtype, category ,action;
8077
8078 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8079 subtype = get_frame_sub_type(pframe); /* bit(7)~bit(2) */
8080 pattrib->subtype = subtype;
8081
8082 rtw_action_frame_parse(pframe, pattrib->pktlen, &category, &action);
8083
8084 if ((subtype == WIFI_ACTION && !(action == ACT_PUBLIC_FTM_REQ || action == ACT_PUBLIC_FTM)) ||
8085 subtype == WIFI_DISASSOC || subtype == WIFI_DEAUTH ||
8086 (subtype == WIFI_PROBERSP && MLME_IS_ADHOC(padapter)))
8087 pattrib->ps_dontq = 0;
8088 else
8089 pattrib->ps_dontq = 1;
8090 }
8091 #endif
8092
update_mgntframe_attrib(_adapter * padapter,struct pkt_attrib * pattrib)8093 void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
8094 {
8095 u8 wireless_mode;
8096 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8097 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
8098 struct sta_priv *pstapriv = &padapter->stapriv;
8099 struct sta_info *psta;
8100
8101 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
8102 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8103 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
8104
8105 /* _rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib)); */
8106
8107 pattrib->hdrlen = 24;
8108 pattrib->nr_frags = 1;
8109 pattrib->priority = 7;
8110 pattrib->mac_id = RTW_DEFAULT_MGMT_MACID;
8111 pattrib->qsel = QSLT_MGNT;
8112
8113 #ifdef CONFIG_MCC_MODE
8114 update_mcc_mgntframe_attrib(padapter, pattrib);
8115 #endif
8116
8117
8118 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
8119 #ifdef CONFIG_CONCURRENT_MODE
8120 if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
8121 #endif /* CONFIG_CONCURRENT_MODE */
8122 if (MLME_IS_GC(padapter)) {
8123 if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
8124 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8125 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8126 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
8127
8128 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
8129 if (psta) {
8130 /* use macid sleep during NoA, mgmt frame use ac queue & ap macid */
8131 pattrib->mac_id = psta->cmn.mac_id;
8132 pattrib->qsel = QSLT_VO;
8133 } else {
8134 if (pwdinfo->p2p_ps_state != P2P_PS_DISABLE)
8135 RTW_ERR("%s , psta was NULL\n", __func__);
8136 }
8137 }
8138 }
8139 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
8140
8141 pattrib->pktlen = 0;
8142
8143 if (IS_CCK_RATE(pmlmeext->tx_rate))
8144 wireless_mode = WIRELESS_11B;
8145 else
8146 wireless_mode = WIRELESS_11G;
8147 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
8148 pattrib->rate = pmlmeext->tx_rate;
8149
8150 pattrib->encrypt = _NO_PRIVACY_;
8151 pattrib->bswenc = _FALSE;
8152
8153 pattrib->qos_en = _FALSE;
8154 pattrib->ht_en = _FALSE;
8155 pattrib->bwmode = CHANNEL_WIDTH_20;
8156 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
8157 pattrib->sgi = _FALSE;
8158
8159 pattrib->seqnum = pmlmeext->mgnt_seq;
8160
8161 pattrib->retry_ctrl = _TRUE;
8162
8163 pattrib->mbssid = 0;
8164 pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
8165 #ifdef CONFIG_RTW_MGMT_QUEUE
8166 pattrib->ps_dontq = 1;
8167 #endif
8168 }
8169
update_mgntframe_attrib_addr(_adapter * padapter,struct xmit_frame * pmgntframe)8170 void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe)
8171 {
8172 u8 *pframe;
8173 struct pkt_attrib *pattrib = &pmgntframe->attrib;
8174 #if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) || defined(CONFIG_RTW_MGMT_QUEUE)
8175 struct sta_info *sta = NULL;
8176 #endif
8177
8178 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8179
8180 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
8181 _rtw_memcpy(pattrib->ta, get_addr2_ptr(pframe), ETH_ALEN);
8182
8183 #if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) || defined(CONFIG_RTW_MGMT_QUEUE)
8184 sta = pattrib->psta;
8185 if (!sta) {
8186 sta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
8187 pattrib->psta = sta;
8188 }
8189
8190 #ifdef CONFIG_BEAMFORMING
8191 if (sta)
8192 update_attrib_txbf_info(padapter, pattrib, sta);
8193 #endif
8194 #endif /* defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) || defined(CONFIG_RTW_MGMT_QUEUE) */
8195 }
8196
dump_mgntframe(_adapter * padapter,struct xmit_frame * pmgntframe)8197 void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
8198 {
8199 if (RTW_CANNOT_RUN(padapter)) {
8200 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
8201 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
8202 return;
8203 }
8204
8205 rtw_hal_mgnt_xmit(padapter, pmgntframe);
8206 }
8207
dump_mgntframe_and_wait(_adapter * padapter,struct xmit_frame * pmgntframe,int timeout_ms)8208 s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
8209 {
8210 s32 ret = _FAIL;
8211 _irqL irqL;
8212 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
8213 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
8214 struct submit_ctx sctx;
8215
8216 if (RTW_CANNOT_RUN(padapter)) {
8217 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
8218 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
8219 return ret;
8220 }
8221
8222 rtw_sctx_init(&sctx, timeout_ms);
8223 pxmitbuf->sctx = &sctx;
8224
8225 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
8226
8227 if (ret == _SUCCESS
8228 #ifdef CONFIG_RTW_MGMT_QUEUE
8229 || ret == RTW_QUEUE_MGMT
8230 #endif
8231 )
8232 ret = rtw_sctx_wait(&sctx, __func__);
8233
8234 _enter_critical(&pxmitpriv->lock_sctx, &irqL);
8235 pxmitbuf->sctx = NULL;
8236 _exit_critical(&pxmitpriv->lock_sctx, &irqL);
8237
8238 return ret;
8239 }
8240
dump_mgntframe_and_wait_ack_timeout(_adapter * padapter,struct xmit_frame * pmgntframe,int timeout_ms)8241 s32 dump_mgntframe_and_wait_ack_timeout(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
8242 {
8243 #ifdef CONFIG_XMIT_ACK
8244 static u8 seq_no = 0;
8245 s32 ret = _FAIL;
8246 struct xmit_priv *pxmitpriv = &(GET_PRIMARY_ADAPTER(padapter))->xmitpriv;
8247
8248 if (RTW_CANNOT_RUN(padapter)) {
8249 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
8250 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
8251 return -1;
8252 }
8253
8254 _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
8255 pxmitpriv->ack_tx = _TRUE;
8256 pxmitpriv->seq_no = seq_no++;
8257 pmgntframe->ack_report = 1;
8258 rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms);
8259
8260 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
8261
8262 if (ret == _SUCCESS
8263 #ifdef CONFIG_RTW_MGMT_QUEUE
8264 || ret == RTW_QUEUE_MGMT
8265 #endif
8266 )
8267 ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__);
8268
8269 pxmitpriv->ack_tx = _FALSE;
8270 _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
8271
8272 return ret;
8273 #else /* !CONFIG_XMIT_ACK */
8274 dump_mgntframe(padapter, pmgntframe);
8275 rtw_msleep_os(50);
8276 return _SUCCESS;
8277 #endif /* !CONFIG_XMIT_ACK */
8278 }
8279
dump_mgntframe_and_wait_ack(_adapter * padapter,struct xmit_frame * pmgntframe)8280 s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
8281 {
8282 /* In this case, use 500 ms as the default wait_ack timeout */
8283 return dump_mgntframe_and_wait_ack_timeout(padapter, pmgntframe, 500);
8284 }
8285
8286
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)8287 int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
8288 {
8289 u8 *ssid_ie;
8290 sint ssid_len_ori;
8291 int len_diff = 0;
8292
8293 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
8294
8295 /* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
8296
8297 if (ssid_ie && ssid_len_ori > 0) {
8298 switch (hidden_ssid_mode) {
8299 case 1: {
8300 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
8301 u32 remain_len = 0;
8302
8303 remain_len = ies_len - (next_ie - ies);
8304
8305 ssid_ie[1] = 0;
8306 _rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
8307 len_diff -= ssid_len_ori;
8308
8309 break;
8310 }
8311 case 2:
8312 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
8313 break;
8314 default:
8315 break;
8316 }
8317 }
8318
8319 return len_diff;
8320 }
8321
8322 #ifdef CONFIG_AP_MODE
issue_beacon(_adapter * padapter,int timeout_ms)8323 void issue_beacon(_adapter *padapter, int timeout_ms)
8324 {
8325 struct xmit_frame *pmgntframe;
8326 struct pkt_attrib *pattrib;
8327 unsigned char *pframe;
8328 struct rtw_ieee80211_hdr *pwlanhdr;
8329 unsigned short *fctrl;
8330 unsigned int rate_len;
8331 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8332 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
8333 _irqL irqL;
8334 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8335 #endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
8336 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8337 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8338 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
8339 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8340 #ifdef CONFIG_P2P
8341 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8342 #endif /* CONFIG_P2P */
8343
8344
8345 /* RTW_INFO("%s\n", __FUNCTION__); */
8346
8347 #ifdef CONFIG_BCN_ICF
8348 pmgntframe = rtw_alloc_bcnxmitframe(pxmitpriv);
8349 if (pmgntframe == NULL)
8350 #else
8351 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8352 if (pmgntframe == NULL)
8353 #endif
8354 {
8355 RTW_INFO("%s, alloc mgnt frame fail\n", __FUNCTION__);
8356 return;
8357 }
8358 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
8359 _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
8360 #endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
8361
8362 /* update attribute */
8363 pattrib = &pmgntframe->attrib;
8364 update_mgntframe_attrib(padapter, pattrib);
8365 pattrib->qsel = QSLT_BEACON;
8366
8367 #if defined(CONFIG_CONCURRENT_MODE) && (!defined(CONFIG_SWTIMER_BASED_TXBCN))
8368 if (padapter->hw_port == HW_PORT1)
8369 pattrib->mbssid = 1;
8370 #endif
8371 #ifdef CONFIG_FW_HANDLE_TXBCN
8372 if (padapter->vap_id != CONFIG_LIMITED_AP_NUM)
8373 pattrib->mbssid = padapter->vap_id;
8374 #endif
8375
8376 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8377
8378 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8379 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8380
8381
8382 fctrl = &(pwlanhdr->frame_ctl);
8383 *(fctrl) = 0;
8384
8385 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8386 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8387 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
8388
8389 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
8390 /* pmlmeext->mgnt_seq++; */
8391 set_frame_sub_type(pframe, WIFI_BEACON);
8392
8393 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8394 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8395
8396 if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) {
8397 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
8398 #ifdef CONFIG_P2P
8399 /* for P2P : Primary Device Type & Device Name */
8400 u32 wpsielen = 0, insert_len = 0;
8401 u8 *wpsie = NULL;
8402 wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
8403
8404 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
8405 uint wps_offset, remainder_ielen;
8406 u8 *premainder_ie, *pframe_wscie;
8407
8408 wps_offset = (uint)(wpsie - cur_network->IEs);
8409
8410 premainder_ie = wpsie + wpsielen;
8411
8412 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
8413
8414 #ifdef CONFIG_IOCTL_CFG80211
8415 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
8416 if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
8417 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
8418 pframe += wps_offset;
8419 pattrib->pktlen += wps_offset;
8420
8421 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
8422 pframe += pmlmepriv->wps_beacon_ie_len;
8423 pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
8424
8425 /* copy remainder_ie to pframe */
8426 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
8427 pframe += remainder_ielen;
8428 pattrib->pktlen += remainder_ielen;
8429 } else {
8430 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8431 pframe += cur_network->IELength;
8432 pattrib->pktlen += cur_network->IELength;
8433 }
8434 } else
8435 #endif /* CONFIG_IOCTL_CFG80211 */
8436 {
8437 pframe_wscie = pframe + wps_offset;
8438 _rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
8439 pframe += (wps_offset + wpsielen);
8440 pattrib->pktlen += (wps_offset + wpsielen);
8441
8442 /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
8443 /* Primary Device Type */
8444 /* Type: */
8445 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
8446 insert_len += 2;
8447
8448 /* Length: */
8449 *(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
8450 insert_len += 2;
8451
8452 /* Value: */
8453 /* Category ID */
8454 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
8455 insert_len += 2;
8456
8457 /* OUI */
8458 *(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
8459 insert_len += 4;
8460
8461 /* Sub Category ID */
8462 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
8463 insert_len += 2;
8464
8465
8466 /* Device Name */
8467 /* Type: */
8468 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
8469 insert_len += 2;
8470
8471 /* Length: */
8472 *(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
8473 insert_len += 2;
8474
8475 /* Value: */
8476 _rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
8477 insert_len += pwdinfo->device_name_len;
8478
8479
8480 /* update wsc ie length */
8481 *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
8482
8483 /* pframe move to end */
8484 pframe += insert_len;
8485 pattrib->pktlen += insert_len;
8486
8487 /* copy remainder_ie to pframe */
8488 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
8489 pframe += remainder_ielen;
8490 pattrib->pktlen += remainder_ielen;
8491 }
8492 } else
8493 #endif /* CONFIG_P2P */
8494 {
8495 int len_diff;
8496 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8497 len_diff = update_hidden_ssid(
8498 pframe + _BEACON_IE_OFFSET_
8499 , cur_network->IELength - _BEACON_IE_OFFSET_
8500 , pmlmeinfo->hidden_ssid_mode
8501 );
8502 pframe += (cur_network->IELength + len_diff);
8503 pattrib->pktlen += (cur_network->IELength + len_diff);
8504 }
8505
8506 {
8507 u8 *wps_ie;
8508 uint wps_ielen;
8509 u8 sr = 0;
8510 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
8511 pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
8512 if (wps_ie && wps_ielen > 0)
8513 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
8514 if (sr != 0)
8515 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
8516 else
8517 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
8518 }
8519
8520 #ifdef CONFIG_P2P
8521 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
8522 u32 len;
8523 #ifdef CONFIG_IOCTL_CFG80211
8524 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
8525 len = pmlmepriv->p2p_beacon_ie_len;
8526 if (pmlmepriv->p2p_beacon_ie && len > 0)
8527 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
8528 } else
8529 #endif /* CONFIG_IOCTL_CFG80211 */
8530 {
8531 len = build_beacon_p2p_ie(pwdinfo, pframe);
8532 }
8533
8534 pframe += len;
8535 pattrib->pktlen += len;
8536
8537 #ifdef CONFIG_MCC_MODE
8538 pframe = rtw_hal_mcc_append_go_p2p_ie(padapter, pframe, &pattrib->pktlen);
8539 #endif /* CONFIG_MCC_MODE*/
8540
8541 #ifdef CONFIG_WFD
8542 len = rtw_append_beacon_wfd_ie(padapter, pframe);
8543 pframe += len;
8544 pattrib->pktlen += len;
8545 #endif
8546 }
8547 #endif /* CONFIG_P2P */
8548 #ifdef CONFIG_RTW_REPEATER_SON
8549 rtw_rson_append_ie(padapter, pframe, &pattrib->pktlen);
8550 #endif
8551 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8552 pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_BEACON_VENDOR_IE_BIT);
8553 #endif
8554
8555 #ifdef CONFIG_RTL8812A
8556 pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen );
8557 #endif/*CONFIG_RTL8812A*/
8558
8559 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
8560 if (padapter->tbtx_capability == _TRUE)
8561 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 8, REALTEK_TBTX_IE, &pattrib->pktlen);
8562 #endif
8563
8564 goto _issue_bcn;
8565
8566 }
8567
8568 /* below for ad-hoc mode */
8569
8570 /* timestamp will be inserted by hardware */
8571 pframe += 8;
8572 pattrib->pktlen += 8;
8573
8574 /* beacon interval: 2 bytes */
8575
8576 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
8577
8578 pframe += 2;
8579 pattrib->pktlen += 2;
8580
8581 /* capability info: 2 bytes */
8582
8583 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
8584
8585 pframe += 2;
8586 pattrib->pktlen += 2;
8587
8588 /* SSID */
8589 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
8590
8591 /* supported rates... */
8592 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
8593 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
8594
8595 /* DS parameter set */
8596 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
8597
8598 /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
8599 {
8600 u8 erpinfo = 0;
8601 u32 ATIMWindow;
8602 /* IBSS Parameter Set... */
8603 /* ATIMWindow = cur->Configuration.ATIMWindow; */
8604 ATIMWindow = 0;
8605 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
8606
8607 /* ERP IE */
8608 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
8609 }
8610
8611
8612 /* EXTERNDED SUPPORTED RATE */
8613 if (rate_len > 8)
8614 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
8615
8616
8617 /* todo:HT for adhoc */
8618
8619 _issue_bcn:
8620
8621 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
8622 pmlmepriv->update_bcn = _FALSE;
8623
8624 _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
8625 #endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
8626
8627 if ((pattrib->pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
8628 RTW_ERR("beacon frame too large ,len(%d,%d)\n",
8629 (pattrib->pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
8630 rtw_warn_on(1);
8631 return;
8632 }
8633
8634 pattrib->last_txcmdsz = pattrib->pktlen;
8635
8636 /* RTW_INFO("issue bcn_sz=%d\n", pattrib->last_txcmdsz); */
8637 if (timeout_ms > 0)
8638 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
8639 else
8640 dump_mgntframe(padapter, pmgntframe);
8641
8642 }
8643 #endif /* CONFIG_AP_MODE */
8644
issue_probersp(_adapter * padapter,unsigned char * da,u8 is_valid_p2p_probereq)8645 void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
8646 {
8647 struct xmit_frame *pmgntframe;
8648 struct pkt_attrib *pattrib;
8649 unsigned char *pframe;
8650 struct rtw_ieee80211_hdr *pwlanhdr;
8651 unsigned short *fctrl;
8652 unsigned char *mac, *bssid;
8653 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8654 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
8655 u8 *pwps_ie;
8656 uint wps_ielen;
8657 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8658 #endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
8659 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8660 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8661 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
8662 unsigned int rate_len;
8663 #ifdef CONFIG_P2P
8664 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8665 #endif /* CONFIG_P2P */
8666
8667 /* RTW_INFO("%s\n", __FUNCTION__); */
8668
8669 if (da == NULL)
8670 return;
8671
8672 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8673 return;
8674
8675 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8676 if (pmgntframe == NULL) {
8677 RTW_INFO("%s, alloc mgnt frame fail\n", __FUNCTION__);
8678 return;
8679 }
8680
8681
8682 /* update attribute */
8683 pattrib = &pmgntframe->attrib;
8684 update_mgntframe_attrib(padapter, pattrib);
8685
8686 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8687
8688 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8689 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8690
8691 mac = adapter_mac_addr(padapter);
8692 bssid = cur_network->MacAddress;
8693
8694 fctrl = &(pwlanhdr->frame_ctl);
8695 *(fctrl) = 0;
8696 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8697 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8698 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8699
8700 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8701 pmlmeext->mgnt_seq++;
8702 set_frame_sub_type(fctrl, WIFI_PROBERSP);
8703
8704 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8705 pattrib->pktlen = pattrib->hdrlen;
8706 pframe += pattrib->hdrlen;
8707
8708
8709 if (cur_network->IELength > MAX_IE_SZ)
8710 return;
8711
8712 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
8713 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
8714 pwps_ie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wps_ielen);
8715
8716 /* inerset & update wps_probe_resp_ie */
8717 if ((pmlmepriv->wps_probe_resp_ie != NULL) && pwps_ie && (wps_ielen > 0)) {
8718 uint wps_offset, remainder_ielen;
8719 u8 *premainder_ie;
8720
8721 wps_offset = (uint)(pwps_ie - cur_network->IEs);
8722
8723 premainder_ie = pwps_ie + wps_ielen;
8724
8725 remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
8726
8727 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
8728 pframe += wps_offset;
8729 pattrib->pktlen += wps_offset;
8730
8731 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */
8732 if ((wps_offset + wps_ielen + 2) <= MAX_IE_SZ) {
8733 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen + 2);
8734 pframe += wps_ielen + 2;
8735 pattrib->pktlen += wps_ielen + 2;
8736 }
8737
8738 if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) {
8739 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
8740 pframe += remainder_ielen;
8741 pattrib->pktlen += remainder_ielen;
8742 }
8743 } else {
8744 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8745 pframe += cur_network->IELength;
8746 pattrib->pktlen += cur_network->IELength;
8747 }
8748
8749 /* retrieve SSID IE from cur_network->Ssid */
8750 {
8751 u8 *ssid_ie;
8752 sint ssid_ielen;
8753 sint ssid_ielen_diff;
8754 u8 buf[MAX_IE_SZ];
8755 u8 *ies = pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr);
8756
8757 ssid_ie = rtw_get_ie(ies + _FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
8758 (pframe - ies) - _FIXED_IE_LENGTH_);
8759
8760 ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
8761
8762 if (ssid_ie && cur_network->Ssid.SsidLength) {
8763 uint remainder_ielen;
8764 u8 *remainder_ie;
8765 remainder_ie = ssid_ie + 2;
8766 remainder_ielen = (pframe - remainder_ie);
8767
8768 if (remainder_ielen > MAX_IE_SZ) {
8769 RTW_WARN(FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
8770 remainder_ielen = MAX_IE_SZ;
8771 }
8772
8773 _rtw_memcpy(buf, remainder_ie, remainder_ielen);
8774 _rtw_memcpy(remainder_ie + ssid_ielen_diff, buf, remainder_ielen);
8775 *(ssid_ie + 1) = cur_network->Ssid.SsidLength;
8776 _rtw_memcpy(ssid_ie + 2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
8777
8778 pframe += ssid_ielen_diff;
8779 pattrib->pktlen += ssid_ielen_diff;
8780 }
8781 }
8782 #ifdef CONFIG_RTW_REPEATER_SON
8783 rtw_rson_append_ie(padapter, pframe, &pattrib->pktlen);
8784 #endif
8785 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8786 pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_PROBERESP_VENDOR_IE_BIT);
8787 #endif
8788 } else
8789 #endif
8790 {
8791
8792 /* timestamp will be inserted by hardware */
8793 pframe += 8;
8794 pattrib->pktlen += 8;
8795
8796 /* beacon interval: 2 bytes */
8797
8798 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
8799
8800 pframe += 2;
8801 pattrib->pktlen += 2;
8802
8803 /* capability info: 2 bytes */
8804
8805 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
8806
8807 pframe += 2;
8808 pattrib->pktlen += 2;
8809
8810 /* below for ad-hoc mode */
8811
8812 /* SSID */
8813 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
8814
8815 /* supported rates... */
8816 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
8817 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
8818
8819 /* DS parameter set */
8820 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
8821
8822 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
8823 u8 erpinfo = 0;
8824 u32 ATIMWindow;
8825 /* IBSS Parameter Set... */
8826 /* ATIMWindow = cur->Configuration.ATIMWindow; */
8827 ATIMWindow = 0;
8828 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
8829
8830 /* ERP IE */
8831 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
8832 }
8833
8834
8835 /* EXTERNDED SUPPORTED RATE */
8836 if (rate_len > 8)
8837 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
8838
8839
8840 /* todo:HT for adhoc */
8841
8842 }
8843
8844 #ifdef CONFIG_P2P
8845 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
8846 /* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */
8847 && (is_valid_p2p_probereq || !padapter->registrypriv.wifi_spec)) {
8848 u32 len;
8849 #ifdef CONFIG_IOCTL_CFG80211
8850 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
8851 /* if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p() */
8852 len = pmlmepriv->p2p_go_probe_resp_ie_len;
8853 if (pmlmepriv->p2p_go_probe_resp_ie && len > 0)
8854 _rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
8855 } else
8856 #endif /* CONFIG_IOCTL_CFG80211 */
8857 {
8858 len = build_probe_resp_p2p_ie(pwdinfo, pframe);
8859 }
8860
8861 pframe += len;
8862 pattrib->pktlen += len;
8863
8864 #ifdef CONFIG_MCC_MODE
8865 pframe = rtw_hal_mcc_append_go_p2p_ie(padapter, pframe, &pattrib->pktlen);
8866 #endif /* CONFIG_MCC_MODE*/
8867
8868 #ifdef CONFIG_WFD
8869 len = rtw_append_probe_resp_wfd_ie(padapter, pframe);
8870 pframe += len;
8871 pattrib->pktlen += len;
8872 #endif
8873 }
8874 #endif /* CONFIG_P2P */
8875
8876
8877 #ifdef CONFIG_AUTO_AP_MODE
8878 {
8879 struct sta_info *psta;
8880 struct sta_priv *pstapriv = &padapter->stapriv;
8881
8882 RTW_INFO("(%s)\n", __FUNCTION__);
8883
8884 /* check rc station */
8885 psta = rtw_get_stainfo(pstapriv, da);
8886 if (psta && psta->isrc && psta->pid > 0) {
8887 u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A};
8888 u8 RC_INFO[14] = {0};
8889 /* EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] */
8890 u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
8891
8892 RTW_INFO("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
8893 psta->pid, MAC_ARG(psta->cmn.mac_addr), cu_ch);
8894
8895 /* append vendor specific ie */
8896 _rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
8897 _rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
8898 _rtw_memcpy(&RC_INFO[10], (u8 *)&psta->pid, 2);
8899 _rtw_memcpy(&RC_INFO[12], (u8 *)&cu_ch, 2);
8900
8901 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
8902 }
8903 }
8904 #endif /* CONFIG_AUTO_AP_MODE */
8905
8906 #ifdef CONFIG_RTL8812A
8907 pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen);
8908 #endif/*CONFIG_RTL8812A*/
8909
8910 pattrib->last_txcmdsz = pattrib->pktlen;
8911
8912
8913 dump_mgntframe(padapter, pmgntframe);
8914
8915 return;
8916
8917 }
8918
_issue_probereq(_adapter * padapter,const NDIS_802_11_SSID * pssid,const u8 * da,u8 ch,bool append_wps,int wait_ack)8919 int _issue_probereq(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 *da, u8 ch, bool append_wps, int wait_ack)
8920 {
8921 int ret = _FAIL;
8922 struct xmit_frame *pmgntframe;
8923 struct pkt_attrib *pattrib;
8924 unsigned char *pframe;
8925 struct rtw_ieee80211_hdr *pwlanhdr;
8926 unsigned short *fctrl;
8927 unsigned char *mac;
8928 unsigned char bssrate[NumRates];
8929 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8930 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8931 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8932 int bssrate_len = 0;
8933 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8934 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
8935 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
8936 #endif
8937
8938 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8939 goto exit;
8940
8941 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8942 if (pmgntframe == NULL)
8943 goto exit;
8944
8945 /* update attribute */
8946 pattrib = &pmgntframe->attrib;
8947 update_mgntframe_attrib(padapter, pattrib);
8948
8949
8950 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8951
8952 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8953 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8954
8955 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
8956 if ((pwdev_priv->pno_mac_addr[0] != 0xFF)
8957 && (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE)
8958 && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE))
8959 mac = pwdev_priv->pno_mac_addr;
8960 else
8961 #endif
8962 mac = adapter_mac_addr(padapter);
8963
8964 fctrl = &(pwlanhdr->frame_ctl);
8965 *(fctrl) = 0;
8966
8967 if (da) {
8968 /* unicast probe request frame */
8969 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8970 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
8971 } else {
8972 /* broadcast probe request frame */
8973 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8974 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8975 }
8976
8977 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8978
8979 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
8980 if ((pwdev_priv->pno_mac_addr[0] != 0xFF)
8981 && (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE)
8982 && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE)) {
8983 #ifdef CONFIG_RTW_DEBUG
8984 RTW_DBG("%s pno_scan_seq_num: %d\n", __func__,
8985 pwdev_priv->pno_scan_seq_num);
8986 #endif
8987 SetSeqNum(pwlanhdr, pwdev_priv->pno_scan_seq_num);
8988 pattrib->seqnum = pwdev_priv->pno_scan_seq_num;
8989 pattrib->qos_en = 1;
8990 pwdev_priv->pno_scan_seq_num++;
8991 } else
8992 #endif
8993 {
8994 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8995 pmlmeext->mgnt_seq++;
8996 }
8997 set_frame_sub_type(pframe, WIFI_PROBEREQ);
8998
8999 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9000 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9001
9002 if (pssid && !MLME_IS_MESH(padapter))
9003 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
9004 else
9005 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
9006
9007 get_rate_set(padapter, bssrate, &bssrate_len);
9008
9009 if (bssrate_len > 8) {
9010 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
9011 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
9012 } else
9013 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
9014
9015 if (ch)
9016 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen);
9017
9018 #ifdef CONFIG_RTW_MESH
9019 if (MLME_IS_MESH(padapter)) {
9020 if (pssid)
9021 pframe = rtw_set_ie_mesh_id(pframe, &pattrib->pktlen, pssid->Ssid, pssid->SsidLength);
9022 else
9023 pframe = rtw_set_ie_mesh_id(pframe, &pattrib->pktlen, NULL, 0);
9024 }
9025 #endif
9026
9027 if (append_wps) {
9028 /* add wps_ie for wps2.0 */
9029 if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) {
9030 _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
9031 pframe += pmlmepriv->wps_probe_req_ie_len;
9032 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
9033 /* pmlmepriv->wps_probe_req_ie_len = 0 ; */ /* reset to zero */
9034 }
9035 }
9036 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
9037 pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_PROBEREQ_VENDOR_IE_BIT);
9038 #endif
9039
9040 #ifdef CONFIG_RTL8812A
9041 pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen );
9042 #endif/*CONFIG_RTL8812A*/
9043
9044
9045 #ifdef CONFIG_RTW_MBO
9046 rtw_mbo_build_probe_req_ies( padapter, &pframe, pattrib);
9047 #endif
9048
9049 pattrib->last_txcmdsz = pattrib->pktlen;
9050
9051
9052 if (wait_ack)
9053 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9054 else {
9055 dump_mgntframe(padapter, pmgntframe);
9056 ret = _SUCCESS;
9057 }
9058
9059 exit:
9060 return ret;
9061 }
9062
issue_probereq(_adapter * padapter,const NDIS_802_11_SSID * pssid,const u8 * da)9063 inline void issue_probereq(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 *da)
9064 {
9065 _issue_probereq(padapter, pssid, da, 0, 1, _FALSE);
9066 }
9067
9068 /*
9069 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9070 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9071 * try_cnt means the maximal TX count to try
9072 */
issue_probereq_ex(_adapter * padapter,const NDIS_802_11_SSID * pssid,const u8 * da,u8 ch,bool append_wps,int try_cnt,int wait_ms)9073 int issue_probereq_ex(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 *da, u8 ch, bool append_wps,
9074 int try_cnt, int wait_ms)
9075 {
9076 int ret = _FAIL;
9077 int i = 0;
9078 systime start = rtw_get_current_time();
9079
9080 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9081 goto exit;
9082
9083 do {
9084 ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms > 0 ? _TRUE : _FALSE);
9085
9086 i++;
9087
9088 if (RTW_CANNOT_RUN(padapter))
9089 break;
9090
9091 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
9092 rtw_msleep_os(wait_ms);
9093
9094 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
9095
9096 if (ret != _FAIL) {
9097 ret = _SUCCESS;
9098 #ifndef DBG_XMIT_ACK
9099 goto exit;
9100 #endif
9101 }
9102
9103 if (try_cnt && wait_ms) {
9104 if (da)
9105 RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9106 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9107 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9108 else
9109 RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9110 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9111 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9112 }
9113 exit:
9114 return ret;
9115 }
9116
9117 /* if psta == NULL, indiate we are station(client) now... */
issue_auth(_adapter * padapter,struct sta_info * psta,unsigned short status)9118 void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
9119 {
9120 struct xmit_frame *pmgntframe;
9121 struct pkt_attrib *pattrib;
9122 unsigned char *pframe;
9123 struct rtw_ieee80211_hdr *pwlanhdr;
9124 unsigned short *fctrl;
9125 unsigned int val32;
9126 unsigned short val16;
9127 int use_shared_key = 0;
9128 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9129 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9130 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9131
9132 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9133 return;
9134
9135 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9136 if (pmgntframe == NULL)
9137 return;
9138
9139 /* update attribute */
9140 pattrib = &pmgntframe->attrib;
9141 update_mgntframe_attrib(padapter, pattrib);
9142
9143 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9144
9145 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9146 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9147
9148 fctrl = &(pwlanhdr->frame_ctl);
9149 *(fctrl) = 0;
9150
9151 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9152 pmlmeext->mgnt_seq++;
9153 set_frame_sub_type(pframe, WIFI_AUTH);
9154
9155 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9156 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9157
9158
9159 if (psta) { /* for AP mode */
9160 #ifdef CONFIG_NATIVEAP_MLME
9161
9162 _rtw_memcpy(pwlanhdr->addr1, psta->cmn.mac_addr, ETH_ALEN);
9163 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9164 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
9165
9166
9167 /* setting auth algo number */
9168 val16 = (u16)psta->authalg;
9169
9170 if (status != _STATS_SUCCESSFUL_)
9171 val16 = 0;
9172
9173 if (val16) {
9174 val16 = cpu_to_le16(val16);
9175 use_shared_key = 1;
9176 }
9177
9178 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
9179
9180 /* setting auth seq number */
9181 val16 = (u16)psta->auth_seq;
9182 val16 = cpu_to_le16(val16);
9183 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
9184
9185 /* setting status code... */
9186 val16 = status;
9187 val16 = cpu_to_le16(val16);
9188 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
9189
9190 /* added challenging text... */
9191 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
9192 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
9193 #endif
9194 } else {
9195 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
9196 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9197 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
9198
9199 #ifdef CONFIG_RTW_80211R
9200 if (rtw_ft_roam(padapter)) {
9201 /* 2: 802.11R FTAA */
9202 val16 = cpu_to_le16(2);
9203 } else
9204 #endif
9205 {
9206 /* setting auth algo number */
9207 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0; /* 0:OPEN System, 1:Shared key */
9208 if (val16) {
9209 val16 = cpu_to_le16(val16);
9210 use_shared_key = 1;
9211 }
9212 }
9213
9214 /* RTW_INFO("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq); */
9215
9216 /* setting IV for auth seq #3 */
9217 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
9218 /* RTW_INFO("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index); */
9219 val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
9220 val32 = cpu_to_le32(val32);
9221 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
9222
9223 pattrib->iv_len = 4;
9224 }
9225
9226 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
9227
9228 /* setting auth seq number */
9229 val16 = pmlmeinfo->auth_seq;
9230 val16 = cpu_to_le16(val16);
9231 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
9232
9233
9234 /* setting status code... */
9235 val16 = status;
9236 val16 = cpu_to_le16(val16);
9237 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
9238
9239 #ifdef CONFIG_RTW_80211R
9240 rtw_ft_build_auth_req_ies(padapter, pattrib, &pframe);
9241 #endif
9242
9243 /* then checking to see if sending challenging text... */
9244 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
9245 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
9246
9247 SetPrivacy(fctrl);
9248
9249 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9250
9251 pattrib->encrypt = _WEP40_;
9252
9253 pattrib->icv_len = 4;
9254
9255 pattrib->pktlen += pattrib->icv_len;
9256
9257 }
9258
9259 }
9260
9261 pattrib->last_txcmdsz = pattrib->pktlen;
9262
9263 rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
9264 RTW_INFO("%s to "MAC_FMT" status:%u\n", __FUNCTION__, MAC_ARG(pwlanhdr->addr1), status);
9265 dump_mgntframe(padapter, pmgntframe);
9266
9267 return;
9268 }
9269
9270
issue_asocrsp(_adapter * padapter,unsigned short status,struct sta_info * pstat,int pkt_type)9271 void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
9272 {
9273 #ifdef CONFIG_AP_MODE
9274 struct xmit_frame *pmgntframe;
9275 struct rtw_ieee80211_hdr *pwlanhdr;
9276 struct pkt_attrib *pattrib;
9277 unsigned char *pbuf, *pframe;
9278 unsigned short val, ie_status;
9279 unsigned short *fctrl;
9280 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9281 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9282 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9283 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9284 WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
9285 u8 *ie = pnetwork->IEs, cap[5], i;
9286 struct security_priv *psecuritypriv = &(padapter->securitypriv);
9287 #ifdef CONFIG_P2P
9288 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
9289 #ifdef CONFIG_WFD
9290 u32 wfdielen = 0;
9291 #endif
9292
9293 #endif /* CONFIG_P2P */
9294
9295 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9296 return;
9297
9298 RTW_INFO("%s to "MAC_FMT" status:%u\n", __FUNCTION__, MAC_ARG(pstat->cmn.mac_addr), status);
9299
9300 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9301 if (pmgntframe == NULL)
9302 return;
9303
9304 /* update attribute */
9305 pattrib = &pmgntframe->attrib;
9306 update_mgntframe_attrib(padapter, pattrib);
9307
9308
9309 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9310
9311 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9312 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9313
9314 fctrl = &(pwlanhdr->frame_ctl);
9315 *(fctrl) = 0;
9316
9317 _rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->cmn.mac_addr, ETH_ALEN);
9318 _rtw_memcpy((void *)get_addr2_ptr(pwlanhdr), adapter_mac_addr(padapter), ETH_ALEN);
9319 _rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9320
9321
9322 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9323 pmlmeext->mgnt_seq++;
9324 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
9325 set_frame_sub_type(pwlanhdr, pkt_type);
9326 else
9327 return;
9328
9329 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9330 pattrib->pktlen += pattrib->hdrlen;
9331 pframe += pattrib->hdrlen;
9332
9333 /* capability */
9334 val = *(unsigned short *)rtw_get_capability_from_ie(ie);
9335 #ifdef CONFIG_RTW_80211K
9336 val |= cap_RM;
9337 #endif
9338 pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
9339
9340 ie_status = cpu_to_le16(status);
9341 pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&ie_status, &(pattrib->pktlen));
9342
9343 val = cpu_to_le16(pstat->cmn.aid | BIT(14) | BIT(15));
9344 pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
9345
9346 if (pstat->bssratelen <= 8)
9347 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
9348 else {
9349 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
9350 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen - 8), pstat->bssrateset + 8, &(pattrib->pktlen));
9351 }
9352
9353 #ifdef CONFIG_IEEE80211W
9354 if (status == _STATS_REFUSED_TEMPORARILY_) {
9355 u8 timeout_itvl[5];
9356 u32 timeout_interval = 3000;
9357 /* Association Comeback time */
9358 timeout_itvl[0] = 0x03;
9359 timeout_interval = cpu_to_le32(timeout_interval);
9360 _rtw_memcpy(timeout_itvl + 1, &timeout_interval, 4);
9361 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
9362 }
9363 #endif /* CONFIG_IEEE80211W */
9364
9365 #ifdef CONFIG_80211N_HT
9366 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) {
9367 uint ie_len = 0;
9368
9369 /* FILL HT CAP INFO IE */
9370 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
9371 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
9372 if (pbuf && ie_len > 0) {
9373 _rtw_memcpy(pframe, pbuf, ie_len + 2);
9374 pframe += (ie_len + 2);
9375 pattrib->pktlen += (ie_len + 2);
9376 }
9377
9378 /* FILL HT ADD INFO IE */
9379 /* p = hostapd_eid_ht_operation(hapd, p); */
9380 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
9381 if (pbuf && ie_len > 0) {
9382 _rtw_memcpy(pframe, pbuf, ie_len + 2);
9383 pframe += (ie_len + 2);
9384 pattrib->pktlen += (ie_len + 2);
9385 }
9386
9387 }
9388 #endif
9389
9390 /*adding EXT_CAPAB_IE */
9391 if (pmlmepriv->ext_capab_ie_len > 0) {
9392 uint ie_len = 0;
9393
9394 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_EXT_CAP, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
9395 if (pbuf && ie_len > 0) {
9396 _rtw_memcpy(pframe, pbuf, ie_len + 2);
9397 pframe += (ie_len + 2);
9398 pattrib->pktlen += (ie_len + 2);
9399 }
9400 }
9401
9402 #ifdef CONFIG_80211AC_VHT
9403 if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option)
9404 && (pstat->wpa_pairwise_cipher != WPA_CIPHER_TKIP)
9405 && (pstat->wpa2_pairwise_cipher != WPA_CIPHER_TKIP)) {
9406 u32 ie_len = 0;
9407
9408 /* FILL VHT CAP IE */
9409 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
9410 if (pbuf && ie_len > 0) {
9411 _rtw_memcpy(pframe, pbuf, ie_len + 2);
9412 pframe += (ie_len + 2);
9413 pattrib->pktlen += (ie_len + 2);
9414 }
9415
9416 /* FILL VHT OPERATION IE */
9417 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
9418 if (pbuf && ie_len > 0) {
9419 _rtw_memcpy(pframe, pbuf, ie_len + 2);
9420 pframe += (ie_len + 2);
9421 pattrib->pktlen += (ie_len + 2);
9422 }
9423 }
9424 #endif /* CONFIG_80211AC_VHT */
9425
9426 #ifdef CONFIG_RTW_80211K
9427 /* FILL RM Enabled Capabilities with joint capabilities */
9428 for (i = 0; i < 5; i++) {
9429 cap[i] = padapter->rmpriv.rm_en_cap_def[i]
9430 & pstat->rm_en_cap[i];
9431 }
9432 if (pstat->capability & cap_RM)
9433 pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, 5,
9434 (u8 *)cap, &(pattrib->pktlen));
9435 #endif /* CONFIG_RTW_80211K */
9436
9437 /* FILL WMM IE */
9438 if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) {
9439 uint ie_len = 0;
9440 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
9441
9442 for (pbuf = ie + _BEACON_IE_OFFSET_; ; pbuf += (ie_len + 2)) {
9443 pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
9444 if (pbuf && _rtw_memcmp(pbuf + 2, WMM_PARA_IE, 6)) {
9445 _rtw_memcpy(pframe, pbuf, ie_len + 2);
9446 pframe += (ie_len + 2);
9447 pattrib->pktlen += (ie_len + 2);
9448
9449 break;
9450 }
9451
9452 if ((pbuf == NULL) || (ie_len == 0))
9453 break;
9454 }
9455
9456 }
9457
9458
9459 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
9460 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
9461
9462 /* add WPS IE ie for wps 2.0 */
9463 if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) {
9464 _rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
9465
9466 pframe += pmlmepriv->wps_assoc_resp_ie_len;
9467 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
9468 }
9469
9470
9471 if ((psecuritypriv->auth_type == MLME_AUTHTYPE_SAE) &&
9472 pmlmepriv->assoc_rsp && pmlmepriv->assoc_rsp_len > 0) {
9473 _rtw_memcpy(pframe, pmlmepriv->assoc_rsp, pmlmepriv->assoc_rsp_len);
9474 pframe += pmlmepriv->assoc_rsp_len;
9475 pattrib->pktlen += pmlmepriv->assoc_rsp_len;
9476 }
9477
9478 #ifdef CONFIG_P2P
9479 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE)) {
9480 u32 len;
9481
9482 if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
9483 len = 0;
9484 if (pmlmepriv->p2p_assoc_resp_ie && pmlmepriv->p2p_assoc_resp_ie_len > 0) {
9485 len = pmlmepriv->p2p_assoc_resp_ie_len;
9486 _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_resp_ie, len);
9487 } else if (pmlmepriv->assoc_rsp && pmlmepriv->assoc_rsp_len > 0) {
9488 len = pmlmepriv->assoc_rsp_len;
9489 _rtw_memcpy(pframe, pmlmepriv->assoc_rsp, len);
9490 }
9491 } else
9492 len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
9493 pframe += len;
9494 pattrib->pktlen += len;
9495 }
9496
9497 #ifdef CONFIG_WFD
9498 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
9499 wfdielen = rtw_append_assoc_resp_wfd_ie(padapter, pframe);
9500 pframe += wfdielen;
9501 pattrib->pktlen += wfdielen;
9502 }
9503 #endif
9504
9505 #endif /* CONFIG_P2P */
9506
9507 #ifdef CONFIG_RTW_MULTI_AP
9508 if (padapter->multi_ap && (pstat->flags & WLAN_STA_MULTI_AP))
9509 pframe = rtw_set_multi_ap_ie_ext(pframe, &pattrib->pktlen, padapter->multi_ap);
9510 #endif
9511
9512 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
9513 pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_ASSOCRESP_VENDOR_IE_BIT);
9514 #endif
9515
9516 #ifdef CONFIG_RTL8812A
9517 pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen );
9518 #endif/*CONFIG_RTL8812A*/
9519
9520
9521 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
9522 if (padapter->tbtx_capability == _TRUE)
9523 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 8, REALTEK_TBTX_IE, &pattrib->pktlen);
9524 #endif
9525
9526 pattrib->last_txcmdsz = pattrib->pktlen;
9527
9528 dump_mgntframe(padapter, pmgntframe);
9529
9530 #endif
9531 }
9532
rtw_append_assoc_req_owe_ie(_adapter * adapter,u8 * pbuf)9533 static u32 rtw_append_assoc_req_owe_ie(_adapter *adapter, u8 *pbuf)
9534 {
9535 struct security_priv *sec = &adapter->securitypriv;
9536 u32 len = 0;
9537
9538 if (sec == NULL)
9539 goto exit;
9540
9541 if (sec->owe_ie_len > 0) {
9542 len = sec->owe_ie_len;
9543 _rtw_memcpy(pbuf, sec->owe_ie, len);
9544 }
9545
9546 exit:
9547 return len;
9548 }
9549
9550 #ifdef CONFIG_ECSA
build_supported_op_class_ie(_adapter * padapter,u8 * pbuf,int * pktlen)9551 u8 *build_supported_op_class_ie(_adapter *padapter, u8 *pbuf, int *pktlen)
9552 {
9553 u8 buf[32];
9554 int ie_len = 0;
9555
9556 ie_len = get_supported_op_class(padapter, buf, sizeof(buf));
9557 pbuf = rtw_set_ie(pbuf, EID_SupRegulatory , ie_len,
9558 (unsigned char *)buf, pktlen);
9559 return pbuf;
9560 }
9561 #endif /* CONFIG_ECSA */
9562
_issue_assocreq(_adapter * padapter,u8 is_reassoc)9563 void _issue_assocreq(_adapter *padapter, u8 is_reassoc)
9564 {
9565 int ret = _FAIL;
9566 struct xmit_frame *pmgntframe;
9567 struct pkt_attrib *pattrib;
9568 unsigned char *pframe;
9569 struct rtw_ieee80211_hdr *pwlanhdr;
9570 unsigned short *fctrl;
9571 unsigned short val16;
9572 unsigned int i, j, index = 0;
9573 unsigned char bssrate[NumRates], sta_bssrate[NumRates];
9574 PNDIS_802_11_VARIABLE_IEs pIE;
9575 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9576 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9577 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9578 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9579 int bssrate_len = 0, sta_bssrate_len = 0;
9580 u8 vs_ie_length = 0;
9581 #ifdef CONFIG_P2P
9582 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
9583 u8 p2pie[255] = { 0x00 };
9584 u16 p2pielen = 0;
9585 #ifdef CONFIG_WFD
9586 u32 wfdielen = 0;
9587 #endif
9588 #endif /* CONFIG_P2P */
9589
9590 #if CONFIG_DFS
9591 u16 cap;
9592 #endif
9593
9594 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9595 goto exit;
9596
9597 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9598 if (pmgntframe == NULL)
9599 goto exit;
9600
9601 /* update attribute */
9602 pattrib = &pmgntframe->attrib;
9603 update_mgntframe_attrib(padapter, pattrib);
9604
9605 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9606
9607 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9608 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9609
9610 fctrl = &(pwlanhdr->frame_ctl);
9611 *(fctrl) = 0;
9612 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9613 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9614 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9615
9616 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9617 pmlmeext->mgnt_seq++;
9618 if (is_reassoc == _TRUE)
9619 set_frame_sub_type(pframe, WIFI_REASSOCREQ);
9620 else
9621 set_frame_sub_type(pframe, WIFI_ASSOCREQ);
9622
9623 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9624 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9625
9626 /* caps */
9627
9628 #if CONFIG_DFS
9629 _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
9630 cap |= cap_SpecMgmt;
9631 #ifdef CONFIG_RTW_80211K
9632 cap |= cap_RM;
9633 #endif
9634 _rtw_memcpy(pframe, &cap, 2);
9635 #else
9636 _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
9637 #endif
9638
9639 pframe += 2;
9640 pattrib->pktlen += 2;
9641
9642 /* listen interval */
9643 /* todo: listen interval for power saving */
9644 val16 = cpu_to_le16(3);
9645 _rtw_memcpy(pframe , (unsigned char *)&val16, 2);
9646 pframe += 2;
9647 pattrib->pktlen += 2;
9648
9649 /*Construct Current AP Field for Reassoc-Req only*/
9650 if (is_reassoc == _TRUE) {
9651 _rtw_memcpy(pframe, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9652 pframe += ETH_ALEN;
9653 pattrib->pktlen += ETH_ALEN;
9654 }
9655
9656 /* SSID */
9657 pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
9658
9659 #if CONFIG_IEEE80211_BAND_5GHZ && CONFIG_DFS
9660 /* Dot H */
9661 if (pmlmeext->cur_channel > 14) {
9662 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
9663 u8 pow_cap_ele[2] = { 0x00 };
9664 u8 sup_ch[30 * 2] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; /* For supported channel */
9665
9666 pow_cap_ele[0] = 13; /* Minimum transmit power capability */
9667 pow_cap_ele[1] = 21; /* Maximum transmit power capability */
9668 pframe = rtw_set_ie(pframe, EID_PowerCap, 2, pow_cap_ele, &(pattrib->pktlen));
9669
9670 /* supported channels */
9671 while (sup_ch_idx < rfctl->max_chan_nums && rfctl->channel_set[sup_ch_idx].ChannelNum != 0) {
9672 if (rfctl->channel_set[sup_ch_idx].ChannelNum <= 14) {
9673 /* TODO: fix 2.4G supported channel when channel doesn't start from 1 and continuous */
9674 sup_ch[0] = 1; /* First channel number */
9675 sup_ch[1] = rfctl->channel_set[sup_ch_idx].ChannelNum; /* Number of channel */
9676 } else {
9677 sup_ch[idx_5g++] = rfctl->channel_set[sup_ch_idx].ChannelNum;
9678 sup_ch[idx_5g++] = 1;
9679 }
9680 sup_ch_idx++;
9681 }
9682 pframe = rtw_set_ie(pframe, EID_SupportedChannels, idx_5g, sup_ch, &(pattrib->pktlen));
9683 }
9684 #endif /* CONFIG_IEEE80211_BAND_5GHZ && CONFIG_DFS */
9685
9686 /* supported rate & extended supported rate */
9687
9688 #if 1 /* Check if the AP's supported rates are also supported by STA. */
9689 get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
9690 /* RTW_INFO("sta_bssrate_len=%d\n", sta_bssrate_len); */
9691
9692 if (pmlmeext->cur_channel == 14) /* for JAPAN, channel 14 can only uses B Mode(CCK) */
9693 sta_bssrate_len = 4;
9694
9695
9696 /* for (i = 0; i < sta_bssrate_len; i++) { */
9697 /* RTW_INFO("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
9698 /* } */
9699
9700 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
9701 if (pmlmeinfo->network.SupportedRates[i] == 0)
9702 break;
9703 RTW_INFO("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
9704 }
9705
9706
9707 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
9708 if (pmlmeinfo->network.SupportedRates[i] == 0)
9709 break;
9710
9711
9712 /* Check if the AP's supported rates are also supported by STA. */
9713 for (j = 0; j < sta_bssrate_len; j++) {
9714 /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
9715 if ((pmlmeinfo->network.SupportedRates[i] | IEEE80211_BASIC_RATE_MASK)
9716 == (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
9717 /* RTW_INFO("match i = %d, j=%d\n", i, j); */
9718 break;
9719 } else {
9720 /* RTW_INFO("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)); */
9721 }
9722 }
9723
9724 if (j == sta_bssrate_len) {
9725 /* the rate is not supported by STA */
9726 RTW_INFO("%s(): the rate[%d]=%02X is not supported by STA!\n", __FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
9727 } else {
9728 /* the rate is supported by STA */
9729 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
9730 }
9731 }
9732
9733 bssrate_len = index;
9734 RTW_INFO("bssrate_len = %d\n", bssrate_len);
9735
9736 #else /* Check if the AP's supported rates are also supported by STA. */
9737 #if 0
9738 get_rate_set(padapter, bssrate, &bssrate_len);
9739 #else
9740 for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
9741 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0)
9742 break;
9743
9744 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
9745 break;
9746
9747 bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
9748 }
9749 #endif
9750 #endif /* Check if the AP's supported rates are also supported by STA. */
9751
9752 if ((bssrate_len == 0) && (pmlmeinfo->network.SupportedRates[0] != 0)) {
9753 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
9754 rtw_free_xmitframe(pxmitpriv, pmgntframe);
9755 goto exit; /* don't connect to AP if no joint supported rate */
9756 }
9757
9758
9759 if (bssrate_len > 8) {
9760 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
9761 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
9762 } else if (bssrate_len > 0)
9763 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
9764 else
9765 RTW_INFO("%s: Connect to AP without 11b and 11g data rate!\n", __FUNCTION__);
9766
9767 #ifdef CONFIG_ECSA
9768 pframe = build_supported_op_class_ie(padapter, pframe, &pattrib->pktlen);
9769 #endif /* CONFIG_ECSA */
9770
9771 #ifdef CONFIG_RTW_MBO
9772 rtw_mbo_build_assoc_req_ies(padapter, &pframe, pattrib);
9773 #endif
9774 #ifdef CONFIG_RTW_80211R
9775 rtw_ft_build_assoc_req_ies(padapter, is_reassoc, pattrib, &pframe);
9776 #endif
9777 #ifdef CONFIG_RTW_80211K
9778 pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, 5,
9779 (u8 *)padapter->rmpriv.rm_en_cap_def,
9780 &(pattrib->pktlen));
9781 #endif /* CONFIG_RTW_80211K */
9782
9783 /* vendor specific IE, such as WPA, WMM, WPS */
9784 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) {
9785 pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
9786
9787 switch (pIE->ElementID) {
9788 case _VENDOR_SPECIFIC_IE_:
9789 if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
9790 (_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
9791 (_rtw_memcmp(pIE->data, WPS_OUI, 4))) {
9792 vs_ie_length = pIE->Length;
9793 if ((!padapter->registrypriv.wifi_spec) && (_rtw_memcmp(pIE->data, WPS_OUI, 4))) {
9794 /* Commented by Kurt 20110629 */
9795 /* In some older APs, WPS handshake */
9796 /* would be fail if we append vender extensions informations to AP */
9797
9798 vs_ie_length = 14;
9799 }
9800
9801 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen));
9802 }
9803 break;
9804
9805 case EID_WPA2:
9806 #ifdef CONFIG_RTW_80211R
9807 if ((is_reassoc) && (rtw_ft_roam(padapter))) {
9808 rtw_ft_update_rsnie(padapter, _TRUE, pattrib, &pframe);
9809 } else
9810 #endif
9811 {
9812 #ifdef CONFIG_IOCTL_CFG80211
9813 if (rtw_sec_chk_auth_alg(padapter, WLAN_AUTH_OPEN) &&
9814 rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE)) {
9815 s32 entry = rtw_cached_pmkid(padapter, pmlmepriv->assoc_bssid);
9816
9817 rtw_rsn_sync_pmkid(padapter, (u8 *)pIE, (pIE->Length + 2), entry);
9818 }
9819 #endif /* CONFIG_IOCTL_CFG80211 */
9820
9821 pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
9822 /* tmp: update rsn's spp related opt. */
9823 /*rtw_set_spp_amsdu_mode(padapter->registrypriv.amsdu_mode, pframe - (pIE->Length + 2), pIE->Length +2);*/
9824 }
9825 break;
9826 case WLAN_EID_RSNX:
9827 pframe = rtw_set_ie(pframe, WLAN_EID_RSNX, pIE->Length,
9828 pIE->data, &(pattrib->pktlen));
9829 break;
9830 #ifdef CONFIG_80211N_HT
9831 case EID_HTCapability:
9832 if (padapter->mlmepriv.htpriv.ht_option == _TRUE) {
9833 if (!(is_ap_in_tkip(padapter))) {
9834 _rtw_memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
9835
9836 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
9837
9838 pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
9839 }
9840 }
9841 break;
9842 #endif /* CONFIG_80211N_HT */
9843
9844 case WLAN_EID_EXT_CAP:
9845 pframe = rtw_set_ie(pframe, WLAN_EID_EXT_CAP, pIE->Length, pIE->data, &(pattrib->pktlen));
9846 break;
9847
9848 #ifdef CONFIG_80211AC_VHT
9849 case EID_VHTCapability:
9850 if (padapter->mlmepriv.vhtpriv.vht_option == _TRUE)
9851 pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
9852 break;
9853
9854 case EID_OpModeNotification:
9855 if (padapter->mlmepriv.vhtpriv.vht_option == _TRUE)
9856 pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen));
9857 break;
9858 #endif /* CONFIG_80211AC_VHT */
9859 default:
9860 break;
9861 }
9862
9863 i += (pIE->Length + 2);
9864 }
9865 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
9866 if (padapter->tbtx_capability == _TRUE)
9867 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 8 , REALTEK_TBTX_IE, &(pattrib->pktlen));
9868 #endif
9869
9870 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
9871 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
9872
9873
9874 #ifdef CONFIG_WAPI_SUPPORT
9875 rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
9876 #endif
9877
9878
9879 #ifdef CONFIG_P2P
9880
9881 #ifdef CONFIG_IOCTL_CFG80211
9882 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
9883 if (pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len > 0) {
9884 _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
9885 pframe += pmlmepriv->p2p_assoc_req_ie_len;
9886 pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
9887 }
9888 } else
9889 #endif /* CONFIG_IOCTL_CFG80211 */
9890 {
9891 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
9892 /* Should add the P2P IE in the association request frame. */
9893 /* P2P OUI */
9894
9895 p2pielen = 0;
9896 p2pie[p2pielen++] = 0x50;
9897 p2pie[p2pielen++] = 0x6F;
9898 p2pie[p2pielen++] = 0x9A;
9899 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
9900
9901 /* Commented by Albert 20101109 */
9902 /* According to the P2P Specification, the association request frame should contain 3 P2P attributes */
9903 /* 1. P2P Capability */
9904 /* 2. Extended Listen Timing */
9905 /* 3. Device Info */
9906 /* Commented by Albert 20110516 */
9907 /* 4. P2P Interface */
9908
9909 /* P2P Capability */
9910 /* Type: */
9911 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
9912
9913 /* Length: */
9914 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
9915 p2pielen += 2;
9916
9917 /* Value: */
9918 /* Device Capability Bitmap, 1 byte */
9919 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
9920
9921 /* Group Capability Bitmap, 1 byte */
9922 if (pwdinfo->persistent_supported)
9923 p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
9924 else
9925 p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
9926
9927 /* Extended Listen Timing */
9928 /* Type: */
9929 p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
9930
9931 /* Length: */
9932 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
9933 p2pielen += 2;
9934
9935 /* Value: */
9936 /* Availability Period */
9937 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
9938 p2pielen += 2;
9939
9940 /* Availability Interval */
9941 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
9942 p2pielen += 2;
9943
9944 /* Device Info */
9945 /* Type: */
9946 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
9947
9948 /* Length: */
9949 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
9950 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
9951 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
9952 p2pielen += 2;
9953
9954 /* Value: */
9955 /* P2P Device Address */
9956 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
9957 p2pielen += ETH_ALEN;
9958
9959 /* Config Method */
9960 /* This field should be big endian. Noted by P2P specification. */
9961 if ((pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN) ||
9962 (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN))
9963 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
9964 else
9965 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC);
9966
9967 p2pielen += 2;
9968
9969 /* Primary Device Type */
9970 /* Category ID */
9971 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
9972 p2pielen += 2;
9973
9974 /* OUI */
9975 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
9976 p2pielen += 4;
9977
9978 /* Sub Category ID */
9979 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
9980 p2pielen += 2;
9981
9982 /* Number of Secondary Device Types */
9983 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
9984
9985 /* Device Name */
9986 /* Type: */
9987 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
9988 p2pielen += 2;
9989
9990 /* Length: */
9991 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
9992 p2pielen += 2;
9993
9994 /* Value: */
9995 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
9996 p2pielen += pwdinfo->device_name_len;
9997
9998 /* P2P Interface */
9999 /* Type: */
10000 p2pie[p2pielen++] = P2P_ATTR_INTERFACE;
10001
10002 /* Length: */
10003 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x000D);
10004 p2pielen += 2;
10005
10006 /* Value: */
10007 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); /* P2P Device Address */
10008 p2pielen += ETH_ALEN;
10009
10010 p2pie[p2pielen++] = 1; /* P2P Interface Address Count */
10011
10012 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); /* P2P Interface Address List */
10013 p2pielen += ETH_ALEN;
10014
10015 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
10016 }
10017 }
10018
10019 #ifdef CONFIG_WFD
10020 wfdielen = rtw_append_assoc_req_wfd_ie(padapter, pframe);
10021 pframe += wfdielen;
10022 pattrib->pktlen += wfdielen;
10023 #endif
10024 #endif /* CONFIG_P2P */
10025
10026 #ifdef CONFIG_RTW_MULTI_AP
10027 if (padapter->multi_ap)
10028 pframe = rtw_set_multi_ap_ie_ext(pframe, &pattrib->pktlen, padapter->multi_ap);
10029 #endif
10030
10031 /* OWE */
10032 {
10033 u32 owe_ie_len;
10034
10035 owe_ie_len = rtw_append_assoc_req_owe_ie(padapter, pframe);
10036 pframe += owe_ie_len;
10037 pattrib->pktlen += owe_ie_len;
10038 }
10039
10040 #ifdef CONFIG_RTW_REPEATER_SON
10041 rtw_rson_append_ie(padapter, pframe, &pattrib->pktlen);
10042 #endif
10043 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
10044 pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_ASSOCREQ_VENDOR_IE_BIT);
10045 #endif
10046
10047 #ifdef CONFIG_RTL8812A
10048 pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen );
10049 #endif/*CONFIG_RTL8812A*/
10050
10051 pattrib->last_txcmdsz = pattrib->pktlen;
10052 dump_mgntframe(padapter, pmgntframe);
10053
10054 ret = _SUCCESS;
10055
10056 exit:
10057 if (ret == _SUCCESS) {
10058 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
10059 #ifdef CONFIG_RTW_WNM
10060 if (is_reassoc == _TRUE)
10061 rtw_wnm_update_reassoc_req_ie(padapter);
10062 #endif
10063 } else
10064 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
10065
10066 return;
10067 }
10068
issue_assocreq(_adapter * padapter)10069 void issue_assocreq(_adapter *padapter)
10070 {
10071 _issue_assocreq(padapter, _FALSE);
10072 }
10073
issue_reassocreq(_adapter * padapter)10074 void issue_reassocreq(_adapter *padapter)
10075 {
10076 _issue_assocreq(padapter, _TRUE);
10077 }
10078
10079 /* when wait_ack is ture, this function shoule be called at process context */
_issue_nulldata(_adapter * padapter,unsigned char * da,unsigned int power_mode,int wait_ack)10080 static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
10081 {
10082 int ret = _FAIL;
10083 struct xmit_frame *pmgntframe;
10084 struct pkt_attrib *pattrib;
10085 unsigned char *pframe;
10086 struct rtw_ieee80211_hdr *pwlanhdr;
10087 unsigned short *fctrl;
10088 struct xmit_priv *pxmitpriv;
10089 struct mlme_ext_priv *pmlmeext;
10090 struct mlme_ext_info *pmlmeinfo;
10091 u8 a4_shift;
10092
10093 /* RTW_INFO("%s:%d\n", __FUNCTION__, power_mode); */
10094
10095 if (!padapter)
10096 goto exit;
10097
10098 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10099 goto exit;
10100
10101 pxmitpriv = &(padapter->xmitpriv);
10102 pmlmeext = &(padapter->mlmeextpriv);
10103 pmlmeinfo = &(pmlmeext->mlmext_info);
10104
10105 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10106 if (pmgntframe == NULL)
10107 goto exit;
10108
10109 /* update attribute */
10110 pattrib = &pmgntframe->attrib;
10111 update_mgntframe_attrib(padapter, pattrib);
10112 pattrib->retry_ctrl = _FALSE;
10113
10114 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10115
10116 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10117 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10118
10119 fctrl = &(pwlanhdr->frame_ctl);
10120 *(fctrl) = 0;
10121
10122 if (MLME_IS_AP(padapter))
10123 SetFrDs(fctrl);
10124 else if (MLME_IS_STA(padapter))
10125 SetToDs(fctrl);
10126 else if (MLME_IS_MESH(padapter)) {
10127 SetToDs(fctrl);
10128 SetFrDs(fctrl);
10129 }
10130
10131 if (power_mode)
10132 SetPwrMgt(fctrl);
10133
10134 if (get_tofr_ds(fctrl) == 3) {
10135 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
10136 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10137 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
10138 _rtw_memcpy(pwlanhdr->addr4, adapter_mac_addr(padapter), ETH_ALEN);
10139 a4_shift = ETH_ALEN;
10140 pattrib->hdrlen += ETH_ALEN;
10141 } else {
10142 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
10143 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10144 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10145 a4_shift = 0;
10146 }
10147
10148 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10149 pmlmeext->mgnt_seq++;
10150 set_frame_sub_type(pframe, WIFI_DATA_NULL);
10151
10152 pframe += sizeof(struct rtw_ieee80211_hdr_3addr) + a4_shift;
10153 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr) + a4_shift;
10154
10155 pattrib->last_txcmdsz = pattrib->pktlen;
10156
10157 if (wait_ack)
10158 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10159 else {
10160 dump_mgntframe(padapter, pmgntframe);
10161 ret = _SUCCESS;
10162 }
10163
10164 exit:
10165 return ret;
10166 }
10167
10168 /*
10169 * When wait_ms > 0, this function should be called at process context
10170 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10171 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10172 * try_cnt means the maximal TX count to try
10173 * da == NULL for station mode
10174 */
issue_nulldata(_adapter * padapter,unsigned char * da,unsigned int power_mode,int try_cnt,int wait_ms)10175 int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
10176 {
10177 int ret = _FAIL;
10178 int i = 0;
10179 systime start = rtw_get_current_time();
10180 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10181 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10182
10183 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10184 goto exit;
10185
10186 /* da == NULL, assum it's null data for sta to ap */
10187 if (da == NULL)
10188 da = get_my_bssid(&(pmlmeinfo->network));
10189
10190 do {
10191 ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0 ? _TRUE : _FALSE);
10192
10193 i++;
10194
10195 if (RTW_CANNOT_RUN(padapter))
10196 break;
10197
10198 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10199 rtw_msleep_os(wait_ms);
10200
10201 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10202
10203 if (ret != _FAIL) {
10204 ret = _SUCCESS;
10205 #ifndef DBG_XMIT_ACK
10206 goto exit;
10207 #endif
10208 }
10209
10210 if (try_cnt && wait_ms) {
10211 if (da)
10212 RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
10213 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
10214 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10215 else
10216 RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
10217 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
10218 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10219 }
10220 exit:
10221 return ret;
10222 }
10223
10224 /* when wait_ack is ture, this function shoule be called at process context */
_issue_qos_nulldata(_adapter * padapter,unsigned char * da,u16 tid,u8 ps,int wait_ack)10225 static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, u8 ps, int wait_ack)
10226 {
10227 int ret = _FAIL;
10228 struct xmit_frame *pmgntframe;
10229 struct pkt_attrib *pattrib;
10230 unsigned char *pframe;
10231 struct rtw_ieee80211_hdr *pwlanhdr;
10232 unsigned short *fctrl, *qc;
10233 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10234 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10235 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10236 u8 a4_shift;
10237
10238 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10239 goto exit;
10240
10241 /* RTW_INFO("%s\n", __FUNCTION__); */
10242
10243 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10244 if (pmgntframe == NULL)
10245 goto exit;
10246
10247 /* update attribute */
10248 pattrib = &pmgntframe->attrib;
10249 update_mgntframe_attrib(padapter, pattrib);
10250
10251 pattrib->hdrlen += 2;
10252 pattrib->qos_en = _TRUE;
10253 pattrib->eosp = 1;
10254 pattrib->ack_policy = 0;
10255 pattrib->mdata = 0;
10256
10257 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10258
10259 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10260 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10261
10262 fctrl = &(pwlanhdr->frame_ctl);
10263 *(fctrl) = 0;
10264
10265 if (MLME_IS_AP(padapter))
10266 SetFrDs(fctrl);
10267 else if (MLME_IS_STA(padapter))
10268 SetToDs(fctrl);
10269 else if (MLME_IS_MESH(padapter)) {
10270 SetToDs(fctrl);
10271 SetFrDs(fctrl);
10272 }
10273
10274 if (ps)
10275 SetPwrMgt(fctrl);
10276
10277 if (pattrib->mdata)
10278 SetMData(fctrl);
10279
10280 if (get_tofr_ds(fctrl) == 3) {
10281 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
10282 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10283 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
10284 _rtw_memcpy(pwlanhdr->addr4, adapter_mac_addr(padapter), ETH_ALEN);
10285 a4_shift = ETH_ALEN;
10286 pattrib->hdrlen += ETH_ALEN;
10287 } else {
10288 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
10289 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10290 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10291 a4_shift = 0;
10292 }
10293
10294 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
10295
10296 SetPriority(qc, tid);
10297
10298 SetEOSP(qc, pattrib->eosp);
10299
10300 SetAckpolicy(qc, pattrib->ack_policy);
10301
10302 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10303 pmlmeext->mgnt_seq++;
10304 set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
10305
10306 pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos) + a4_shift;
10307 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos) + a4_shift;
10308
10309 pattrib->last_txcmdsz = pattrib->pktlen;
10310
10311 if (wait_ack)
10312 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10313 else {
10314 dump_mgntframe(padapter, pmgntframe);
10315 ret = _SUCCESS;
10316 }
10317
10318 exit:
10319 return ret;
10320 }
10321
10322 /*
10323 * when wait_ms >0 , this function should be called at process context
10324 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10325 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10326 * try_cnt means the maximal TX count to try
10327 * da == NULL for station mode
10328 */
issue_qos_nulldata(_adapter * padapter,unsigned char * da,u16 tid,u8 ps,int try_cnt,int wait_ms)10329 int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, u8 ps, int try_cnt, int wait_ms)
10330 {
10331 int ret = _FAIL;
10332 int i = 0;
10333 systime start = rtw_get_current_time();
10334 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10335 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10336
10337 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10338 goto exit;
10339
10340 /* da == NULL, assum it's null data for sta to ap*/
10341 if (da == NULL)
10342 da = get_my_bssid(&(pmlmeinfo->network));
10343
10344 do {
10345 ret = _issue_qos_nulldata(padapter, da, tid, ps, wait_ms > 0 ? _TRUE : _FALSE);
10346
10347 i++;
10348
10349 if (RTW_CANNOT_RUN(padapter))
10350 break;
10351
10352 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10353 rtw_msleep_os(wait_ms);
10354
10355 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10356
10357 if (ret != _FAIL) {
10358 ret = _SUCCESS;
10359 #ifndef DBG_XMIT_ACK
10360 goto exit;
10361 #endif
10362 }
10363
10364 if (try_cnt && wait_ms) {
10365 if (da)
10366 RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
10367 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
10368 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10369 else
10370 RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
10371 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
10372 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10373 }
10374 exit:
10375 return ret;
10376 }
10377
_issue_deauth(_adapter * padapter,unsigned char * da,unsigned short reason,u8 wait_ack,u8 key_type)10378 static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack, u8 key_type)
10379 {
10380 struct xmit_frame *pmgntframe;
10381 struct pkt_attrib *pattrib;
10382 unsigned char *pframe;
10383 struct rtw_ieee80211_hdr *pwlanhdr;
10384 unsigned short *fctrl;
10385 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10386 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10387 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10388 int ret = _FAIL;
10389 #ifdef CONFIG_P2P
10390 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
10391 #endif /* CONFIG_P2P */
10392
10393 /* RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
10394
10395 #ifdef CONFIG_P2P
10396 if (!(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) && (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
10397 _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
10398 _set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
10399 }
10400 #endif /* CONFIG_P2P */
10401
10402 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10403 goto exit;
10404
10405 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10406 if (pmgntframe == NULL)
10407 goto exit;
10408
10409 /* update attribute */
10410 pattrib = &pmgntframe->attrib;
10411 update_mgntframe_attrib(padapter, pattrib);
10412 pattrib->retry_ctrl = _FALSE;
10413 pattrib->key_type = key_type;
10414 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10415
10416 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10417 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10418
10419 fctrl = &(pwlanhdr->frame_ctl);
10420 *(fctrl) = 0;
10421
10422 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
10423 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10424 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10425
10426 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10427 pmlmeext->mgnt_seq++;
10428 set_frame_sub_type(pframe, WIFI_DEAUTH);
10429
10430 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10431 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10432
10433 reason = cpu_to_le16(reason);
10434 pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
10435
10436 pattrib->last_txcmdsz = pattrib->pktlen;
10437
10438
10439 if (wait_ack)
10440 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10441 else {
10442 dump_mgntframe(padapter, pmgntframe);
10443 ret = _SUCCESS;
10444 }
10445
10446 exit:
10447 return ret;
10448 }
10449
issue_deauth(_adapter * padapter,unsigned char * da,unsigned short reason)10450 int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
10451 {
10452 RTW_INFO("%s reason(%u) to "MAC_FMT"\n", __func__, reason, MAC_ARG(da));
10453 return _issue_deauth(padapter, da, reason, _FALSE, IEEE80211W_RIGHT_KEY);
10454 }
10455
10456 #ifdef CONFIG_IEEE80211W
issue_deauth_11w(_adapter * padapter,unsigned char * da,unsigned short reason,u8 key_type)10457 int issue_deauth_11w(_adapter *padapter, unsigned char *da, unsigned short reason, u8 key_type)
10458 {
10459 RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
10460 return _issue_deauth(padapter, da, reason, _FALSE, key_type);
10461 }
10462 #endif /* CONFIG_IEEE80211W */
10463
10464 /*
10465 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10466 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10467 * try_cnt means the maximal TX count to try
10468 */
issue_deauth_ex(_adapter * padapter,u8 * da,unsigned short reason,int try_cnt,int wait_ms)10469 int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
10470 int wait_ms)
10471 {
10472 int ret = _FAIL;
10473 int i = 0;
10474 systime start = rtw_get_current_time();
10475
10476 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10477 goto exit;
10478
10479 do {
10480 ret = _issue_deauth(padapter, da, reason, wait_ms > 0 ? _TRUE : _FALSE, IEEE80211W_RIGHT_KEY);
10481
10482 i++;
10483
10484 if (RTW_CANNOT_RUN(padapter))
10485 break;
10486
10487 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10488 rtw_msleep_os(wait_ms);
10489
10490 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10491
10492 if (ret != _FAIL) {
10493 ret = _SUCCESS;
10494 #ifndef DBG_XMIT_ACK
10495 goto exit;
10496 #endif
10497 }
10498
10499 if (try_cnt && wait_ms) {
10500 if (da)
10501 RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
10502 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
10503 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10504 else
10505 RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
10506 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
10507 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10508 }
10509 exit:
10510 return ret;
10511 }
10512
issue_action_spct_ch_switch(_adapter * padapter,u8 * ra,u8 new_ch,u8 ch_offset)10513 void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
10514 {
10515 struct xmit_frame *pmgntframe;
10516 struct pkt_attrib *pattrib;
10517 unsigned char *pframe;
10518 struct rtw_ieee80211_hdr *pwlanhdr;
10519 unsigned short *fctrl;
10520 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10521 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10522
10523 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10524 return;
10525
10526 RTW_INFO(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
10527 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
10528
10529 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10530 if (pmgntframe == NULL)
10531 return;
10532
10533 /* update attribute */
10534 pattrib = &pmgntframe->attrib;
10535 update_mgntframe_attrib(padapter, pattrib);
10536
10537 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10538
10539 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10540 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10541
10542 fctrl = &(pwlanhdr->frame_ctl);
10543 *(fctrl) = 0;
10544
10545 _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
10546 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
10547 _rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
10548
10549 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10550 pmlmeext->mgnt_seq++;
10551 set_frame_sub_type(pframe, WIFI_ACTION);
10552
10553 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10554 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10555
10556 /* category, action */
10557 {
10558 u8 category, action;
10559 category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
10560 action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
10561
10562 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10563 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10564 }
10565
10566 pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
10567 pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
10568 hal_ch_offset_to_secondary_ch_offset(ch_offset));
10569
10570 pattrib->last_txcmdsz = pattrib->pktlen;
10571
10572 dump_mgntframe(padapter, pmgntframe);
10573
10574 }
10575
10576 #ifdef CONFIG_IEEE80211W
issue_action_SA_Query(_adapter * padapter,unsigned char * raddr,unsigned char action,unsigned short tid,u8 key_type)10577 void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid, u8 key_type)
10578 {
10579 u8 category = RTW_WLAN_CATEGORY_SA_QUERY;
10580 u16 reason_code;
10581 struct xmit_frame *pmgntframe;
10582 struct pkt_attrib *pattrib;
10583 u8 *pframe;
10584 struct rtw_ieee80211_hdr *pwlanhdr;
10585 u16 *fctrl;
10586 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10587 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10588 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10589 struct sta_info *psta;
10590 struct sta_priv *pstapriv = &padapter->stapriv;
10591 struct registry_priv *pregpriv = &padapter->registrypriv;
10592 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10593
10594 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10595 return;
10596
10597 RTW_INFO("%s, %04x\n", __FUNCTION__, tid);
10598
10599 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10600 if (pmgntframe == NULL) {
10601 RTW_INFO("%s: alloc_mgtxmitframe fail\n", __FUNCTION__);
10602 return;
10603 }
10604
10605 /* update attribute */
10606 pattrib = &pmgntframe->attrib;
10607 update_mgntframe_attrib(padapter, pattrib);
10608 pattrib->key_type = key_type;
10609 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10610
10611 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10612 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10613
10614 fctrl = &(pwlanhdr->frame_ctl);
10615 *(fctrl) = 0;
10616
10617 if (raddr)
10618 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
10619 else
10620 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10621 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10622 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10623
10624 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10625 pmlmeext->mgnt_seq++;
10626 set_frame_sub_type(pframe, WIFI_ACTION);
10627
10628 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10629 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10630
10631 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
10632 pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
10633
10634 switch (action) {
10635 case 0: /* SA Query req */
10636 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
10637 pmlmeext->sa_query_seq++;
10638 /* send sa query request to AP, AP should reply sa query response in 1 second */
10639 if (pattrib->key_type == IEEE80211W_RIGHT_KEY) {
10640 psta = rtw_get_stainfo(pstapriv, pwlanhdr->addr1);
10641 if (psta != NULL) {
10642 /* RTW_INFO("%s, %d, set dot11w_expire_timer\n", __func__, __LINE__); */
10643 _set_timer(&psta->dot11w_expire_timer, 1000);
10644 }
10645 }
10646 break;
10647
10648 case 1: /* SA Query rsp */
10649 tid = cpu_to_le16(tid);
10650 /* RTW_INFO("rtw_set_fixed_ie, %04x\n", tid); */
10651 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen);
10652 break;
10653 default:
10654 break;
10655 }
10656
10657 pattrib->last_txcmdsz = pattrib->pktlen;
10658
10659 dump_mgntframe(padapter, pmgntframe);
10660 }
10661 #endif /* CONFIG_IEEE80211W */
10662
10663 /**
10664 * issue_action_ba - internal function to TX Block Ack action frame
10665 * @padapter: the adapter to TX
10666 * @raddr: receiver address
10667 * @action: Block Ack Action
10668 * @tid: tid
10669 * @size: the announced AMPDU buffer size. used by ADDBA_RESP
10670 * @status: status/reason code. used by ADDBA_RESP, DELBA
10671 * @initiator: if we are the initiator of AMPDU association. used by DELBA
10672 * @wait_ack: used xmit ack
10673 *
10674 * Returns:
10675 * _SUCCESS: No xmit ack is used or acked
10676 * _FAIL: not acked when using xmit ack
10677 */
issue_action_ba(_adapter * padapter,unsigned char * raddr,unsigned char action,u8 tid,u8 size,u16 status,u8 initiator,int wait_ack)10678 static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned char action
10679 , u8 tid, u8 size, u16 status, u8 initiator, int wait_ack)
10680 {
10681 int ret = _FAIL;
10682 u8 category = RTW_WLAN_CATEGORY_BACK;
10683 u16 start_seq;
10684 u16 BA_para_set;
10685 u16 BA_timeout_value;
10686 u16 BA_starting_seqctrl = 0;
10687 struct xmit_frame *pmgntframe;
10688 struct pkt_attrib *pattrib;
10689 u8 *pframe;
10690 struct rtw_ieee80211_hdr *pwlanhdr;
10691 u16 *fctrl;
10692 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10693 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10694 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10695 struct sta_info *psta;
10696 struct sta_priv *pstapriv = &padapter->stapriv;
10697 struct registry_priv *pregpriv = &padapter->registrypriv;
10698
10699 #ifdef CONFIG_80211N_HT
10700
10701 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10702 goto exit;
10703
10704 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10705 if (pmgntframe == NULL)
10706 goto exit;
10707
10708 /* update attribute */
10709 pattrib = &pmgntframe->attrib;
10710 update_mgntframe_attrib(padapter, pattrib);
10711
10712 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10713
10714 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10715 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10716
10717 fctrl = &(pwlanhdr->frame_ctl);
10718 *(fctrl) = 0;
10719
10720 /* _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */
10721 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
10722 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10723 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10724
10725 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10726 pmlmeext->mgnt_seq++;
10727 set_frame_sub_type(pframe, WIFI_ACTION);
10728
10729 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10730 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10731
10732 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10733 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10734
10735 if (category == 3) {
10736 switch (action) {
10737 case RTW_WLAN_ACTION_ADDBA_REQ:
10738 do {
10739 pmlmeinfo->dialogToken++;
10740 } while (pmlmeinfo->dialogToken == 0);
10741 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
10742
10743 #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
10744 BA_para_set = (0x0802 | ((tid & 0xf) << 2)); /* immediate ack & 16 buffer size */
10745 #else
10746 BA_para_set = (0x1002 | ((tid & 0xf) << 2)); /* immediate ack & 64 buffer size */
10747 #endif
10748
10749 #ifdef CONFIG_TX_AMSDU
10750 if (padapter->tx_amsdu >= 1) /* TX AMSDU enabled */
10751 BA_para_set |= BIT(0);
10752 else /* TX AMSDU disabled */
10753 BA_para_set &= ~BIT(0);
10754 #endif
10755 psta = rtw_get_stainfo(pstapriv, raddr);
10756 if (psta != NULL) {
10757 if (psta->flags & WLAN_STA_AMSDU_DISABLE)
10758 BA_para_set &= ~BIT(0);
10759 }
10760
10761 BA_para_set = cpu_to_le16(BA_para_set);
10762 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
10763
10764 /* BA_timeout_value = 0xffff; */ /* max: 65535 TUs(~ 65 ms) */
10765 BA_timeout_value = 5000;/* ~ 5ms */
10766 BA_timeout_value = cpu_to_le16(BA_timeout_value);
10767 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
10768
10769 /* if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) */
10770 psta = rtw_get_stainfo(pstapriv, raddr);
10771 if (psta != NULL) {
10772 start_seq = (psta->sta_xmitpriv.txseq_tid[tid & 0x07] & 0xfff) + 1;
10773
10774 RTW_INFO("BA_starting_seqctrl = %d for TID=%d\n", start_seq, tid & 0x07);
10775
10776 psta->BA_starting_seqctrl[tid & 0x07] = start_seq;
10777
10778 BA_starting_seqctrl = start_seq << 4;
10779 }
10780
10781 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
10782 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
10783 break;
10784
10785 case RTW_WLAN_ACTION_ADDBA_RESP:
10786 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
10787 status = cpu_to_le16(status);
10788 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
10789
10790 BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set);
10791
10792 BA_para_set &= ~IEEE80211_ADDBA_PARAM_TID_MASK;
10793 BA_para_set |= (tid << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
10794
10795 BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
10796 BA_para_set |= (size << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
10797
10798 if (!padapter->registrypriv.wifi_spec) {
10799 if (pregpriv->rx_ampdu_amsdu == 0) /* disabled */
10800 BA_para_set &= ~BIT(0);
10801 else if (pregpriv->rx_ampdu_amsdu == 1) /* enabled */
10802 BA_para_set |= BIT(0);
10803 }
10804
10805 psta = rtw_get_stainfo(pstapriv, raddr);
10806 if (psta != NULL) {
10807 if (psta->flags & WLAN_STA_AMSDU_DISABLE)
10808 BA_para_set &= ~BIT(0);
10809 }
10810
10811 BA_para_set = cpu_to_le16(BA_para_set);
10812
10813 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
10814 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
10815 break;
10816
10817 case RTW_WLAN_ACTION_DELBA:
10818 BA_para_set = 0;
10819 BA_para_set |= (tid << 12) & IEEE80211_DELBA_PARAM_TID_MASK;
10820 BA_para_set |= (initiator << 11) & IEEE80211_DELBA_PARAM_INITIATOR_MASK;
10821
10822 BA_para_set = cpu_to_le16(BA_para_set);
10823 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
10824 status = cpu_to_le16(status);
10825 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(status)), &(pattrib->pktlen));
10826 break;
10827 default:
10828 break;
10829 }
10830 }
10831
10832 pattrib->last_txcmdsz = pattrib->pktlen;
10833
10834 if (wait_ack)
10835 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10836 else {
10837 dump_mgntframe(padapter, pmgntframe);
10838 ret = _SUCCESS;
10839 }
10840
10841 exit:
10842 #endif /* CONFIG_80211N_HT */
10843 return ret;
10844 }
10845
10846 /**
10847 * issue_addba_req - TX ADDBA_REQ
10848 * @adapter: the adapter to TX
10849 * @ra: receiver address
10850 * @tid: tid
10851 */
issue_addba_req(_adapter * adapter,unsigned char * ra,u8 tid)10852 inline void issue_addba_req(_adapter *adapter, unsigned char *ra, u8 tid)
10853 {
10854 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_REQ
10855 , tid
10856 , 0 /* unused */
10857 , 0 /* unused */
10858 , 0 /* unused */
10859 , _FALSE
10860 );
10861 RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u\n"
10862 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid);
10863
10864 }
10865
10866 /**
10867 * issue_addba_rsp - TX ADDBA_RESP
10868 * @adapter: the adapter to TX
10869 * @ra: receiver address
10870 * @tid: tid
10871 * @status: status code
10872 * @size: the announced AMPDU buffer size
10873 */
issue_addba_rsp(_adapter * adapter,unsigned char * ra,u8 tid,u16 status,u8 size)10874 inline void issue_addba_rsp(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size)
10875 {
10876 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
10877 , tid
10878 , size
10879 , status
10880 , 0 /* unused */
10881 , _FALSE
10882 );
10883 RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" status=%u, tid=%u, size=%u\n"
10884 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size);
10885 }
10886
10887 /**
10888 * issue_addba_rsp_wait_ack - TX ADDBA_RESP and wait ack
10889 * @adapter: the adapter to TX
10890 * @ra: receiver address
10891 * @tid: tid
10892 * @status: status code
10893 * @size: the announced AMPDU buffer size
10894 * @try_cnt: the maximal TX count to try
10895 * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10896 * > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10897 */
issue_addba_rsp_wait_ack(_adapter * adapter,unsigned char * ra,u8 tid,u16 status,u8 size,int try_cnt,int wait_ms)10898 inline u8 issue_addba_rsp_wait_ack(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size, int try_cnt, int wait_ms)
10899 {
10900 int ret = _FAIL;
10901 int i = 0;
10902 systime start = rtw_get_current_time();
10903
10904 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(adapter)))
10905 goto exit;
10906
10907 do {
10908 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
10909 , tid
10910 , size
10911 , status
10912 , 0 /* unused */
10913 , _TRUE
10914 );
10915
10916 i++;
10917
10918 if (RTW_CANNOT_RUN(adapter))
10919 break;
10920
10921 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10922 rtw_msleep_os(wait_ms);
10923
10924 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10925
10926 if (ret != _FAIL) {
10927 ret = _SUCCESS;
10928 #ifndef DBG_XMIT_ACK
10929 /* goto exit; */
10930 #endif
10931 }
10932
10933 if (try_cnt && wait_ms) {
10934 RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" status:=%u tid=%u size:%u%s, %d/%d in %u ms\n"
10935 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size
10936 , ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10937 }
10938
10939 exit:
10940 return ret;
10941 }
10942
10943 /**
10944 * issue_del_ba - TX DELBA
10945 * @adapter: the adapter to TX
10946 * @ra: receiver address
10947 * @tid: tid
10948 * @reason: reason code
10949 * @initiator: if we are the initiator of AMPDU association. used by DELBA
10950 */
issue_del_ba(_adapter * adapter,unsigned char * ra,u8 tid,u16 reason,u8 initiator)10951 inline void issue_del_ba(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator)
10952 {
10953 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10954 , tid
10955 , 0 /* unused */
10956 , reason
10957 , initiator
10958 , _FALSE
10959 );
10960 RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u\n"
10961 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator);
10962 }
10963
10964 /**
10965 * issue_del_ba_ex - TX DELBA with xmit ack options
10966 * @adapter: the adapter to TX
10967 * @ra: receiver address
10968 * @tid: tid
10969 * @reason: reason code
10970 * @initiator: if we are the initiator of AMPDU association. used by DELBA
10971 * @try_cnt: the maximal TX count to try
10972 * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10973 * > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10974 */
issue_del_ba_ex(_adapter * adapter,unsigned char * ra,u8 tid,u16 reason,u8 initiator,int try_cnt,int wait_ms)10975 int issue_del_ba_ex(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator
10976 , int try_cnt, int wait_ms)
10977 {
10978 int ret = _FAIL;
10979 int i = 0;
10980 systime start = rtw_get_current_time();
10981
10982 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(adapter)))
10983 goto exit;
10984
10985 do {
10986 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10987 , tid
10988 , 0 /* unused */
10989 , reason
10990 , initiator
10991 , wait_ms > 0 ? _TRUE : _FALSE
10992 );
10993
10994 i++;
10995
10996 if (RTW_CANNOT_RUN(adapter))
10997 break;
10998
10999 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
11000 rtw_msleep_os(wait_ms);
11001
11002 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
11003
11004 if (ret != _FAIL) {
11005 ret = _SUCCESS;
11006 #ifndef DBG_XMIT_ACK
11007 /* goto exit; */
11008 #endif
11009 }
11010
11011 if (try_cnt && wait_ms) {
11012 RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u%s, %d/%d in %u ms\n"
11013 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator
11014 , ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
11015 }
11016 exit:
11017 return ret;
11018 }
11019
issue_action_BSSCoexistPacket(_adapter * padapter)11020 void issue_action_BSSCoexistPacket(_adapter *padapter)
11021 {
11022 _irqL irqL;
11023 _list *plist, *phead;
11024 unsigned char category, action;
11025 struct xmit_frame *pmgntframe;
11026 struct pkt_attrib *pattrib;
11027 unsigned char *pframe;
11028 struct rtw_ieee80211_hdr *pwlanhdr;
11029 unsigned short *fctrl;
11030 struct wlan_network *pnetwork = NULL;
11031 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
11032 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11033 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
11034 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11035 _queue *queue = &(pmlmepriv->scanned_queue);
11036 u8 InfoContent[16] = {0};
11037 u8 ICS[8][15];
11038 #ifdef CONFIG_80211N_HT
11039 if ((pmlmepriv->num_FortyMHzIntolerant == 0) && (pmlmepriv->num_sta_no_ht == 0))
11040 return;
11041
11042 if (_TRUE == pmlmeinfo->bwmode_updated)
11043 return;
11044
11045 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
11046 return;
11047
11048 RTW_INFO("%s\n", __FUNCTION__);
11049
11050
11051 category = RTW_WLAN_CATEGORY_PUBLIC;
11052 action = ACT_PUBLIC_BSSCOEXIST;
11053
11054 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
11055 if (pmgntframe == NULL)
11056 return;
11057
11058 /* update attribute */
11059 pattrib = &pmgntframe->attrib;
11060 update_mgntframe_attrib(padapter, pattrib);
11061
11062 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
11063
11064 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
11065 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
11066
11067 fctrl = &(pwlanhdr->frame_ctl);
11068 *(fctrl) = 0;
11069
11070 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
11071 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
11072 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
11073
11074 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
11075 pmlmeext->mgnt_seq++;
11076 set_frame_sub_type(pframe, WIFI_ACTION);
11077
11078 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
11079 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
11080
11081 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
11082 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
11083
11084 /* TODO calculate 40Mhz intolerant via ch and ch offset */
11085 /* if (pmlmepriv->num_FortyMHzIntolerant > 0) */
11086 {
11087 u8 iedata = 0;
11088
11089 iedata |= BIT(2);/* 20 MHz BSS Width Request */
11090 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
11091 }
11092
11093 /* */
11094 _rtw_memset(ICS, 0, sizeof(ICS));
11095 if (pmlmepriv->num_sta_no_ht > 0) {
11096 int i;
11097
11098 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
11099
11100 phead = get_list_head(queue);
11101 plist = get_next(phead);
11102
11103 while (1) {
11104 int len;
11105 u8 *p;
11106 WLAN_BSSID_EX *pbss_network;
11107
11108 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
11109 break;
11110
11111 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
11112
11113 plist = get_next(plist);
11114
11115 pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
11116
11117 p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
11118 if ((p == NULL) || (len == 0)) { /* non-HT */
11119 if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
11120 continue;
11121
11122 ICS[0][pbss_network->Configuration.DSConfig] = 1;
11123
11124 if (ICS[0][0] == 0)
11125 ICS[0][0] = 1;
11126 }
11127
11128 }
11129
11130 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
11131
11132
11133 for (i = 0; i < 8; i++) {
11134 if (ICS[i][0] == 1) {
11135 int j, k = 0;
11136
11137 InfoContent[k] = i;
11138 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i); */
11139 k++;
11140
11141 for (j = 1; j <= 14; j++) {
11142 if (ICS[i][j] == 1) {
11143 if (k < 16) {
11144 InfoContent[k] = j; /* channel number */
11145 /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */
11146 k++;
11147 }
11148 }
11149 }
11150
11151 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
11152
11153 }
11154
11155 }
11156
11157
11158 }
11159
11160
11161 pattrib->last_txcmdsz = pattrib->pktlen;
11162
11163 dump_mgntframe(padapter, pmgntframe);
11164 #endif /* CONFIG_80211N_HT */
11165 }
11166
11167 /* Spatial Multiplexing Powersave (SMPS) action frame */
_issue_action_SM_PS(_adapter * padapter,unsigned char * raddr,u8 NewMimoPsMode,u8 wait_ack)11168 int _issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode , u8 wait_ack)
11169 {
11170
11171 int ret = _FAIL;
11172 unsigned char category = RTW_WLAN_CATEGORY_HT;
11173 u8 action = RTW_WLAN_ACTION_HT_SM_PS;
11174 u8 sm_power_control = 0;
11175 struct xmit_frame *pmgntframe;
11176 struct pkt_attrib *pattrib;
11177 unsigned char *pframe;
11178 struct rtw_ieee80211_hdr *pwlanhdr;
11179 unsigned short *fctrl;
11180 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
11181 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
11182 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11183
11184
11185 if (NewMimoPsMode == WLAN_HT_CAP_SM_PS_DISABLED) {
11186 sm_power_control = sm_power_control & ~(BIT(0)); /* SM Power Save Enable = 0 SM Power Save Disable */
11187 } else if (NewMimoPsMode == WLAN_HT_CAP_SM_PS_STATIC) {
11188 sm_power_control = sm_power_control | BIT(0); /* SM Power Save Enable = 1 SM Power Save Enable */
11189 sm_power_control = sm_power_control & ~(BIT(1)); /* SM Mode = 0 Static Mode */
11190 } else if (NewMimoPsMode == WLAN_HT_CAP_SM_PS_DYNAMIC) {
11191 sm_power_control = sm_power_control | BIT(0); /* SM Power Save Enable = 1 SM Power Save Enable */
11192 sm_power_control = sm_power_control | BIT(1); /* SM Mode = 1 Dynamic Mode */
11193 } else
11194 return ret;
11195
11196 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
11197 return ret;
11198
11199 RTW_INFO("%s, sm_power_control=%u, NewMimoPsMode=%u\n", __FUNCTION__ , sm_power_control , NewMimoPsMode);
11200
11201 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
11202 if (pmgntframe == NULL)
11203 return ret;
11204
11205 /* update attribute */
11206 pattrib = &pmgntframe->attrib;
11207 update_mgntframe_attrib(padapter, pattrib);
11208
11209 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
11210
11211 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
11212 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
11213
11214 fctrl = &(pwlanhdr->frame_ctl);
11215 *(fctrl) = 0;
11216
11217 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); /* RA */
11218 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
11219 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); /* DA = RA */
11220
11221 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
11222 pmlmeext->mgnt_seq++;
11223 set_frame_sub_type(pframe, WIFI_ACTION);
11224
11225 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
11226 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
11227
11228 /* category, action */
11229 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
11230 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
11231
11232 pframe = rtw_set_fixed_ie(pframe, 1, &(sm_power_control), &(pattrib->pktlen));
11233
11234 pattrib->last_txcmdsz = pattrib->pktlen;
11235
11236 if (wait_ack)
11237 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
11238 else {
11239 dump_mgntframe(padapter, pmgntframe);
11240 ret = _SUCCESS;
11241 }
11242
11243 if (ret != _SUCCESS)
11244 RTW_INFO("%s, ack to\n", __func__);
11245
11246 return ret;
11247 }
11248
11249 /*
11250 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
11251 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
11252 * try_cnt means the maximal TX count to try
11253 */
issue_action_SM_PS_wait_ack(_adapter * padapter,unsigned char * raddr,u8 NewMimoPsMode,int try_cnt,int wait_ms)11254 int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms)
11255 {
11256 int ret = _FAIL;
11257 int i = 0;
11258 systime start = rtw_get_current_time();
11259
11260 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
11261 goto exit;
11262
11263 do {
11264 ret = _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , wait_ms > 0 ? _TRUE : _FALSE);
11265
11266 i++;
11267
11268 if (RTW_CANNOT_RUN(padapter))
11269 break;
11270
11271 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
11272 rtw_msleep_os(wait_ms);
11273
11274 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
11275
11276 if (ret != _FAIL) {
11277 ret = _SUCCESS;
11278 #ifndef DBG_XMIT_ACK
11279 goto exit;
11280 #endif
11281 }
11282
11283 if (try_cnt && wait_ms) {
11284 if (raddr)
11285 RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", %s , %d/%d in %u ms\n",
11286 FUNC_ADPT_ARG(padapter), MAC_ARG(raddr),
11287 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
11288 else
11289 RTW_INFO(FUNC_ADPT_FMT", %s , %d/%d in %u ms\n",
11290 FUNC_ADPT_ARG(padapter),
11291 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
11292 }
11293 exit:
11294
11295 return ret;
11296 }
11297
issue_action_SM_PS(_adapter * padapter,unsigned char * raddr,u8 NewMimoPsMode)11298 int issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode)
11299 {
11300 RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(raddr));
11301 return _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , _FALSE);
11302 }
11303
11304 /**
11305 * _send_delba_sta_tid - Cancel the AMPDU association for the specific @sta, @tid
11306 * @adapter: the adapter to which @sta belongs
11307 * @initiator: if we are the initiator of AMPDU association
11308 * @sta: the sta to be checked
11309 * @tid: the tid to be checked
11310 * @force: cancel and send DELBA even when no AMPDU association is setup
11311 * @wait_ack: send delba with xmit ack (valid when initiator == 0)
11312 *
11313 * Returns:
11314 * _FAIL if sta is NULL
11315 * when initiator is 1, always _SUCCESS
11316 * when initiator is 0, _SUCCESS if DELBA is acked
11317 */
_send_delba_sta_tid(_adapter * adapter,u8 initiator,struct sta_info * sta,u8 tid,u8 force,int wait_ack)11318 static unsigned int _send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
11319 , u8 force, int wait_ack)
11320 {
11321 int ret = _SUCCESS;
11322
11323 if (sta == NULL) {
11324 ret = _FAIL;
11325 goto exit;
11326 }
11327
11328 if (initiator == 0) {
11329 /* recipient */
11330 if (force || sta->recvreorder_ctrl[tid].enable == _TRUE) {
11331 u8 ampdu_size_bak = sta->recvreorder_ctrl[tid].ampdu_size;
11332
11333 sta->recvreorder_ctrl[tid].enable = _FALSE;
11334 sta->recvreorder_ctrl[tid].ampdu_size = RX_AMPDU_SIZE_INVALID;
11335
11336 if (rtw_del_rx_ampdu_test_trigger_no_tx_fail())
11337 ret = _FAIL;
11338 else if (wait_ack)
11339 ret = issue_del_ba_ex(adapter, sta->cmn.mac_addr, tid, 37, initiator, 3, 1);
11340 else
11341 issue_del_ba(adapter, sta->cmn.mac_addr, tid, 37, initiator);
11342
11343 if (ret == _FAIL && sta->recvreorder_ctrl[tid].enable == _FALSE)
11344 sta->recvreorder_ctrl[tid].ampdu_size = ampdu_size_bak;
11345 }
11346 } else if (initiator == 1) {
11347 /* originator */
11348 #ifdef CONFIG_80211N_HT
11349 if (force || sta->htpriv.agg_enable_bitmap & BIT(tid)) {
11350 sta->htpriv.agg_enable_bitmap &= ~BIT(tid);
11351 sta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
11352 issue_del_ba(adapter, sta->cmn.mac_addr, tid, 37, initiator);
11353 }
11354 #endif
11355 }
11356
11357 exit:
11358 return ret;
11359 }
11360
send_delba_sta_tid(_adapter * adapter,u8 initiator,struct sta_info * sta,u8 tid,u8 force)11361 inline unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
11362 , u8 force)
11363 {
11364 return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 0);
11365 }
11366
send_delba_sta_tid_wait_ack(_adapter * adapter,u8 initiator,struct sta_info * sta,u8 tid,u8 force)11367 inline unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
11368 , u8 force)
11369 {
11370 return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 1);
11371 }
11372
send_delba(_adapter * padapter,u8 initiator,u8 * addr)11373 unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
11374 {
11375 struct sta_priv *pstapriv = &padapter->stapriv;
11376 struct sta_info *psta = NULL;
11377 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11378 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11379 u16 tid;
11380
11381 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
11382 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
11383 return _SUCCESS;
11384
11385 psta = rtw_get_stainfo(pstapriv, addr);
11386 if (psta == NULL)
11387 return _SUCCESS;
11388
11389 #if 0
11390 RTW_INFO("%s:%s\n", __func__, (initiator == 0) ? "RX_DIR" : "TX_DIR");
11391 if (initiator == 1) /* originator */
11392 RTW_INFO("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
11393 #endif
11394
11395 for (tid = 0; tid < TID_NUM; tid++)
11396 send_delba_sta_tid(padapter, initiator, psta, tid, 0);
11397
11398 return _SUCCESS;
11399 }
11400
11401 #ifdef CONFIG_AP_MODE
send_beacon(_adapter * padapter)11402 unsigned int send_beacon(_adapter *padapter)
11403 {
11404 #if defined(CONFIG_PCI_HCI) && !defined(CONFIG_PCI_BCN_POLLING)
11405 #ifdef CONFIG_FW_HANDLE_TXBCN
11406 u8 vap_id = padapter->vap_id;
11407
11408 /* bypass TX BCN because vap_id is invalid*/
11409 if (vap_id == CONFIG_LIMITED_AP_NUM)
11410 return _SUCCESS;
11411 #endif
11412
11413 /* bypass TX BCN queue because op ch is switching/waiting */
11414 if (check_fwstate(&padapter->mlmepriv, WIFI_OP_CH_SWITCHING)
11415 || IS_CH_WAITING(adapter_to_rfctl(padapter))
11416 )
11417 return _SUCCESS;
11418
11419 /* RTW_INFO("%s\n", __FUNCTION__); */
11420
11421 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
11422
11423 /* 8192EE Port select for Beacon DL */
11424 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
11425 #ifdef CONFIG_FW_HANDLE_TXBCN
11426 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_HEAD_SEL, &vap_id);
11427 #endif
11428
11429 issue_beacon(padapter, 0);
11430
11431 #ifdef CONFIG_FW_HANDLE_TXBCN
11432 vap_id = 0xFF;
11433 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_HEAD_SEL, &vap_id);
11434 #endif
11435
11436 #ifdef RTL8814AE_SW_BCN
11437 if (GET_HAL_DATA(padapter)->bCorrectBCN != 0)
11438 RTW_INFO("%s, line%d, Warnning, pHalData->bCorrectBCN != 0\n", __func__, __LINE__);
11439 GET_HAL_DATA(padapter)->bCorrectBCN = 1;
11440 #endif
11441
11442 return _SUCCESS;
11443 #endif
11444
11445 /* CONFIG_PCI_BCN_POLLING is for pci interface beacon polling mode */
11446 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)|| defined(CONFIG_PCI_BCN_POLLING)
11447 u8 bxmitok = _FALSE;
11448 int issue = 0;
11449 int poll = 0;
11450 systime start = rtw_get_current_time();
11451 #ifdef CONFIG_FW_HANDLE_TXBCN
11452 u8 vap_id = padapter->vap_id;
11453
11454 /* bypass TX BCN because vap_id is invalid*/
11455 if (vap_id == CONFIG_LIMITED_AP_NUM)
11456 return _SUCCESS;
11457 #endif
11458
11459 /* bypass TX BCN queue because op ch is switching/waiting */
11460 if (check_fwstate(&padapter->mlmepriv, WIFI_OP_CH_SWITCHING)
11461 || IS_CH_WAITING(adapter_to_rfctl(padapter))
11462 )
11463 return _SUCCESS;
11464
11465 #if defined(CONFIG_USB_HCI)
11466 #if defined(CONFIG_RTL8812A)
11467 if (IS_FULL_SPEED_USB(padapter)) {
11468 issue_beacon(padapter, 300);
11469 bxmitok = _TRUE;
11470 } else
11471 #endif
11472 #endif
11473 {
11474 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
11475 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
11476 #ifdef CONFIG_FW_HANDLE_TXBCN
11477 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_HEAD_SEL, &vap_id);
11478 #endif
11479 do {
11480 #if defined(CONFIG_PCI_BCN_POLLING)
11481 issue_beacon(padapter, 0);
11482 #else
11483 issue_beacon(padapter, 100);
11484 #endif
11485 issue++;
11486 do {
11487 #if defined(CONFIG_PCI_BCN_POLLING)
11488 rtw_msleep_os(1);
11489 #else
11490 rtw_yield_os();
11491 #endif
11492 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
11493 poll++;
11494 } while ((poll % 10) != 0 && _FALSE == bxmitok && !RTW_CANNOT_RUN(padapter));
11495 #if defined(CONFIG_PCI_BCN_POLLING)
11496 rtw_hal_unmap_beacon_icf(padapter);
11497 #endif
11498 } while (bxmitok == _FALSE && (issue < 100) && !RTW_CANNOT_RUN(padapter));
11499 #ifdef CONFIG_FW_HANDLE_TXBCN
11500 vap_id = 0xFF;
11501 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_HEAD_SEL, &vap_id);
11502 #endif
11503 }
11504 if (RTW_CANNOT_RUN(padapter))
11505 return _FAIL;
11506
11507
11508 if (_FALSE == bxmitok) {
11509 RTW_INFO("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
11510 #ifdef CONFIG_BCN_RECOVERY
11511 GET_HAL_DATA(padapter)->issue_bcn_fail++;
11512 #endif /*CONFIG_BCN_RECOVERY*/
11513 return _FAIL;
11514 } else {
11515 u32 passing_time = rtw_get_passing_time_ms(start);
11516
11517 if (passing_time > 100 || issue > 3)
11518 RTW_INFO("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
11519 else if (0)
11520 RTW_INFO("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
11521
11522 #ifdef CONFIG_FW_CORRECT_BCN
11523 rtw_hal_fw_correct_bcn(padapter);
11524 #endif
11525 return _SUCCESS;
11526 }
11527
11528 #endif /*defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)*/
11529
11530 }
11531 #endif /* CONFIG_AP_MODE */
11532
11533 /****************************************************************************
11534
11535 Following are some utitity fuctions for WiFi MLME
11536
11537 *****************************************************************************/
11538
IsLegal5GChannel(PADAPTER Adapter,u8 channel)11539 BOOLEAN IsLegal5GChannel(
11540 PADAPTER Adapter,
11541 u8 channel)
11542 {
11543
11544 int i = 0;
11545 u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
11546 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
11547 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
11548 161, 163, 165
11549 };
11550 for (i = 0; i < sizeof(Channel_5G); i++)
11551 if (channel == Channel_5G[i])
11552 return _TRUE;
11553 return _FALSE;
11554 }
11555
11556 /* collect bss info from Beacon and Probe request/response frames. */
collect_bss_info(_adapter * padapter,union recv_frame * precv_frame,WLAN_BSSID_EX * bssid)11557 u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
11558 {
11559 int i;
11560 sint len;
11561 u8 *p;
11562 u8 rf_path;
11563 u16 val16, subtype;
11564 u8 *pframe = precv_frame->u.hdr.rx_data;
11565 u32 packet_len = precv_frame->u.hdr.len;
11566 u8 ie_offset;
11567 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
11568 struct registry_priv *pregistrypriv = &padapter->registrypriv;
11569 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11570 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11571 #ifdef CONFIG_LAYER2_ROAMING
11572 u32 *pbuf;
11573 #endif
11574
11575 len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
11576
11577 if (len > MAX_IE_SZ) {
11578 /* RTW_INFO("IE too long for survey event\n"); */
11579 return _FAIL;
11580 }
11581
11582 _rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
11583
11584 subtype = get_frame_sub_type(pframe);
11585
11586 if (subtype == WIFI_BEACON) {
11587 bssid->Reserved[0] = BSS_TYPE_BCN;
11588 ie_offset = _BEACON_IE_OFFSET_;
11589 } else {
11590 /* FIXME : more type */
11591 if (subtype == WIFI_PROBERSP) {
11592 ie_offset = _PROBERSP_IE_OFFSET_;
11593 bssid->Reserved[0] = BSS_TYPE_PROB_RSP;
11594 } else if (subtype == WIFI_PROBEREQ) {
11595 ie_offset = _PROBEREQ_IE_OFFSET_;
11596 bssid->Reserved[0] = BSS_TYPE_PROB_REQ;
11597 } else {
11598 bssid->Reserved[0] = BSS_TYPE_UNDEF;
11599 ie_offset = _FIXED_IE_LENGTH_;
11600 }
11601 }
11602
11603 bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
11604
11605 /* below is to copy the information element */
11606 bssid->IELength = len;
11607 _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
11608
11609 /* get the signal strength */
11610 /* bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; */ /* 0-100 index. */
11611 bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.recv_signal_power; /* in dBM.raw data */
11612 bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.signal_quality;/* in percentage */
11613 bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.signal_strength;/* in percentage */
11614
11615 /* get rx_snr */
11616 if (precv_frame->u.hdr.attrib.data_rate >= DESC_RATE11M) {
11617 bssid->PhyInfo.is_cck_rate = 0;
11618 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++)
11619 bssid->PhyInfo.rx_snr[rf_path] =
11620 precv_frame->u.hdr.attrib.phy_info.rx_snr[rf_path];
11621 } else
11622 bssid->PhyInfo.is_cck_rate = 1;
11623
11624 #ifdef CONFIG_ANTENNA_DIVERSITY
11625 rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &(bssid->PhyInfo.Optimum_antenna), NULL);
11626 #endif
11627
11628 /* checking SSID */
11629 p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset);
11630 if (p == NULL) {
11631 RTW_INFO("marc: cannot find SSID for survey event\n");
11632 return _FAIL;
11633 }
11634
11635 if (*(p + 1)) {
11636 if (len > NDIS_802_11_LENGTH_SSID) {
11637 RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
11638 return _FAIL;
11639 }
11640 _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
11641 bssid->Ssid.SsidLength = *(p + 1);
11642 } else
11643 bssid->Ssid.SsidLength = 0;
11644
11645 _rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
11646
11647 /* checking rate info... */
11648 i = 0;
11649 p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
11650 if (p != NULL) {
11651 if (len > NDIS_802_11_LENGTH_RATES_EX) {
11652 RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
11653 return _FAIL;
11654 }
11655 #ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT
11656 if (rtw_validate_value(_SUPPORTEDRATES_IE_, p+2, len) == _FALSE) {
11657 rtw_absorb_ssid_ifneed(padapter, bssid, pframe);
11658 RTW_DBG_DUMP("Invalidated Support Rate IE --", p, len+2);
11659 return _FAIL;
11660 }
11661 #endif /* #ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT */
11662 _rtw_memcpy(bssid->SupportedRates, (p + 2), len);
11663 i = len;
11664 }
11665
11666 p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
11667 if (p != NULL) {
11668 if (len > (NDIS_802_11_LENGTH_RATES_EX - i)) {
11669 RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
11670 return _FAIL;
11671 }
11672 #ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT
11673 if (rtw_validate_value(_EXT_SUPPORTEDRATES_IE_, p+2, len) == _FALSE) {
11674 rtw_absorb_ssid_ifneed(padapter, bssid, pframe);
11675 RTW_DBG_DUMP("Invalidated EXT Support Rate IE --", p, len+2);
11676 return _FAIL;
11677 }
11678 #endif /* #ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT */
11679 _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
11680 }
11681
11682 #ifdef CONFIG_P2P
11683 if (subtype == WIFI_PROBEREQ) {
11684 u8 *p2p_ie;
11685 u32 p2p_ielen;
11686 /* Set Listion Channel */
11687 p2p_ie = rtw_get_p2p_ie(bssid->IEs, bssid->IELength, NULL, &p2p_ielen);
11688 if (p2p_ie) {
11689 u32 attr_contentlen = 0;
11690 u8 listen_ch[5] = { 0x00 };
11691
11692 attr_contentlen = sizeof(listen_ch);
11693 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, listen_ch, &attr_contentlen);
11694 bssid->Configuration.DSConfig = listen_ch[4];
11695 } else {
11696 /* use current channel */
11697 bssid->Configuration.DSConfig = padapter->mlmeextpriv.cur_channel;
11698 RTW_INFO("%s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d)\n", __FUNCTION__, __LINE__, bssid->Configuration.DSConfig);
11699 }
11700
11701 /* FIXME */
11702 bssid->InfrastructureMode = Ndis802_11Infrastructure;
11703 _rtw_memcpy(bssid->MacAddress, get_addr2_ptr(pframe), ETH_ALEN);
11704 bssid->Privacy = 1;
11705 return _SUCCESS;
11706 }
11707 #endif /* CONFIG_P2P */
11708
11709 if (bssid->IELength < 12)
11710 return _FAIL;
11711
11712 /* Checking for DSConfig */
11713 p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
11714
11715 bssid->Configuration.DSConfig = 0;
11716 bssid->Configuration.Length = 0;
11717
11718 if (p)
11719 bssid->Configuration.DSConfig = *(p + 2);
11720 else {
11721 /* In 5G, some ap do not have DSSET IE */
11722 /* checking HT info for channel */
11723 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
11724 if (p) {
11725 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
11726 bssid->Configuration.DSConfig = HT_info->primary_channel;
11727 } else {
11728 /* use current channel */
11729 bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
11730 }
11731 }
11732
11733 _rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
11734 bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
11735
11736 val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
11737
11738 if ((val16 & 0x03) == cap_ESS) {
11739 bssid->InfrastructureMode = Ndis802_11Infrastructure;
11740 _rtw_memcpy(bssid->MacAddress, get_addr2_ptr(pframe), ETH_ALEN);
11741 } else if ((val16 & 0x03) == cap_IBSS){
11742 bssid->InfrastructureMode = Ndis802_11IBSS;
11743 _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
11744 } else if ((val16 & 0x03) == 0x00){
11745 u8 *mesh_id_ie, *mesh_conf_ie;
11746 sint mesh_id_ie_len, mesh_conf_ie_len;
11747
11748 mesh_id_ie = rtw_get_ie(bssid->IEs + ie_offset, WLAN_EID_MESH_ID, &mesh_id_ie_len, bssid->IELength - ie_offset);
11749 mesh_conf_ie = rtw_get_ie(bssid->IEs + ie_offset, WLAN_EID_MESH_CONFIG, &mesh_conf_ie_len, bssid->IELength - ie_offset);
11750 if (mesh_id_ie || mesh_conf_ie) {
11751 if (!mesh_id_ie) {
11752 RTW_INFO("cannot find Mesh ID for survey event\n");
11753 return _FAIL;
11754 }
11755 if (mesh_id_ie_len) {
11756 if (mesh_id_ie_len > NDIS_802_11_LENGTH_SSID) {
11757 RTW_INFO("Mesh ID too long (%d) for survey event\n", mesh_id_ie_len);
11758 return _FAIL;
11759 }
11760 _rtw_memcpy(bssid->mesh_id.Ssid, (mesh_id_ie + 2), mesh_id_ie_len);
11761 bssid->mesh_id.SsidLength = mesh_id_ie_len;
11762 } else
11763 bssid->mesh_id.SsidLength = 0;
11764
11765 if (!mesh_conf_ie) {
11766 RTW_INFO("cannot find Mesh config for survey event\n");
11767 return _FAIL;
11768 }
11769 if (mesh_conf_ie_len != 7) {
11770 RTW_INFO("invalid Mesh conf IE len (%d) for survey event\n", mesh_conf_ie_len);
11771 return _FAIL;
11772 }
11773
11774 bssid->InfrastructureMode = Ndis802_11_mesh;
11775 _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
11776 } else {
11777 /* default cases */
11778 bssid->InfrastructureMode = Ndis802_11IBSS;
11779 _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
11780 }
11781 }
11782
11783 if (val16 & BIT(4))
11784 bssid->Privacy = 1;
11785 else
11786 bssid->Privacy = 0;
11787
11788 bssid->Configuration.ATIMWindow = 0;
11789
11790 /* 20/40 BSS Coexistence check */
11791 if ((pregistrypriv->wifi_spec == 1) && (_FALSE == pmlmeinfo->bwmode_updated)) {
11792 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11793 #ifdef CONFIG_80211N_HT
11794 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
11795 if (p && len > 0) {
11796 struct HT_caps_element *pHT_caps;
11797 pHT_caps = (struct HT_caps_element *)(p + 2);
11798
11799 if (pHT_caps->u.HT_cap_element.HT_caps_info & BIT(14))
11800 pmlmepriv->num_FortyMHzIntolerant++;
11801 } else
11802 pmlmepriv->num_sta_no_ht++;
11803 #endif /* CONFIG_80211N_HT */
11804
11805 }
11806
11807 #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
11808 if (strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
11809 RTW_INFO("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
11810 , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
11811 , rtw_get_oper_ch(padapter)
11812 , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
11813 );
11814 }
11815 #endif
11816
11817 /* mark bss info receving from nearby channel as SignalQuality 101 */
11818 if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
11819 bssid->PhyInfo.SignalQuality = 101;
11820
11821 #ifdef CONFIG_RTW_80211K
11822 p = rtw_get_ie(bssid->IEs + ie_offset, _EID_RRM_EN_CAP_IE_, &len, bssid->IELength - ie_offset);
11823 if (p)
11824 _rtw_memcpy(bssid->PhyInfo.rm_en_cap, (p + 2), MIN(*(p + 1),
11825 sizeof(bssid->PhyInfo.rm_en_cap)));
11826
11827 /* save freerun counter */
11828 bssid->PhyInfo.free_cnt = precv_frame->u.hdr.attrib.free_cnt;
11829 #endif
11830 #ifdef CONFIG_LAYER2_ROAMING
11831 pbuf = (u32 *)((u8 *)pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
11832 bssid->tsf = le32_to_cpu(*(pbuf + 1));
11833 bssid->tsf = bssid->tsf << 32;
11834 bssid->tsf |= le32_to_cpu(*pbuf);
11835 #endif
11836 return _SUCCESS;
11837 }
11838
11839 #ifdef CONFIG_AP_MODE
start_create_ibss(_adapter * padapter)11840 void start_create_ibss(_adapter *padapter)
11841 {
11842 unsigned short caps;
11843 u8 val8;
11844 u8 join_type;
11845 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11846 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11847 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
11848 u8 doiqk = _FALSE;
11849 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
11850 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
11851
11852 /* update wireless mode */
11853 update_wireless_mode(padapter);
11854
11855 /* udpate capability */
11856 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
11857 update_capinfo(padapter, caps);
11858 if (caps & cap_IBSS) { /* adhoc master */
11859 /* set_opmode_cmd(padapter, adhoc); */ /* removed */
11860
11861 val8 = 0xcf;
11862 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
11863
11864 doiqk = _TRUE;
11865 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
11866
11867 /* switch channel */
11868 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
11869
11870 doiqk = _FALSE;
11871 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
11872
11873 beacon_timing_control(padapter);
11874
11875 /* set msr to WIFI_FW_ADHOC_STATE */
11876 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
11877 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
11878
11879 /* issue beacon */
11880 if (send_beacon(padapter) == _FAIL) {
11881
11882 report_join_res(padapter, -1, WLAN_STATUS_UNSPECIFIED_FAILURE);
11883 pmlmeinfo->state = WIFI_FW_NULL_STATE;
11884 } else {
11885 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
11886 rtw_hal_rcr_set_chk_bssid(padapter, MLME_ADHOC_STARTED);
11887 join_type = 0;
11888 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
11889
11890 rtw_btcoex_connect_notify(padapter, join_type);
11891
11892 report_join_res(padapter, 1, WLAN_STATUS_SUCCESS);
11893 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
11894 rtw_indicate_connect(padapter);
11895 }
11896 } else {
11897 RTW_INFO("start_create_ibss, invalid cap:%x\n", caps);
11898 return;
11899 }
11900 /* update bc/mc sta_info */
11901 update_bmc_sta(padapter);
11902
11903 }
11904 #endif /* CONFIG_AP_MODE */
11905
start_clnt_join(_adapter * padapter)11906 void start_clnt_join(_adapter *padapter)
11907 {
11908 unsigned short caps;
11909 u8 val8;
11910 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11911 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11912 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
11913 int beacon_timeout;
11914 u8 ASIX_ID[] = {0x00, 0x0E, 0xC6};
11915
11916 /* update wireless mode */
11917 update_wireless_mode(padapter);
11918
11919 /* udpate capability */
11920 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
11921 update_capinfo(padapter, caps);
11922
11923 /* check if sta is ASIX peer and fix IOT issue if it is. */
11924 if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) , ASIX_ID , 3)) {
11925 u8 iot_flag = _TRUE;
11926 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
11927 }
11928
11929 if (caps & cap_ESS) {
11930 Set_MSR(padapter, WIFI_FW_STATION_STATE);
11931
11932 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
11933
11934 #ifdef CONFIG_WAPI_SUPPORT
11935 if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI) {
11936 /* Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey. */
11937 val8 = 0x4c;
11938 }
11939 #endif
11940 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
11941
11942 #ifdef CONFIG_DEAUTH_BEFORE_CONNECT
11943 /* Because of AP's not receiving deauth before */
11944 /* AP may: 1)not response auth or 2)deauth us after link is complete */
11945 /* issue deauth before issuing auth to deal with the situation */
11946
11947 /* Commented by Albert 2012/07/21 */
11948 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
11949 {
11950 #ifdef CONFIG_P2P
11951 _queue *queue = &(padapter->mlmepriv.scanned_queue);
11952 _list *head = get_list_head(queue);
11953 _list *pos = get_next(head);
11954 struct wlan_network *scanned = NULL;
11955 u8 ie_offset = 0;
11956 _irqL irqL;
11957 bool has_p2p_ie = _FALSE;
11958
11959 _enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
11960
11961 for (pos = get_next(head); !rtw_end_of_queue_search(head, pos); pos = get_next(pos)) {
11962
11963 scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
11964
11965 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
11966 && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
11967 ) {
11968 ie_offset = (scanned->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12);
11969 if (rtw_get_p2p_ie(scanned->network.IEs + ie_offset, scanned->network.IELength - ie_offset, NULL, NULL))
11970 has_p2p_ie = _TRUE;
11971 break;
11972 }
11973 }
11974
11975 _exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
11976
11977 if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE)
11978 #endif /* CONFIG_P2P */
11979 /* To avoid connecting to AP fail during resume process, change retry count from 5 to 1 */
11980 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
11981 }
11982 #endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
11983
11984 /* here wait for receiving the beacon to start auth */
11985 /* and enable a timer */
11986 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
11987 set_link_timer(pmlmeext, beacon_timeout);
11988 _set_timer(&padapter->mlmepriv.assoc_timer,
11989 (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO * REASSOC_LIMIT) + beacon_timeout);
11990
11991 #ifdef CONFIG_RTW_80211R
11992 if (rtw_ft_roam(padapter)) {
11993 rtw_ft_start_clnt_join(padapter);
11994 } else
11995 #endif
11996 {
11997 rtw_sta_linking_test_set_start();
11998 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
11999 }
12000 } else if (caps & cap_IBSS) { /* adhoc client */
12001 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
12002
12003 val8 = 0xcf;
12004 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
12005
12006 beacon_timing_control(padapter);
12007
12008 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
12009
12010 report_join_res(padapter, 1, WLAN_STATUS_SUCCESS);
12011 } else {
12012 /* RTW_INFO("marc: invalid cap:%x\n", caps); */
12013 return;
12014 }
12015
12016 }
12017
start_clnt_auth(_adapter * padapter)12018 void start_clnt_auth(_adapter *padapter)
12019 {
12020 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12021 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12022
12023 _cancel_timer_ex(&pmlmeext->link_timer);
12024
12025 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
12026 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
12027
12028 pmlmeinfo->auth_seq = 1;
12029 pmlmeinfo->reauth_count = 0;
12030 pmlmeinfo->reassoc_count = 0;
12031 pmlmeinfo->link_count = 0;
12032 pmlmeext->retry = 0;
12033
12034 #ifdef CONFIG_RTW_80211R
12035 if (rtw_ft_roam(padapter)) {
12036 rtw_ft_set_status(padapter, RTW_FT_AUTHENTICATING_STA);
12037 RTW_PRINT("start ft auth\n");
12038 } else
12039 #endif
12040 RTW_PRINT("start auth\n");
12041
12042 #ifdef CONFIG_IOCTL_CFG80211
12043 if (rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE)) {
12044 if (rtw_cached_pmkid(padapter, get_my_bssid(&pmlmeinfo->network)) != -1) {
12045 RTW_INFO("SAE: PMKSA cache entry found\n");
12046 padapter->securitypriv.auth_alg = WLAN_AUTH_OPEN;
12047 goto no_external_auth;
12048 }
12049
12050 RTW_PRINT("SAE: start external auth\n");
12051 rtw_cfg80211_external_auth_request(padapter, NULL);
12052 return;
12053 }
12054 no_external_auth:
12055 #endif /* CONFIG_IOCTL_CFG80211 */
12056
12057 issue_auth(padapter, NULL, 0);
12058
12059 set_link_timer(pmlmeext, REAUTH_TO);
12060
12061 }
12062
12063
start_clnt_assoc(_adapter * padapter)12064 void start_clnt_assoc(_adapter *padapter)
12065 {
12066 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12067 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12068
12069 _cancel_timer_ex(&pmlmeext->link_timer);
12070
12071 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
12072 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
12073
12074 #ifdef CONFIG_RTW_80211R
12075 if (rtw_ft_roam(padapter)
12076 #ifdef CONFIG_RTW_WNM
12077 || rtw_wnm_btm_reassoc_req(padapter)
12078 #endif
12079 )
12080 issue_reassocreq(padapter);
12081 else
12082 #endif
12083 issue_assocreq(padapter);
12084
12085 set_link_timer(pmlmeext, REASSOC_TO);
12086 }
12087
receive_disconnect(_adapter * padapter,unsigned char * MacAddr,unsigned short reason,u8 locally_generated)12088 unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, u8 locally_generated)
12089 {
12090 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12091 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12092
12093 if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
12094 return _SUCCESS;
12095
12096 RTW_INFO("%s\n", __FUNCTION__);
12097
12098 #ifdef CONFIG_RTW_REPEATER_SON
12099 rtw_rson_do_disconnect(padapter);
12100 #endif
12101 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
12102 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
12103 if (report_del_sta_event(padapter, MacAddr, reason, _TRUE, locally_generated) != _FAIL)
12104 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12105 } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) {
12106 if (report_join_res(padapter, -2, reason) != _FAIL)
12107 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12108 } else
12109 RTW_INFO(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(padapter));
12110 #ifdef CONFIG_RTW_80211R
12111 rtw_ft_roam_status_reset(padapter);
12112 #endif
12113 #ifdef CONFIG_RTW_WNM
12114 rtw_wnm_reset_btm_state(padapter);
12115 #endif
12116 }
12117
12118 return _SUCCESS;
12119 }
12120
rtw_hidden_ssid_bss_count(_adapter * adapter,WLAN_BSSID_EX * bss)12121 static void rtw_hidden_ssid_bss_count(_adapter *adapter, WLAN_BSSID_EX *bss)
12122 {
12123 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
12124 RT_CHANNEL_INFO *chset = rfctl->channel_set;
12125 int chset_idx;
12126
12127 if (bss->InfrastructureMode != Ndis802_11Infrastructure)
12128 return;
12129
12130 if (!hidden_ssid_ap(bss))
12131 return;
12132
12133 chset_idx = rtw_chset_search_ch(chset, bss->Configuration.DSConfig);
12134 if (chset_idx < 0)
12135 return;
12136
12137 chset[chset_idx].hidden_bss_cnt++;
12138 }
12139
12140 /****************************************************************************
12141
12142 Following are the functions to report events
12143
12144 *****************************************************************************/
12145
report_survey_event(_adapter * padapter,union recv_frame * precv_frame)12146 void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
12147 {
12148 struct cmd_obj *pcmd_obj;
12149 u8 *pevtcmd;
12150 u32 cmdsz;
12151 struct survey_event *psurvey_evt;
12152 struct rtw_evt_header *evt_hdr;
12153 struct mlme_ext_priv *pmlmeext;
12154 struct cmd_priv *pcmdpriv;
12155 /* u8 *pframe = precv_frame->u.hdr.rx_data; */
12156 /* uint len = precv_frame->u.hdr.len; */
12157
12158 if (!padapter)
12159 return;
12160
12161 pmlmeext = &padapter->mlmeextpriv;
12162 pcmdpriv = &padapter->cmdpriv;
12163
12164 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12165 if (pcmd_obj == NULL)
12166 return;
12167
12168 cmdsz = (sizeof(struct survey_event) + sizeof(struct rtw_evt_header));
12169 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12170 if (pevtcmd == NULL) {
12171 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12172 return;
12173 }
12174
12175 _rtw_init_listhead(&pcmd_obj->list);
12176
12177 pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
12178 pcmd_obj->cmdsz = cmdsz;
12179 pcmd_obj->parmbuf = pevtcmd;
12180
12181 pcmd_obj->rsp = NULL;
12182 pcmd_obj->rspsz = 0;
12183
12184 evt_hdr = (struct rtw_evt_header *)(pevtcmd);
12185 evt_hdr->len = sizeof(struct survey_event);
12186 evt_hdr->id = EVT_SURVEY;
12187 evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12188
12189 psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct rtw_evt_header));
12190
12191 if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL) {
12192 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12193 rtw_mfree((u8 *)pevtcmd, cmdsz);
12194 return;
12195 }
12196
12197 rtw_hidden_ssid_bss_count(padapter, &psurvey_evt->bss);
12198
12199 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12200
12201 pmlmeext->sitesurvey_res.bss_cnt++;
12202
12203 return;
12204
12205 }
12206
12207 /*
12208 * @acs: aim to trigger channel selection
12209 */
report_surveydone_event(_adapter * padapter,bool acs)12210 void report_surveydone_event(_adapter *padapter, bool acs)
12211 {
12212 struct cmd_obj *pcmd_obj;
12213 u8 *pevtcmd;
12214 u32 cmdsz;
12215 struct surveydone_event *psurveydone_evt;
12216 struct rtw_evt_header *evt_hdr;
12217 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12218 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12219
12220 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12221 if (pcmd_obj == NULL)
12222 return;
12223
12224 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct rtw_evt_header));
12225 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12226 if (pevtcmd == NULL) {
12227 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12228 return;
12229 }
12230
12231 _rtw_init_listhead(&pcmd_obj->list);
12232
12233 pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
12234 pcmd_obj->cmdsz = cmdsz;
12235 pcmd_obj->parmbuf = pevtcmd;
12236
12237 pcmd_obj->rsp = NULL;
12238 pcmd_obj->rspsz = 0;
12239
12240 evt_hdr = (struct rtw_evt_header *)(pevtcmd);
12241 evt_hdr->len = sizeof(struct surveydone_event);
12242 evt_hdr->id = EVT_SURVEY_DONE;
12243 evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12244
12245 psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct rtw_evt_header));
12246 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
12247 psurveydone_evt->activate_ch_cnt = pmlmeext->sitesurvey_res.activate_ch_cnt;
12248 psurveydone_evt->acs = acs;
12249
12250 RTW_INFO("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
12251
12252 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12253
12254 return;
12255
12256 }
12257
report_join_res(_adapter * padapter,int aid_res,u16 status)12258 u32 report_join_res(_adapter *padapter, int aid_res, u16 status)
12259 {
12260 struct cmd_obj *pcmd_obj;
12261 u8 *pevtcmd;
12262 u32 cmdsz;
12263 struct joinbss_event *pjoinbss_evt;
12264 struct rtw_evt_header *evt_hdr;
12265 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12266 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12267 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12268 u32 ret = _FAIL;
12269
12270 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12271 if (pcmd_obj == NULL)
12272 goto exit;
12273
12274 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct rtw_evt_header));
12275 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12276 if (pevtcmd == NULL) {
12277 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12278 goto exit;
12279 }
12280
12281 _rtw_init_listhead(&pcmd_obj->list);
12282
12283 pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
12284 pcmd_obj->cmdsz = cmdsz;
12285 pcmd_obj->parmbuf = pevtcmd;
12286
12287 pcmd_obj->rsp = NULL;
12288 pcmd_obj->rspsz = 0;
12289
12290 evt_hdr = (struct rtw_evt_header *)(pevtcmd);
12291 evt_hdr->len = sizeof(struct joinbss_event);
12292 evt_hdr->id = EVT_JOINBSS;
12293 evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12294
12295 pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct rtw_evt_header));
12296 _rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
12297 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = aid_res;
12298
12299 RTW_INFO("report_join_res(%d, %u)\n", aid_res, status);
12300
12301
12302 rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network, status);
12303
12304
12305 ret = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12306
12307 exit:
12308 return ret;
12309 }
12310
report_wmm_edca_update(_adapter * padapter)12311 void report_wmm_edca_update(_adapter *padapter)
12312 {
12313 struct cmd_obj *pcmd_obj;
12314 u8 *pevtcmd;
12315 u32 cmdsz;
12316 struct wmm_event *pwmm_event;
12317 struct rtw_evt_header *evt_hdr;
12318 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12319 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12320
12321 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12322 if (pcmd_obj == NULL)
12323 return;
12324
12325 cmdsz = (sizeof(struct wmm_event) + sizeof(struct rtw_evt_header));
12326 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12327 if (pevtcmd == NULL) {
12328 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12329 return;
12330 }
12331
12332 _rtw_init_listhead(&pcmd_obj->list);
12333
12334 pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
12335 pcmd_obj->cmdsz = cmdsz;
12336 pcmd_obj->parmbuf = pevtcmd;
12337
12338 pcmd_obj->rsp = NULL;
12339 pcmd_obj->rspsz = 0;
12340
12341 evt_hdr = (struct rtw_evt_header *)(pevtcmd);
12342 evt_hdr->len = sizeof(struct wmm_event);
12343 evt_hdr->id = EVT_WMM_UPDATE;
12344 evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12345
12346 pwmm_event = (struct wmm_event *)(pevtcmd + sizeof(struct rtw_evt_header));
12347 pwmm_event->wmm = 0;
12348
12349 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12350
12351 return;
12352
12353 }
12354
report_del_sta_event(_adapter * padapter,unsigned char * MacAddr,unsigned short reason,bool enqueue,u8 locally_generated)12355 u32 report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, bool enqueue, u8 locally_generated)
12356 {
12357 struct cmd_obj *pcmd_obj;
12358 u8 *pevtcmd;
12359 u32 cmdsz;
12360 struct sta_info *psta;
12361 int mac_id = -1;
12362 struct stadel_event *pdel_sta_evt;
12363 struct rtw_evt_header *evt_hdr;
12364 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12365 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12366 u8 res = _SUCCESS;
12367
12368 /* prepare cmd parameter */
12369 cmdsz = (sizeof(struct stadel_event) + sizeof(struct rtw_evt_header));
12370 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12371 if (pevtcmd == NULL) {
12372 res = _FAIL;
12373 goto exit;
12374 }
12375
12376 evt_hdr = (struct rtw_evt_header *)(pevtcmd);
12377 evt_hdr->len = sizeof(struct stadel_event);
12378 evt_hdr->id = EVT_DEL_STA;
12379 evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12380
12381 pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct rtw_evt_header));
12382 _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
12383 _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
12384 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
12385 if (psta)
12386 mac_id = (int)psta->cmn.mac_id;
12387 else
12388 mac_id = (-1);
12389 pdel_sta_evt->mac_id = mac_id;
12390 pdel_sta_evt->locally_generated = locally_generated;
12391
12392 if (!enqueue) {
12393 /* do directly */
12394 rtw_stadel_event_callback(padapter, (u8 *)pdel_sta_evt);
12395 rtw_mfree(pevtcmd, cmdsz);
12396 } else {
12397 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12398 if (pcmd_obj == NULL) {
12399 rtw_mfree(pevtcmd, cmdsz);
12400 res = _FAIL;
12401 goto exit;
12402 }
12403
12404 _rtw_init_listhead(&pcmd_obj->list);
12405 pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
12406 pcmd_obj->cmdsz = cmdsz;
12407 pcmd_obj->parmbuf = pevtcmd;
12408
12409 pcmd_obj->rsp = NULL;
12410 pcmd_obj->rspsz = 0;
12411
12412 res = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12413 }
12414
12415 exit:
12416
12417 RTW_INFO(FUNC_ADPT_FMT" "MAC_FMT" mac_id=%d, enqueue:%d, res:%u\n"
12418 , FUNC_ADPT_ARG(padapter), MAC_ARG(MacAddr), mac_id, enqueue, res);
12419
12420 return res;
12421 }
12422
report_add_sta_event(_adapter * padapter,unsigned char * MacAddr)12423 void report_add_sta_event(_adapter *padapter, unsigned char *MacAddr)
12424 {
12425 struct cmd_obj *pcmd_obj;
12426 u8 *pevtcmd;
12427 u32 cmdsz;
12428 struct stassoc_event *padd_sta_evt;
12429 struct rtw_evt_header *evt_hdr;
12430 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12431 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12432
12433 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12434 if (pcmd_obj == NULL)
12435 return;
12436
12437 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct rtw_evt_header));
12438 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12439 if (pevtcmd == NULL) {
12440 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12441 return;
12442 }
12443
12444 _rtw_init_listhead(&pcmd_obj->list);
12445
12446 pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
12447 pcmd_obj->cmdsz = cmdsz;
12448 pcmd_obj->parmbuf = pevtcmd;
12449
12450 pcmd_obj->rsp = NULL;
12451 pcmd_obj->rspsz = 0;
12452
12453 evt_hdr = (struct rtw_evt_header *)(pevtcmd);
12454 evt_hdr->len = sizeof(struct stassoc_event);
12455 evt_hdr->id = EVT_ADD_STA;
12456 evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12457
12458 padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct rtw_evt_header));
12459 _rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
12460
12461 RTW_INFO("report_add_sta_event: add STA\n");
12462
12463 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12464
12465 return;
12466 }
12467
12468
rtw_port_switch_chk(_adapter * adapter)12469 bool rtw_port_switch_chk(_adapter *adapter)
12470 {
12471 bool switch_needed = _FALSE;
12472 #ifdef CONFIG_CONCURRENT_MODE
12473 #ifdef CONFIG_RUNTIME_PORT_SWITCH
12474 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12475 struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
12476 _adapter *if_port0 = NULL;
12477 _adapter *if_port1 = NULL;
12478 struct mlme_ext_info *if_port0_mlmeinfo = NULL;
12479 struct mlme_ext_info *if_port1_mlmeinfo = NULL;
12480 int i;
12481
12482 for (i = 0; i < dvobj->iface_nums; i++) {
12483 if (get_hw_port(dvobj->padapters[i]) == HW_PORT0) {
12484 if_port0 = dvobj->padapters[i];
12485 if_port0_mlmeinfo = &(if_port0->mlmeextpriv.mlmext_info);
12486 } else if (get_hw_port(dvobj->padapters[i]) == HW_PORT1) {
12487 if_port1 = dvobj->padapters[i];
12488 if_port1_mlmeinfo = &(if_port1->mlmeextpriv.mlmext_info);
12489 }
12490 }
12491
12492 if (if_port0 == NULL) {
12493 rtw_warn_on(1);
12494 goto exit;
12495 }
12496
12497 if (if_port1 == NULL) {
12498 rtw_warn_on(1);
12499 goto exit;
12500 }
12501
12502 #ifdef DBG_RUNTIME_PORT_SWITCH
12503 RTW_INFO(FUNC_ADPT_FMT" wowlan_mode:%u\n"
12504 ADPT_FMT", port0, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n"
12505 ADPT_FMT", port1, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n",
12506 FUNC_ADPT_ARG(adapter), pwrctl->wowlan_mode,
12507 ADPT_ARG(if_port0), if_port0_mlmeinfo->state, rtw_p2p_state(&if_port0->wdinfo), rtw_p2p_chk_state(&if_port0->wdinfo, P2P_STATE_NONE),
12508 ADPT_ARG(if_port1), if_port1_mlmeinfo->state, rtw_p2p_state(&if_port1->wdinfo), rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE));
12509 #endif /* DBG_RUNTIME_PORT_SWITCH */
12510
12511 #ifdef CONFIG_WOWLAN
12512 /* WOWLAN interface(primary, for now) should be port0 */
12513 if (pwrctl->wowlan_mode == _TRUE) {
12514 if (!is_primary_adapter(if_port0)) {
12515 RTW_INFO("%s "ADPT_FMT" enable WOWLAN\n", __func__, ADPT_ARG(if_port1));
12516 switch_needed = _TRUE;
12517 }
12518 goto exit;
12519 }
12520 #endif /* CONFIG_WOWLAN */
12521
12522 /* AP/Mesh should use port0 for ctl frame's ack */
12523 if ((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
12524 RTW_INFO("%s "ADPT_FMT" is AP/GO/Mesh\n", __func__, ADPT_ARG(if_port1));
12525 switch_needed = _TRUE;
12526 goto exit;
12527 }
12528
12529 /* GC should use port0 for p2p ps */
12530 if (((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
12531 && (if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
12532 #ifdef CONFIG_P2P
12533 && !rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE)
12534 #endif
12535 && !check_fwstate(&if_port1->mlmepriv, WIFI_UNDER_WPS)
12536 ) {
12537 RTW_INFO("%s "ADPT_FMT" is GC\n", __func__, ADPT_ARG(if_port1));
12538 switch_needed = _TRUE;
12539 goto exit;
12540 }
12541
12542 /* port1 linked, but port0 not linked */
12543 if ((if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
12544 && !(if_port0_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
12545 && ((if_port0_mlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
12546 ) {
12547 RTW_INFO("%s "ADPT_FMT" is SINGLE_LINK\n", __func__, ADPT_ARG(if_port1));
12548 switch_needed = _TRUE;
12549 goto exit;
12550 }
12551
12552 exit:
12553 #ifdef DBG_RUNTIME_PORT_SWITCH
12554 RTW_INFO(FUNC_ADPT_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), switch_needed);
12555 #endif /* DBG_RUNTIME_PORT_SWITCH */
12556 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
12557 #endif /* CONFIG_CONCURRENT_MODE */
12558 return switch_needed;
12559 }
12560
12561 /****************************************************************************
12562
12563 Following are the event callback functions
12564
12565 *****************************************************************************/
12566
12567 /* for sta/adhoc mode */
update_sta_info(_adapter * padapter,struct sta_info * psta)12568 void update_sta_info(_adapter *padapter, struct sta_info *psta)
12569 {
12570 _irqL irqL;
12571 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
12572 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12573 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12574
12575 /* ERP */
12576 VCS_update(padapter, psta);
12577
12578 #ifdef CONFIG_80211N_HT
12579 /* HT */
12580 if (pmlmepriv->htpriv.ht_option) {
12581 psta->htpriv.ht_option = _TRUE;
12582
12583 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
12584
12585 psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
12586
12587 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
12588 psta->htpriv.sgi_20m = _TRUE;
12589
12590 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
12591 psta->htpriv.sgi_40m = _TRUE;
12592
12593 psta->qos_option = _TRUE;
12594
12595 psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
12596 psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
12597 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
12598
12599 _rtw_memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap));
12600 #ifdef CONFIG_BEAMFORMING
12601 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
12602 psta->cmn.bf_info.ht_beamform_cap = pmlmepriv->htpriv.beamform_cap;
12603 #endif
12604 } else
12605 #endif /* CONFIG_80211N_HT */
12606 {
12607 #ifdef CONFIG_80211N_HT
12608 psta->htpriv.ht_option = _FALSE;
12609 psta->htpriv.ampdu_enable = _FALSE;
12610 psta->htpriv.tx_amsdu_enable = _FALSE;
12611 psta->htpriv.sgi_20m = _FALSE;
12612 psta->htpriv.sgi_40m = _FALSE;
12613 #endif /* CONFIG_80211N_HT */
12614 psta->qos_option = _FALSE;
12615
12616 }
12617
12618 #ifdef CONFIG_80211N_HT
12619 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
12620
12621 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
12622 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
12623 #endif /* CONFIG_80211N_HT */
12624
12625 psta->cmn.bw_mode = pmlmeext->cur_bwmode;
12626
12627 /* QoS */
12628 if (pmlmepriv->qospriv.qos_option)
12629 psta->qos_option = _TRUE;
12630
12631 #ifdef CONFIG_80211AC_VHT
12632 _rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
12633 if (psta->vhtpriv.vht_option) {
12634 psta->cmn.ra_info.is_vht_enable = _TRUE;
12635 #ifdef CONFIG_BEAMFORMING
12636 psta->vhtpriv.beamform_cap = pmlmepriv->vhtpriv.beamform_cap;
12637 psta->cmn.bf_info.vht_beamform_cap = pmlmepriv->vhtpriv.beamform_cap;
12638 #endif /*CONFIG_BEAMFORMING*/
12639 }
12640 #endif /* CONFIG_80211AC_VHT */
12641 psta->cmn.ra_info.is_support_sgi = query_ra_short_GI(psta, rtw_get_tx_bw_mode(padapter, psta));
12642 update_ldpc_stbc_cap(psta);
12643
12644 _enter_critical_bh(&psta->lock, &irqL);
12645 psta->state = WIFI_ASOC_STATE;
12646 _exit_critical_bh(&psta->lock, &irqL);
12647
12648 }
12649
12650 #ifdef CONFIG_80211D
rtw_joinbss_update_regulatory(_adapter * adapter,const WLAN_BSSID_EX * network)12651 static void rtw_joinbss_update_regulatory(_adapter *adapter, const WLAN_BSSID_EX *network)
12652 {
12653 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
12654
12655 if (rfctl->regd_src == REGD_SRC_RTK_PRIV
12656 && !rtw_rfctl_is_disable_sw_channel_plan(rfctl_to_dvobj(rfctl))
12657 ) {
12658 struct mlme_priv *mlme = &adapter->mlmepriv;
12659 const u8 *country_ie = NULL;
12660 sint country_ie_len = 0;
12661
12662 if (network) {
12663 if (rtw_iface_accept_country_ie(adapter)) {
12664 country_ie = rtw_get_ie(BSS_EX_TLV_IES(network)
12665 , WLAN_EID_COUNTRY, &country_ie_len, BSS_EX_TLV_IES_LEN(network));
12666 if (country_ie) {
12667 if (country_ie_len < 6) {
12668 country_ie = NULL;
12669 country_ie_len = 0;
12670 } else
12671 country_ie_len += 2;
12672 }
12673 }
12674 }
12675
12676 if (country_ie) {
12677 rtw_buf_update(&mlme->recv_country_ie, &mlme->recv_country_ie_len, country_ie, country_ie_len);
12678 if (rtw_apply_recv_country_ie_cmd(adapter, RTW_CMDF_DIRECTLY
12679 , network->Configuration.DSConfig > 14 ? BAND_ON_5G : BAND_ON_2_4G
12680 , network->Configuration.DSConfig, country_ie) != _SUCCESS
12681 )
12682 RTW_WARN(FUNC_ADPT_FMT" rtw_apply_recv_country_ie_cmd() fail\n", FUNC_ADPT_ARG(adapter));
12683 } else
12684 rtw_buf_free(&mlme->recv_country_ie, &mlme->recv_country_ie_len);
12685 }
12686 }
12687
rtw_leavebss_update_regulatory(_adapter * adapter)12688 static void rtw_leavebss_update_regulatory(_adapter *adapter)
12689 {
12690 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12691 struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj);
12692
12693 if (rfctl->regd_src == REGD_SRC_RTK_PRIV
12694 && !rtw_rfctl_is_disable_sw_channel_plan(dvobj)
12695 ) {
12696 if (rtw_apply_recv_country_ie_cmd(adapter, RTW_CMDF_DIRECTLY, 0, 0, NULL) != _SUCCESS)
12697 RTW_WARN(FUNC_ADPT_FMT" rtw_apply_recv_country_ie_cmd() fail\n", FUNC_ADPT_ARG(adapter));
12698 }
12699 }
12700 #endif /* CONFIG_80211D */
12701
rtw_mlmeext_disconnect(_adapter * padapter)12702 static void rtw_mlmeext_disconnect(_adapter *padapter)
12703 {
12704 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12705 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12706 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12707 u8 self_action = MLME_ACTION_UNKNOWN;
12708 u8 state_backup = (pmlmeinfo->state & 0x03);
12709 u8 ASIX_ID[] = {0x00, 0x0E, 0xC6};
12710
12711 if (MLME_IS_AP(padapter))
12712 self_action = MLME_AP_STOPPED;
12713 else if (MLME_IS_MESH(padapter))
12714 self_action = MLME_MESH_STOPPED;
12715 else if (MLME_IS_STA(padapter))
12716 self_action = MLME_STA_DISCONNECTED;
12717 else if (MLME_IS_ADHOC(padapter) || MLME_IS_ADHOC_MASTER(padapter))
12718 self_action = MLME_ADHOC_STOPPED;
12719 else {
12720 RTW_INFO("state:0x%x\n", MLME_STATE(padapter));
12721 rtw_warn_on(1);
12722 }
12723
12724 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
12725 #ifdef CONFIG_HW_P0_TSF_SYNC
12726 if (self_action == MLME_STA_DISCONNECTED)
12727 correct_TSF(padapter, self_action);
12728 #endif
12729 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
12730 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
12731 if (self_action == MLME_STA_DISCONNECTED)
12732 rtw_hal_rcr_set_chk_bssid(padapter, self_action);
12733
12734 /* set MSR to no link state->infra. mode */
12735 Set_MSR(padapter, _HW_STATE_STATION_);
12736
12737 /* check if sta is ASIX peer and fix IOT issue if it is. */
12738 if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) , ASIX_ID , 3)) {
12739 u8 iot_flag = _FALSE;
12740 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
12741 }
12742 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12743
12744 #ifdef CONFIG_MCC_MODE
12745 /* mcc disconnect setting before download LPS rsvd page */
12746 rtw_hal_set_mcc_setting_disconnect(padapter);
12747 #endif /* CONFIG_MCC_MODE */
12748
12749 if (state_backup == WIFI_FW_STATION_STATE) {
12750 if (rtw_port_switch_chk(padapter) == _TRUE) {
12751 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12752 #ifdef CONFIG_LPS
12753 {
12754 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
12755 if (port0_iface)
12756 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, RTW_CMDF_DIRECTLY);
12757 }
12758 #endif
12759 }
12760 }
12761
12762 /* switch to the 20M Hz mode after disconnect */
12763 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
12764 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
12765 #ifdef CONFIG_CTRL_TXSS_BY_TP
12766 pmlmeext->txss_1ss = _FALSE;
12767 #endif
12768
12769 #ifdef CONFIG_FCS_MODE
12770 if (EN_FCS(padapter))
12771 rtw_hal_set_hwreg(padapter, HW_VAR_STOP_FCS_MODE, NULL);
12772 #endif
12773
12774 #ifdef CONFIG_80211D
12775 if (self_action == MLME_STA_DISCONNECTED)
12776 rtw_leavebss_update_regulatory(padapter);
12777 #endif
12778
12779 #ifdef CONFIG_DFS_MASTER
12780 if (!CHK_MLME_STATE(padapter, WIFI_AP_STATE | WIFI_MESH_STATE | WIFI_OP_CH_SWITCHING)) {
12781 /* radar detect status no need to check here for AP/MESH or iface under OPCH_SW */
12782 rtw_dfs_rd_en_decision(padapter, self_action, 0);
12783 }
12784 #endif
12785
12786 if (!MLME_IS_OPCH_SW(padapter)) {
12787 /* channel status no need to check here for iface under OPCH_SW */
12788 u8 ch, bw, offset;
12789
12790 if (rtw_mi_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0)
12791 set_channel_bwmode(padapter, ch, offset, bw);
12792 rtw_mi_update_union_chan_inf(padapter, ch, offset, bw);
12793 rtw_rfctl_update_op_mode(adapter_to_rfctl(padapter), BIT(padapter->iface_id), 0);
12794 }
12795
12796 flush_all_cam_entry(padapter);
12797
12798 _cancel_timer_ex(&pmlmeext->link_timer);
12799
12800 /* pmlmepriv->LinkDetectInfo.TrafficBusyState = _FALSE; */
12801 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
12802 pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
12803
12804 #ifdef CONFIG_TDLS
12805 padapter->tdlsinfo.ap_prohibited = _FALSE;
12806
12807 /* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */
12808 if (padapter->registrypriv.wifi_spec == 1)
12809 padapter->tdlsinfo.ch_switch_prohibited = _FALSE;
12810 #endif /* CONFIG_TDLS */
12811
12812 #ifdef CONFIG_WMMPS_STA
12813 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
12814 /* reset currently related uapsd setting when the connection has broken */
12815 pmlmepriv->qospriv.uapsd_max_sp_len = 0;
12816 pmlmepriv->qospriv.uapsd_tid = 0;
12817 pmlmepriv->qospriv.uapsd_tid_delivery_enabled = 0;
12818 pmlmepriv->qospriv.uapsd_tid_trigger_enabled = 0;
12819 pmlmepriv->qospriv.uapsd_ap_supported = 0;
12820 }
12821 #endif /* CONFIG_WMMPS_STA */
12822 #ifdef CONFIG_RTS_FULL_BW
12823 rtw_set_rts_bw(padapter);
12824 #endif/*CONFIG_RTS_FULL_BW*/
12825
12826 pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_UNKNOWN;
12827 rtw_phydm_update_ap_vendor_ie(padapter);
12828 }
12829
mlmeext_joinbss_event_callback(_adapter * padapter,int join_res)12830 void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
12831 {
12832 struct sta_info *psta;
12833 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12834 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12835 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
12836 struct sta_priv *pstapriv = &padapter->stapriv;
12837 u8 join_type;
12838 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12839
12840 #if (!defined(CONFIG_IOCTL_CFG80211)) || defined(CONFIG_LAYER2_ROAMING)
12841 struct security_priv *psecuritypriv = &padapter->securitypriv;
12842 #endif
12843
12844 if (pmlmepriv->wpa_phase == _TRUE)
12845 pmlmepriv->wpa_phase = _FALSE;
12846
12847 if (join_res < 0) {
12848 join_type = 1;
12849 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12850 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
12851 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
12852 rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_DISCONNECTED);
12853
12854 rtw_btcoex_connect_notify(padapter, join_type);
12855 pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_UNKNOWN;
12856 goto exit_mlmeext_joinbss_event_callback;
12857 }
12858
12859 #ifdef CONFIG_ARP_KEEP_ALIVE
12860 pmlmepriv->bGetGateway = 1;
12861 pmlmepriv->GetGatewayTryCnt = 0;
12862 #endif
12863
12864 #ifdef CONFIG_AP_MODE
12865 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
12866 /* update bc/mc sta_info */
12867 update_bmc_sta(padapter);
12868 }
12869 #endif
12870
12871 /* turn on dynamic functions */
12872 /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */
12873
12874 /* update IOT-releated issue */
12875 update_IOT_info(padapter);
12876
12877 #ifdef CONFIG_RTS_FULL_BW
12878 rtw_set_rts_bw(padapter);
12879 #endif/*CONFIG_RTS_FULL_BW*/
12880
12881 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
12882
12883 /* BCN interval */
12884 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
12885
12886 /* udpate capability */
12887 update_capinfo(padapter, pmlmeinfo->capability);
12888
12889 /* WMM, Update EDCA param */
12890 WMMOnAssocRsp(padapter);
12891 #ifdef CONFIG_80211N_HT
12892 /* HT */
12893 HTOnAssocRsp(padapter);
12894 #endif /* CONFIG_80211N_HT */
12895 #ifdef CONFIG_80211AC_VHT
12896 /* VHT */
12897 VHTOnAssocRsp(padapter);
12898 #endif
12899
12900 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
12901 if (psta) { /* only for infra. mode */
12902 psta->wireless_mode = pmlmeext->cur_wireless_mode;
12903
12904 /* set per sta rate after updating HT cap. */
12905 set_sta_rate(padapter, psta);
12906
12907 rtw_sta_media_status_rpt(padapter, psta, 1);
12908
12909 /* wakeup macid after join bss successfully to ensure
12910 the subsequent data frames can be sent out normally */
12911 rtw_hal_macid_wakeup(padapter, psta->cmn.mac_id);
12912
12913 rtw_xmit_queue_clear(psta);
12914 }
12915
12916 #ifndef CONFIG_IOCTL_CFG80211
12917 if (is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm))
12918 rtw_sec_restore_wep_key(padapter);
12919 #endif /* CONFIG_IOCTL_CFG80211 */
12920
12921 if (rtw_port_switch_chk(padapter) == _TRUE)
12922 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12923
12924 join_type = 2;
12925 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12926
12927 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
12928 rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_CONNECTED);
12929
12930 /* correcting TSF */
12931 correct_TSF(padapter, MLME_STA_CONNECTED);
12932
12933 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
12934 }
12935
12936 #ifdef CONFIG_LPS
12937 #ifndef CONFIG_FW_MULTI_PORT_SUPPORT
12938 if (get_hw_port(padapter) == HW_PORT0)
12939 #endif
12940 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, RTW_CMDF_DIRECTLY);
12941 #endif
12942
12943 rtw_btcoex_connect_notify(padapter, join_type);
12944
12945 #ifdef CONFIG_BEAMFORMING
12946 if (psta)
12947 beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
12948 #endif/*CONFIG_BEAMFORMING*/
12949
12950 exit_mlmeext_joinbss_event_callback:
12951
12952 rtw_phydm_update_ap_vendor_ie(padapter);
12953
12954 rtw_join_done_chk_ch(padapter, join_res);
12955 #ifdef CONFIG_RTW_REPEATER_SON
12956 rtw_rson_join_done(padapter);
12957 #endif
12958
12959 #ifdef CONFIG_LAYER2_ROAMING
12960 if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) &&
12961 (pmlmepriv->roam_network)) {
12962 struct xmit_frame *rframe;
12963 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
12964 _list *plist, *phead;
12965 _irqL irqL;
12966 _pkt *pkt;
12967
12968 padapter->mlmepriv.roam_network = NULL;
12969 _enter_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL);
12970 phead = get_list_head(&pxmitpriv->rpkt_queue);
12971 plist = get_next(phead);
12972 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
12973 rframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
12974 plist = get_next(plist);
12975 rtw_list_delete(&rframe->list);
12976 pkt = rframe->pkt;
12977 rtw_xmit_posthandle(padapter, rframe, pkt);
12978 }
12979 _exit_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL);
12980 }
12981 #endif
12982 RTW_INFO("=>%s - End to Connection without 4-way\n", __FUNCTION__);
12983 }
12984
12985 /* currently only adhoc mode will go here */
mlmeext_sta_add_event_callback(_adapter * padapter,struct sta_info * psta)12986 void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
12987 {
12988 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
12989 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12990 u8 join_type;
12991
12992 RTW_INFO("%s\n", __FUNCTION__);
12993
12994 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
12995 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { /* adhoc master or sta_count>1 */
12996 /* nothing to do */
12997 } else { /* adhoc client */
12998 #ifdef CONFIG_AP_MODE
12999 /* update TSF Value */
13000 /* update_TSF(pmlmeext, pframe, len); */
13001
13002 /* correcting TSF */
13003 correct_TSF(padapter, MLME_ADHOC_STARTED);
13004
13005 /* start beacon */
13006 if (send_beacon(padapter) == _FAIL)
13007 rtw_warn_on(1);
13008
13009 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
13010 #endif
13011 }
13012
13013 join_type = 2;
13014 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
13015
13016 rtw_btcoex_connect_notify(padapter, join_type);
13017 }
13018
13019 /* update adhoc sta_info */
13020 update_sta_info(padapter, psta);
13021
13022 rtw_hal_update_sta_ra_info(padapter, psta);
13023
13024 /* ToDo: HT for Ad-hoc */
13025 psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
13026 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
13027
13028 /* rate radaptive */
13029 Update_RA_Entry(padapter, psta);
13030 }
13031
mlmeext_sta_del_event_callback(_adapter * padapter)13032 void mlmeext_sta_del_event_callback(_adapter *padapter)
13033 {
13034 if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
13035 rtw_mlmeext_disconnect(padapter);
13036 }
13037
13038 /****************************************************************************
13039
13040 Following are the functions for the timer handlers
13041
13042 *****************************************************************************/
_linked_info_dump(_adapter * padapter)13043 void _linked_info_dump(_adapter *padapter)
13044 {
13045 if (padapter->bLinkInfoDump) {
13046 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, RTW_DBGDUMP);
13047 rtw_hal_set_odm_var(padapter, HAL_ODM_RX_INFO_DUMP, RTW_DBGDUMP, _FALSE);
13048 }
13049 }
13050 /********************************************************************
13051
13052 When station does not receive any packet in MAX_CONTINUAL_NORXPACKET_COUNT*2 seconds,
13053 recipient station will teardown the block ack by issuing DELBA frame.
13054
13055 *********************************************************************/
rtw_delba_check(_adapter * padapter,struct sta_info * psta,u8 from_timer)13056 void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer)
13057 {
13058 int i = 0;
13059 int ret = _SUCCESS;
13060 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13061 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13062
13063 /*
13064 IOT issue,occur Broadcom ap(Buffalo WZR-D1800H,Netgear R6300).
13065 AP is originator.AP does not transmit unicast packets when STA response its BAR.
13066 This case probably occur ap issue BAR after AP builds BA.
13067
13068 Follow 802.11 spec, STA shall maintain an inactivity timer for every negotiated Block Ack setup.
13069 The inactivity timer is not reset when MPDUs corresponding to other TIDs are received.
13070 */
13071 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) {
13072 for (i = 0; i < TID_NUM ; i++) {
13073 if ((psta->recvreorder_ctrl[i].enable) &&
13074 (sta_rx_data_qos_pkts(psta, i) == sta_last_rx_data_qos_pkts(psta, i)) ) {
13075 if (_TRUE == rtw_inc_and_chk_continual_no_rx_packet(psta, i)) {
13076 /* send a DELBA frame to the peer STA with the Reason Code field set to TIMEOUT */
13077 if (!from_timer)
13078 ret = issue_del_ba_ex(padapter, psta->cmn.mac_addr, i, 39, 0, 3, 1);
13079 else
13080 issue_del_ba(padapter, psta->cmn.mac_addr, i, 39, 0);
13081 psta->recvreorder_ctrl[i].enable = _FALSE;
13082 if (ret != _FAIL)
13083 psta->recvreorder_ctrl[i].ampdu_size = RX_AMPDU_SIZE_INVALID;
13084 rtw_reset_continual_no_rx_packet(psta, i);
13085 }
13086 } else {
13087 /* The inactivity timer is reset when MPDUs to the TID is received. */
13088 rtw_reset_continual_no_rx_packet(psta, i);
13089 }
13090 }
13091 }
13092 }
13093
13094
chk_ap_is_alive(_adapter * padapter,struct sta_info * psta)13095 u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
13096 {
13097 u8 ret = _FALSE;
13098 #ifdef DBG_EXPIRATION_CHK
13099 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13100 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13101
13102 RTW_INFO(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
13103 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
13104 ", retry:%u\n"
13105 , FUNC_ADPT_ARG(padapter)
13106 , STA_RX_PKTS_DIFF_ARG(psta)
13107 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
13108 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
13109 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
13110 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
13111 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
13112 , pmlmeinfo->bcn_interval*/
13113 , pmlmeext->retry
13114 );
13115
13116 RTW_INFO(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
13117 , sta_tx_pkts(psta)
13118 , pmlmeinfo->link_count
13119 );
13120 #endif
13121
13122 if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
13123 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
13124 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
13125 )
13126 ret = _FALSE;
13127 else
13128 ret = _TRUE;
13129
13130 sta_update_last_rx_pkts(psta);
13131
13132 return ret;
13133 }
13134
chk_adhoc_peer_is_alive(struct sta_info * psta)13135 u8 chk_adhoc_peer_is_alive(struct sta_info *psta)
13136 {
13137 u8 ret = _TRUE;
13138
13139 #ifdef DBG_EXPIRATION_CHK
13140 RTW_INFO("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
13141 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
13142 ", expire_to:%u\n"
13143 , MAC_ARG(psta->cmn.mac_addr)
13144 , psta->cmn.rssi_stat.rssi
13145 , STA_RX_PKTS_DIFF_ARG(psta)
13146 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
13147 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
13148 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
13149 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
13150 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
13151 , pmlmeinfo->bcn_interval*/
13152 , psta->expire_to
13153 );
13154 #endif
13155
13156 if (sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)
13157 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
13158 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
13159 ret = _FALSE;
13160
13161 sta_update_last_rx_pkts(psta);
13162
13163 return ret;
13164 }
13165
13166 #ifdef CONFIG_TDLS
chk_tdls_peer_sta_is_alive(_adapter * padapter,struct sta_info * psta)13167 u8 chk_tdls_peer_sta_is_alive(_adapter *padapter, struct sta_info *psta)
13168 {
13169 if ((psta->sta_stats.rx_data_pkts == psta->sta_stats.last_rx_data_pkts)
13170 && (psta->sta_stats.rx_tdls_disc_rsp_pkts == psta->sta_stats.last_rx_tdls_disc_rsp_pkts))
13171 return _FALSE;
13172
13173 return _TRUE;
13174 }
13175
linked_status_chk_tdls(_adapter * padapter)13176 void linked_status_chk_tdls(_adapter *padapter)
13177 {
13178 struct candidate_pool {
13179 struct sta_info *psta;
13180 u8 addr[ETH_ALEN];
13181 };
13182 struct sta_priv *pstapriv = &padapter->stapriv;
13183 _irqL irqL;
13184 u8 ack_chk;
13185 struct sta_info *psta;
13186 int i, num_teardown = 0, num_checkalive = 0;
13187 _list *plist, *phead;
13188 struct tdls_txmgmt txmgmt;
13189 struct candidate_pool checkalive[MAX_ALLOWED_TDLS_STA_NUM];
13190 struct candidate_pool teardown[MAX_ALLOWED_TDLS_STA_NUM];
13191 u8 tdls_sta_max = _FALSE;
13192
13193 #define ALIVE_MIN 2
13194 #define ALIVE_MAX 5
13195
13196 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
13197 _rtw_memset(checkalive, 0x00, sizeof(checkalive));
13198 _rtw_memset(teardown, 0x00, sizeof(teardown));
13199
13200 if ((padapter->tdlsinfo.link_established == _TRUE)) {
13201 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13202 for (i = 0; i < NUM_STA; i++) {
13203 phead = &(pstapriv->sta_hash[i]);
13204 plist = get_next(phead);
13205
13206 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
13207 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
13208 plist = get_next(plist);
13209
13210 if (psta->tdls_sta_state & TDLS_LINKED_STATE) {
13211 psta->alive_count++;
13212 if (psta->alive_count >= ALIVE_MIN) {
13213 if (chk_tdls_peer_sta_is_alive(padapter, psta) == _FALSE) {
13214 if (psta->alive_count < ALIVE_MAX) {
13215 _rtw_memcpy(checkalive[num_checkalive].addr, psta->cmn.mac_addr, ETH_ALEN);
13216 checkalive[num_checkalive].psta = psta;
13217 num_checkalive++;
13218 } else {
13219 _rtw_memcpy(teardown[num_teardown].addr, psta->cmn.mac_addr, ETH_ALEN);
13220 teardown[num_teardown].psta = psta;
13221 num_teardown++;
13222 }
13223 } else
13224 psta->alive_count = 0;
13225 }
13226 psta->sta_stats.last_rx_data_pkts = psta->sta_stats.rx_data_pkts;
13227 psta->sta_stats.last_rx_tdls_disc_rsp_pkts = psta->sta_stats.rx_tdls_disc_rsp_pkts;
13228
13229 if ((num_checkalive >= MAX_ALLOWED_TDLS_STA_NUM) || (num_teardown >= MAX_ALLOWED_TDLS_STA_NUM)) {
13230 tdls_sta_max = _TRUE;
13231 break;
13232 }
13233 }
13234 }
13235
13236 if (tdls_sta_max == _TRUE)
13237 break;
13238 }
13239 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13240
13241 if (num_checkalive > 0) {
13242 for (i = 0; i < num_checkalive; i++) {
13243 _rtw_memcpy(txmgmt.peer, checkalive[i].addr, ETH_ALEN);
13244 issue_tdls_dis_req(padapter, &txmgmt);
13245 issue_tdls_dis_req(padapter, &txmgmt);
13246 issue_tdls_dis_req(padapter, &txmgmt);
13247 }
13248 }
13249
13250 if (num_teardown > 0) {
13251 for (i = 0; i < num_teardown; i++) {
13252 RTW_INFO("[%s %d] Send teardown to "MAC_FMT"\n", __FUNCTION__, __LINE__, MAC_ARG(teardown[i].addr));
13253 txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
13254 _rtw_memcpy(txmgmt.peer, teardown[i].addr, ETH_ALEN);
13255 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
13256 }
13257 }
13258 }
13259
13260 }
13261 #endif /* CONFIG_TDLS */
13262
rtw_get_rx_chk_limit(_adapter * adapter)13263 inline int rtw_get_rx_chk_limit(_adapter *adapter)
13264 {
13265 return adapter->stapriv.rx_chk_limit;
13266 }
13267
rtw_set_rx_chk_limit(_adapter * adapter,int limit)13268 inline void rtw_set_rx_chk_limit(_adapter *adapter, int limit)
13269 {
13270 adapter->stapriv.rx_chk_limit = limit;
13271 }
13272
13273 /* from_timer == 1 means driver is in LPS */
linked_status_chk(_adapter * padapter,u8 from_timer)13274 void linked_status_chk(_adapter *padapter, u8 from_timer)
13275 {
13276 u32 i;
13277 struct sta_info *psta;
13278 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13279 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13280 struct sta_priv *pstapriv = &padapter->stapriv;
13281 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
13282 #ifdef CONFIG_LAYER2_ROAMING
13283 struct recv_priv *precvpriv = &padapter->recvpriv;
13284 #endif
13285
13286 #ifdef CONFIG_RTW_WDS
13287 rtw_wds_gptr_expire(padapter);
13288 #endif
13289
13290 if (padapter->registrypriv.mp_mode == _TRUE)
13291 return;
13292
13293 if (check_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON))
13294 return;
13295
13296 if (is_client_associated_to_ap(padapter)) {
13297 /* linked infrastructure client mode */
13298
13299 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
13300 int rx_chk_limit;
13301 int link_count_limit;
13302
13303 #if defined(CONFIG_RTW_REPEATER_SON)
13304 rtw_rson_scan_wk_cmd(padapter, RSON_SCAN_PROCESS);
13305 #elif defined(CONFIG_LAYER2_ROAMING)
13306 if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) {
13307 RTW_INFO("signal_strength_data.avg_val = %d\n", precvpriv->signal_strength_data.avg_val);
13308 if ((precvpriv->signal_strength_data.avg_val < pmlmepriv->roam_rssi_threshold)
13309 && (rtw_get_passing_time_ms(pmlmepriv->last_roaming) >= pmlmepriv->roam_scan_int*2000)) {
13310 #ifdef CONFIG_RTW_80211K
13311 rtw_roam_nb_discover(padapter, _FALSE);
13312 #endif
13313 pmlmepriv->need_to_roam = _TRUE;
13314 rtw_drv_scan_by_self(padapter, RTW_AUTO_SCAN_REASON_ROAM);
13315 pmlmepriv->last_roaming = rtw_get_current_time();
13316 } else
13317 pmlmepriv->need_to_roam = _FALSE;
13318 }
13319 #endif
13320 #ifdef CONFIG_MCC_MODE
13321 /*
13322 * due to tx ps null date to ao, so ap doest not tx pkt to driver
13323 * we may check chk_ap_is_alive fail, and may issue_probereq to wrong channel under sitesurvey
13324 * don't keep alive check under MCC
13325 */
13326 if (rtw_hal_mcc_link_status_chk(padapter, __func__) == _FALSE)
13327 return;
13328 #endif
13329
13330 rx_chk_limit = rtw_get_rx_chk_limit(padapter);
13331
13332 #ifdef CONFIG_ARP_KEEP_ALIVE
13333 if (!from_timer && pmlmepriv->bGetGateway == 1 && pmlmepriv->GetGatewayTryCnt < 3) {
13334 RTW_INFO("do rtw_gw_addr_query() : %d\n", pmlmepriv->GetGatewayTryCnt);
13335 pmlmepriv->GetGatewayTryCnt++;
13336 if (rtw_gw_addr_query(padapter) == 0)
13337 pmlmepriv->bGetGateway = 0;
13338 else {
13339 _rtw_memset(pmlmepriv->gw_ip, 0, 4);
13340 _rtw_memset(pmlmepriv->gw_mac_addr, 0, ETH_ALEN);
13341 }
13342 }
13343 #endif
13344 #ifdef CONFIG_P2P
13345 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) {
13346 if (!from_timer)
13347 link_count_limit = 3; /* 8 sec */
13348 else
13349 link_count_limit = 15; /* 32 sec */
13350 } else
13351 #endif /* CONFIG_P2P */
13352 {
13353 if (!from_timer)
13354 link_count_limit = 7; /* 16 sec */
13355 else
13356 link_count_limit = 29; /* 60 sec */
13357 }
13358
13359 #ifdef CONFIG_TDLS
13360 #ifdef CONFIG_TDLS_CH_SW
13361 if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
13362 return;
13363 #endif /* CONFIG_TDLS_CH_SW */
13364
13365 #ifdef CONFIG_TDLS_AUTOCHECKALIVE
13366 linked_status_chk_tdls(padapter);
13367 #endif /* CONFIG_TDLS_AUTOCHECKALIVE */
13368 #endif /* CONFIG_TDLS */
13369
13370 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
13371 if (psta != NULL) {
13372 bool is_p2p_enable = _FALSE;
13373 #ifdef CONFIG_P2P
13374 is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
13375 #endif
13376
13377 #ifdef CONFIG_ISSUE_DELBA_WHEN_NO_TRAFFIC
13378 /*issue delba when ap does not tx data packet that is Broadcom ap */
13379 rtw_delba_check(padapter, psta, from_timer);
13380 #endif
13381 if (chk_ap_is_alive(padapter, psta) == _FALSE)
13382 rx_chk = _FAIL;
13383
13384 if (sta_last_tx_pkts(psta) == sta_tx_pkts(psta))
13385 tx_chk = _FAIL;
13386
13387 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
13388 if (!from_timer && pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)
13389 ) {
13390 u8 backup_ch = 0, backup_bw = 0, backup_offset = 0;
13391 u8 union_ch = 0, union_bw = 0, union_offset = 0;
13392 u8 switch_channel_by_drv = _TRUE;
13393
13394
13395 #ifdef CONFIG_MCC_MODE
13396 if (MCC_EN(padapter)) {
13397 /* driver doesn't switch channel under MCC */
13398 if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC))
13399 switch_channel_by_drv = _FALSE;
13400 }
13401 #endif
13402 if (switch_channel_by_drv) {
13403 if (!rtw_mi_get_ch_setting_union(padapter, &union_ch, &union_bw, &union_offset)
13404 || pmlmeext->cur_channel != union_ch)
13405 goto bypass_active_keep_alive;
13406
13407 /* switch to correct channel of current network before issue keep-alive frames */
13408 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
13409 backup_ch = rtw_get_oper_ch(padapter);
13410 backup_bw = rtw_get_oper_bw(padapter);
13411 backup_offset = rtw_get_oper_choffset(padapter);
13412 set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
13413 }
13414 }
13415
13416 if (rx_chk != _SUCCESS)
13417 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->cmn.mac_addr, 0, 0, 3, 1);
13418
13419 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) || rx_chk != _SUCCESS) {
13420 if (rtw_mi_check_fwstate(padapter, WIFI_UNDER_SURVEY))
13421 tx_chk = issue_nulldata(padapter, psta->cmn.mac_addr, 1, 3, 1);
13422 else
13423 tx_chk = issue_nulldata(padapter, psta->cmn.mac_addr, 0, 3, 1);
13424 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
13425 if (tx_chk == _SUCCESS && !is_p2p_enable)
13426 rx_chk = _SUCCESS;
13427 }
13428
13429 /* back to the original operation channel */
13430 if (backup_ch > 0 && switch_channel_by_drv)
13431 set_channel_bwmode(padapter, backup_ch, backup_offset, backup_bw);
13432
13433 bypass_active_keep_alive:
13434 ;
13435 } else
13436 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
13437 {
13438 if (rx_chk != _SUCCESS) {
13439 if (pmlmeext->retry == 0) {
13440 #ifdef DBG_EXPIRATION_CHK
13441 RTW_INFO("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
13442 #endif
13443 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, (from_timer ? 0 : 1));
13444 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, (from_timer ? 0 : 1));
13445 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, (from_timer ? 0 : 1));
13446 }
13447 }
13448
13449 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit
13450 #ifdef CONFIG_MCC_MODE
13451 /* FW tx nulldata under MCC mode, we just check ap is alive */
13452 && (!rtw_hal_check_mcc_status(padapter, MCC_STATUS_NEED_MCC))
13453 #endif /* CONFIG_MCC_MODE */
13454 ) {
13455 #ifdef DBG_EXPIRATION_CHK
13456 RTW_INFO("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer ? 1 : 0);
13457 #endif
13458 if (from_timer || rtw_mi_check_fwstate(padapter, WIFI_UNDER_SURVEY))
13459 tx_chk = issue_nulldata(padapter, NULL, 1, 0, 0);
13460 else
13461 tx_chk = issue_nulldata(padapter, NULL, 0, 1, 1);
13462 }
13463 }
13464
13465 if (rx_chk == _FAIL) {
13466 pmlmeext->retry++;
13467 if (pmlmeext->retry > rx_chk_limit) {
13468 RTW_PRINT(FUNC_ADPT_FMT" disconnect or roaming\n",
13469 FUNC_ADPT_ARG(padapter));
13470 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
13471 , WLAN_REASON_EXPIRATION_CHK, _FALSE);
13472 return;
13473 }
13474 } else
13475 pmlmeext->retry = 0;
13476
13477 if (tx_chk == _FAIL)
13478 pmlmeinfo->link_count %= (link_count_limit + 1);
13479 else {
13480 psta->sta_stats.last_tx_pkts = psta->sta_stats.tx_pkts;
13481 pmlmeinfo->link_count = 0;
13482 }
13483
13484 } /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */
13485
13486 } else if (is_client_associated_to_ibss(padapter)) {
13487 _irqL irqL;
13488 _list *phead, *plist, dlist;
13489
13490 _rtw_init_listhead(&dlist);
13491
13492 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13493
13494 for (i = 0; i < NUM_STA; i++) {
13495
13496 phead = &(pstapriv->sta_hash[i]);
13497 plist = get_next(phead);
13498 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
13499 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
13500 plist = get_next(plist);
13501
13502 if (is_broadcast_mac_addr(psta->cmn.mac_addr))
13503 continue;
13504
13505 if (chk_adhoc_peer_is_alive(psta) || !psta->expire_to)
13506 psta->expire_to = pstapriv->adhoc_expire_to;
13507 else
13508 psta->expire_to--;
13509
13510 if (psta->expire_to <= 0) {
13511 rtw_list_delete(&psta->list);
13512 rtw_list_insert_tail(&psta->list, &dlist);
13513 }
13514 }
13515 }
13516
13517 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13518
13519 plist = get_next(&dlist);
13520 while (rtw_end_of_queue_search(&dlist, plist) == _FALSE) {
13521 psta = LIST_CONTAINOR(plist, struct sta_info, list);
13522 plist = get_next(plist);
13523 rtw_list_delete(&psta->list);
13524 RTW_INFO(FUNC_ADPT_FMT" ibss expire "MAC_FMT"\n"
13525 , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
13526 report_del_sta_event(padapter, psta->cmn.mac_addr, WLAN_REASON_EXPIRATION_CHK, from_timer ? _TRUE : _FALSE, _FALSE);
13527 }
13528 }
13529
13530 }
13531
survey_timer_hdl(void * ctx)13532 void survey_timer_hdl(void *ctx)
13533 {
13534 _adapter *padapter = (_adapter *)ctx;
13535 struct cmd_obj *cmd;
13536 struct sitesurvey_parm *psurveyPara;
13537 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
13538 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13539
13540 if (mlmeext_scan_state(pmlmeext) > SCAN_DISABLE) {
13541 cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
13542 if (cmd == NULL) {
13543 rtw_warn_on(1);
13544 goto exit;
13545 }
13546
13547 psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
13548 if (psurveyPara == NULL) {
13549 rtw_warn_on(1);
13550 rtw_mfree((unsigned char *)cmd, sizeof(struct cmd_obj));
13551 goto exit;
13552 }
13553
13554 init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, CMD_SITE_SURVEY);
13555 rtw_enqueue_cmd(pcmdpriv, cmd);
13556 }
13557
13558 exit:
13559 return;
13560 }
13561
13562 #ifdef CONFIG_RTW_REPEATER_SON
13563 /* 100ms pass, stop rson_scan */
rson_timer_hdl(void * ctx)13564 void rson_timer_hdl(void *ctx)
13565 {
13566 _adapter *padapter = (_adapter *)ctx;
13567
13568 rtw_rson_scan_wk_cmd(padapter, RSON_SCAN_DISABLE);
13569 }
13570
13571 #endif
13572
13573 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
rtw_tbtx_xmit_timer_hdl(void * ctx)13574 void rtw_tbtx_xmit_timer_hdl(void *ctx)
13575 {
13576 _adapter *padapter = (_adapter *)ctx;
13577 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13578
13579 if (ATOMIC_READ(&padapter->tbtx_remove_tx_pause) == _TRUE){
13580 ATOMIC_SET(&padapter->tbtx_tx_pause, _FALSE);
13581 rtw_tx_control_cmd(padapter);
13582 }else {
13583 rtw_issue_action_token_rel(padapter);
13584 ATOMIC_SET(&padapter->tbtx_tx_pause, _TRUE);
13585 rtw_tx_control_cmd(padapter);
13586 _set_timer(&pmlmeext->tbtx_xmit_timer, MAX_TXPAUSE_DURATION);
13587 ATOMIC_SET(&padapter->tbtx_remove_tx_pause, _TRUE);
13588 }
13589 }
13590
13591 #ifdef CONFIG_AP_MODE
rtw_tbtx_token_dispatch_timer_hdl(void * ctx)13592 void rtw_tbtx_token_dispatch_timer_hdl(void *ctx)
13593 {
13594 _adapter *padapter = (_adapter *)ctx;
13595 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13596 _irqL irqL;
13597 struct sta_info *psta = NULL;
13598 struct sta_priv *pstapriv = &padapter->stapriv;
13599 _list *phead, *plist;
13600 int i, found = _FALSE;
13601 u8 nr_send, th_idx = 0;
13602
13603 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
13604 RTW_DBG("%s:asoc_cnt: %d\n",__func__, pstapriv->tbtx_asoc_list_cnt);
13605
13606 // check number of TBTX sta
13607 if (padapter->stapriv.tbtx_asoc_list_cnt < 2)
13608 goto exit;
13609
13610 // dispatch token
13611
13612 nr_send = RTW_DIV_ROUND_UP(pstapriv->tbtx_asoc_list_cnt, NR_TBTX_SLOT);
13613
13614 phead = &pstapriv->asoc_list;
13615 plist = get_next(phead);
13616 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
13617 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
13618 /* psta is supporting TBTX */
13619 if ((!psta) || (!psta->tbtx_enable))
13620 RTW_DBG("sta tbtx_enable is false\n");
13621 else {
13622 for (i = 0; i < nr_send; i++) {
13623 if (pstapriv->last_token_holder == psta) {
13624 found = _TRUE;
13625 goto outof_loop;
13626 }
13627 }
13628 }
13629 plist = get_next(plist);
13630 }
13631 outof_loop:
13632
13633 RTW_DBG("rtw_tbtx_token_dispatch_timer_hdl() th_idx=%d, nr_send=%d, phead=%p, plist=%p, found=%d\n ", th_idx , nr_send, phead, plist, found);
13634 if (!found) {
13635 plist = get_next(phead);
13636 while(rtw_end_of_queue_search(phead, plist) == _FALSE) {
13637 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
13638 if ((!psta) || (!psta->tbtx_enable))
13639 RTW_DBG("sta tbtx_enable is false\n");
13640 else {
13641 pstapriv->token_holder[th_idx] = psta;
13642 rtw_issue_action_token_req(padapter, pstapriv->token_holder[th_idx++]);
13643 break;
13644 }
13645 plist = get_next(plist);
13646 }
13647 }
13648
13649 for (i=th_idx; i<nr_send;) {
13650 plist = get_next(plist);
13651 if (plist == phead)
13652 plist = get_next(plist);
13653 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
13654 if ((!psta) || (!psta->tbtx_enable))
13655 RTW_DBG("sta tbtx_enable is false\n");
13656 else {
13657 pstapriv->token_holder[th_idx] = psta;
13658 rtw_issue_action_token_req(padapter, pstapriv->token_holder[th_idx++]);
13659 i++;
13660 }
13661 }
13662 ATOMIC_SET(&pstapriv->nr_token_keeper, nr_send);
13663
13664
13665 exit:
13666 // set_timer
13667 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
13668 _set_timer(&pmlmeext->tbtx_token_dispatch_timer, TBTX_TX_DURATION);
13669 }
13670 #endif /* CONFIG_AP_MODE */
13671 #endif /* CONFIG_RTW_TOKEN_BASED_XMIT */
13672
link_timer_hdl(void * ctx)13673 void link_timer_hdl(void *ctx)
13674 {
13675 _adapter *padapter = (_adapter *)ctx;
13676 /* static unsigned int rx_pkt = 0; */
13677 /* static u64 tx_cnt = 0; */
13678 /* struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); */
13679 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13680 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13681 /* struct sta_priv *pstapriv = &padapter->stapriv; */
13682 #ifdef CONFIG_RTW_80211R
13683 struct sta_priv *pstapriv = &padapter->stapriv;
13684 struct sta_info *psta = NULL;
13685 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
13686 #endif
13687
13688 if (rtw_sta_linking_test_force_fail())
13689 RTW_INFO("rtw_sta_linking_test_force_fail\n");
13690
13691 if (pmlmeext->join_abort && pmlmeinfo->state != WIFI_FW_NULL_STATE) {
13692 RTW_INFO(FUNC_ADPT_FMT" join abort\n", FUNC_ADPT_ARG(padapter));
13693 pmlmeinfo->state = WIFI_FW_NULL_STATE;
13694 report_join_res(padapter, -4, WLAN_STATUS_UNSPECIFIED_FAILURE);
13695 goto exit;
13696 }
13697
13698 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
13699 RTW_INFO("link_timer_hdl:no beacon while connecting\n");
13700 pmlmeinfo->state = WIFI_FW_NULL_STATE;
13701 report_join_res(padapter, -3, WLAN_STATUS_UNSPECIFIED_FAILURE);
13702 } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
13703
13704 #ifdef CONFIG_IOCTL_CFG80211
13705 if (rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE))
13706 return;
13707 #endif /* CONFIG_IOCTL_CFG80211 */
13708
13709 /* re-auth timer */
13710 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
13711 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
13712 /* { */
13713 pmlmeinfo->state = 0;
13714 if (pmlmeinfo->auth_status) {
13715 report_join_res(padapter, -1, pmlmeinfo->auth_status);
13716 pmlmeinfo->auth_status = 0; /* reset */
13717 } else
13718 report_join_res(padapter, -1, WLAN_STATUS_UNSPECIFIED_FAILURE);
13719 return;
13720 /* } */
13721 /* else */
13722 /* { */
13723 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
13724 /* pmlmeinfo->reauth_count = 0; */
13725 /* } */
13726 }
13727
13728 RTW_INFO("link_timer_hdl: auth timeout and try again\n");
13729 pmlmeinfo->auth_seq = 1;
13730 issue_auth(padapter, NULL, 0);
13731 set_link_timer(pmlmeext, REAUTH_TO);
13732 } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
13733 /* re-assoc timer */
13734 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
13735 pmlmeinfo->state = WIFI_FW_NULL_STATE;
13736 #ifdef CONFIG_RTW_80211R
13737 if (rtw_ft_roam(padapter)) {
13738 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
13739 if (psta)
13740 rtw_free_stainfo(padapter, psta);
13741 }
13742 #endif
13743 report_join_res(padapter, -2, WLAN_STATUS_UNSPECIFIED_FAILURE);
13744 return;
13745 }
13746
13747 #ifdef CONFIG_RTW_80211R
13748 if (rtw_ft_roam(padapter)) {
13749 RTW_INFO("link_timer_hdl: reassoc timeout and try again\n");
13750 issue_reassocreq(padapter);
13751 } else
13752 #endif
13753 {
13754 RTW_INFO("link_timer_hdl: assoc timeout and try again\n");
13755 issue_assocreq(padapter);
13756 }
13757
13758 set_link_timer(pmlmeext, REASSOC_TO);
13759 }
13760
13761 exit:
13762 return;
13763 }
13764
addba_timer_hdl(void * ctx)13765 void addba_timer_hdl(void *ctx)
13766 {
13767 struct sta_info *psta = (struct sta_info *)ctx;
13768
13769 #ifdef CONFIG_80211N_HT
13770 struct ht_priv *phtpriv;
13771
13772 if (!psta)
13773 return;
13774
13775 phtpriv = &psta->htpriv;
13776
13777 if ((phtpriv->ht_option == _TRUE) && (phtpriv->ampdu_enable == _TRUE)) {
13778 if (phtpriv->candidate_tid_bitmap)
13779 phtpriv->candidate_tid_bitmap = 0x0;
13780
13781 }
13782 #endif /* CONFIG_80211N_HT */
13783 }
13784
13785 #ifdef CONFIG_IEEE80211W
report_sta_timeout_event(_adapter * padapter,u8 * MacAddr,unsigned short reason)13786 void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason)
13787 {
13788 struct cmd_obj *pcmd_obj;
13789 u8 *pevtcmd;
13790 u32 cmdsz;
13791 struct sta_info *psta;
13792 int mac_id;
13793 struct stadel_event *pdel_sta_evt;
13794 struct rtw_evt_header *evt_hdr;
13795 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13796 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
13797
13798 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
13799 if (pcmd_obj == NULL)
13800 return;
13801
13802 cmdsz = (sizeof(struct stadel_event) + sizeof(struct rtw_evt_header));
13803 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
13804 if (pevtcmd == NULL) {
13805 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
13806 return;
13807 }
13808
13809 _rtw_init_listhead(&pcmd_obj->list);
13810
13811 pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
13812 pcmd_obj->cmdsz = cmdsz;
13813 pcmd_obj->parmbuf = pevtcmd;
13814
13815 pcmd_obj->rsp = NULL;
13816 pcmd_obj->rspsz = 0;
13817
13818 evt_hdr = (struct rtw_evt_header *)(pevtcmd);
13819 evt_hdr->len = sizeof(struct stadel_event);
13820 evt_hdr->id = EVT_TIMEOUT_STA;
13821 evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
13822
13823 pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct rtw_evt_header));
13824 _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
13825 _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
13826
13827
13828 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
13829 if (psta)
13830 mac_id = (int)psta->cmn.mac_id;
13831 else
13832 mac_id = (-1);
13833
13834 pdel_sta_evt->mac_id = mac_id;
13835
13836 RTW_INFO("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
13837
13838 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
13839
13840 return;
13841 }
13842
clnt_sa_query_timeout(_adapter * padapter)13843 void clnt_sa_query_timeout(_adapter *padapter)
13844 {
13845 struct mlme_ext_priv *mlmeext = &(padapter->mlmeextpriv);
13846 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
13847
13848 RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
13849 receive_disconnect(padapter, get_my_bssid(&(mlmeinfo->network)), WLAN_REASON_SA_QUERY_TIMEOUT, _FALSE);
13850 }
13851
sa_query_timer_hdl(void * ctx)13852 void sa_query_timer_hdl(void *ctx)
13853 {
13854 struct sta_info *psta = (struct sta_info *)ctx;
13855 _adapter *padapter = psta->padapter;
13856 _irqL irqL;
13857 struct sta_priv *pstapriv = &padapter->stapriv;
13858 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
13859
13860 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE &&
13861 check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
13862 clnt_sa_query_timeout(padapter);
13863 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
13864 report_sta_timeout_event(padapter, psta->cmn.mac_addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
13865 }
13866
13867 #endif /* CONFIG_IEEE80211W */
13868
13869 #ifdef CONFIG_AUTO_AP_MODE
rtw_auto_ap_rx_msg_dump(_adapter * padapter,union recv_frame * precv_frame,u8 * ehdr_pos)13870 void rtw_auto_ap_rx_msg_dump(_adapter *padapter, union recv_frame *precv_frame, u8 *ehdr_pos)
13871 {
13872 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
13873 struct sta_info *psta = precv_frame->u.hdr.psta;
13874 struct ethhdr *ehdr = (struct ethhdr *)ehdr_pos;
13875
13876 RTW_INFO("eth rx: got eth_type=0x%x\n", ntohs(ehdr->h_proto));
13877
13878 if (psta && psta->isrc && psta->pid > 0) {
13879 u16 rx_pid;
13880
13881 rx_pid = *(u16 *)(ehdr_pos + ETH_HLEN);
13882
13883 RTW_INFO("eth rx(pid=0x%x): sta("MAC_FMT") pid=0x%x\n",
13884 rx_pid, MAC_ARG(psta->cmn.mac_addr), psta->pid);
13885
13886 if (rx_pid == psta->pid) {
13887 int i;
13888 u16 len = *(u16 *)(ehdr_pos + ETH_HLEN + 2);
13889 /* u16 ctrl_type = *(u16 *)(ehdr_pos + ETH_HLEN + 4); */
13890
13891 /* RTW_INFO("eth, RC: len=0x%x, ctrl_type=0x%x\n", len, ctrl_type); */
13892 RTW_INFO("eth, RC: len=0x%x\n", len);
13893
13894 for (i = 0; i < len; i++)
13895 RTW_INFO("0x%x\n", *(ehdr_pos + ETH_HLEN + 4 + i));
13896 /* RTW_INFO("0x%x\n", *(ehdr_pos + ETH_HLEN + 6 + i)); */
13897
13898 RTW_INFO("eth, RC-end\n");
13899 }
13900 }
13901
13902 }
13903
rtw_start_auto_ap(_adapter * adapter)13904 void rtw_start_auto_ap(_adapter *adapter)
13905 {
13906 RTW_INFO("%s\n", __FUNCTION__);
13907
13908 rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode, 0);
13909
13910 rtw_setopmode_cmd(adapter, Ndis802_11APMode, RTW_CMDF_WAIT_ACK);
13911 }
13912
rtw_auto_ap_start_beacon(_adapter * adapter)13913 static int rtw_auto_ap_start_beacon(_adapter *adapter)
13914 {
13915 int ret = 0;
13916 u8 *pbuf = NULL;
13917 uint len;
13918 u8 supportRate[16];
13919 int sz = 0, rateLen;
13920 u8 *ie;
13921 u8 wireless_mode, oper_channel;
13922 u8 ssid[3] = {0}; /* hidden ssid */
13923 u32 ssid_len = sizeof(ssid);
13924 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
13925
13926 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
13927 return -EINVAL;
13928
13929
13930 len = 128;
13931 pbuf = rtw_zmalloc(len);
13932 if (!pbuf)
13933 return -ENOMEM;
13934
13935
13936 /* generate beacon */
13937 ie = pbuf;
13938
13939 /* timestamp will be inserted by hardware */
13940 sz += 8;
13941 ie += sz;
13942
13943 /* beacon interval : 2bytes */
13944 *(u16 *)ie = cpu_to_le16((u16)100); /* BCN_INTERVAL=100; */
13945 sz += 2;
13946 ie += 2;
13947
13948 /* capability info */
13949 *(u16 *)ie = 0;
13950 *(u16 *)ie |= cpu_to_le16(cap_ESS);
13951 *(u16 *)ie |= cpu_to_le16(cap_ShortPremble);
13952 /* *(u16*)ie |= cpu_to_le16(cap_Privacy); */
13953 sz += 2;
13954 ie += 2;
13955
13956 /* SSID */
13957 ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
13958
13959 /* supported rates */
13960 wireless_mode = (WIRELESS_11BG_24N & padapter->registrypriv.wireless_mode);
13961 rtw_set_supported_rate(supportRate, wireless_mode);
13962 rateLen = rtw_get_rateset_len(supportRate);
13963 if (rateLen > 8)
13964 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
13965 else
13966 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
13967
13968
13969 /* DS parameter set */
13970 if (rtw_mi_check_status(adapter, MI_LINKED))
13971 oper_channel = rtw_mi_get_union_chan(adapter);
13972 else
13973 oper_channel = adapter_to_dvobj(adapter)->oper_channel;
13974
13975 ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
13976
13977 /* ext supported rates */
13978 if (rateLen > 8)
13979 ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
13980
13981 RTW_INFO("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz);
13982
13983 /* lunch ap mode & start to issue beacon */
13984 if (rtw_check_beacon_data(adapter, pbuf, sz) == _SUCCESS) {
13985
13986 } else
13987 ret = -EINVAL;
13988
13989
13990 rtw_mfree(pbuf, len);
13991
13992 return ret;
13993
13994 }
13995 #endif/* CONFIG_AUTO_AP_MODE */
13996
13997 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
tx_control_hdl(_adapter * adapter)13998 u8 tx_control_hdl(_adapter *adapter)
13999 {
14000 u8 val;
14001
14002 if(ATOMIC_READ(&adapter->tbtx_tx_pause))
14003 val = 0xff;
14004 else
14005 val = 0x00;
14006
14007 rtw_hal_set_hwreg(adapter, HW_VAR_TXPAUSE, &val);
14008
14009 return H2C_SUCCESS;
14010 }
14011 #endif
14012
14013 #ifdef CONFIG_AP_MODE
stop_ap_hdl(_adapter * adapter)14014 u8 stop_ap_hdl(_adapter *adapter)
14015 {
14016 u8 self_action = MLME_ACTION_UNKNOWN;
14017
14018 RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
14019
14020 if (MLME_IS_AP(adapter))
14021 self_action = MLME_AP_STOPPED;
14022 else if (MLME_IS_MESH(adapter))
14023 self_action = MLME_MESH_STOPPED;
14024 else
14025 rtw_warn_on(1);
14026
14027 rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11Infrastructure, RTW_CMDF_DIRECTLY);
14028 rtw_setopmode_cmd(adapter, Ndis802_11Infrastructure, RTW_CMDF_DIRECTLY);
14029
14030 #ifdef CONFIG_DFS_MASTER
14031 rtw_dfs_rd_en_decision(adapter, self_action, 0);
14032 #endif
14033
14034 return H2C_SUCCESS;
14035 }
14036 #endif
14037
setopmode_hdl(_adapter * padapter,u8 * pbuf)14038 u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
14039 {
14040 u8 type;
14041 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14042 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14043 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
14044
14045 if (psetop->mode == Ndis802_11APMode
14046 || psetop->mode == Ndis802_11_mesh
14047 ) {
14048 pmlmeinfo->state = WIFI_FW_AP_STATE;
14049 type = _HW_STATE_AP_;
14050 } else if (psetop->mode == Ndis802_11Infrastructure) {
14051 pmlmeinfo->state &= ~(BIT(0) | BIT(1)); /* clear state */
14052 pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */
14053 type = _HW_STATE_STATION_;
14054 } else if (psetop->mode == Ndis802_11IBSS)
14055 type = _HW_STATE_ADHOC_;
14056 else if (psetop->mode == Ndis802_11Monitor)
14057 type = _HW_STATE_MONITOR_;
14058 else
14059 type = _HW_STATE_NOLINK_;
14060
14061 #ifdef CONFIG_AP_PORT_SWAP
14062 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, (u8 *)(&type));
14063 #endif
14064
14065 rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
14066
14067 #ifdef CONFIG_AUTO_AP_MODE
14068 if (psetop->mode == Ndis802_11APMode)
14069 rtw_auto_ap_start_beacon(padapter);
14070 #endif
14071
14072 if (rtw_port_switch_chk(padapter) == _TRUE) {
14073 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
14074
14075 if (psetop->mode == Ndis802_11APMode)
14076 adapter_to_pwrctl(padapter)->fw_psmode_iface_id = 0xff; /* ap mode won't dowload rsvd pages */
14077 else if (psetop->mode == Ndis802_11Infrastructure) {
14078 #ifdef CONFIG_LPS
14079 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
14080 if (port0_iface)
14081 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, RTW_CMDF_DIRECTLY);
14082 #endif
14083 }
14084 }
14085
14086 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
14087 /* Enable beacon early interrupt IMR of AP mode after port switch done */
14088 if (MLME_IS_AP(padapter))
14089 rtw_hal_set_ap_bcn_imr_cmd(padapter, 1);
14090 #endif
14091
14092 #ifdef CONFIG_BT_COEXIST
14093 if (psetop->mode == Ndis802_11APMode
14094 || psetop->mode == Ndis802_11_mesh
14095 || psetop->mode == Ndis802_11Monitor
14096 ) {
14097 /* Do this after port switch to */
14098 /* prevent from downloading rsvd page to wrong port */
14099 rtw_btcoex_MediaStatusNotify(padapter, 1); /* connect */
14100 }
14101 #endif /* CONFIG_BT_COEXIST */
14102
14103 return H2C_SUCCESS;
14104
14105 }
14106
createbss_hdl(_adapter * padapter,u8 * pbuf)14107 u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
14108 {
14109 #ifdef CONFIG_AP_MODE
14110 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14111 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14112 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
14113 WLAN_BSSID_EX *pdev_network = &padapter->registrypriv.dev_network;
14114 struct createbss_parm *parm = (struct createbss_parm *)pbuf;
14115 u8 ret = H2C_SUCCESS;
14116 /* u8 initialgain; */
14117 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14118 struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj);
14119
14120 if ((parm->req_ch == 0 && pmlmeinfo->state == WIFI_FW_AP_STATE)
14121 || parm->req_ch != 0
14122 ) {
14123 start_bss_network(padapter, parm);
14124 if (rfctl->ap_csa_en) {
14125 u8 enable = 0;
14126 rfctl->ap_csa_en = AP_CSA_DISABLE;
14127 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_EARLY_C2H_RPT, &enable);
14128 }
14129 goto exit;
14130 }
14131
14132 /* below is for ad-hoc master */
14133 if (parm->adhoc) {
14134 rtw_warn_on(pdev_network->InfrastructureMode != Ndis802_11IBSS);
14135 rtw_joinbss_reset(padapter);
14136
14137 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
14138 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
14139 pmlmeinfo->ERP_enable = 0;
14140 pmlmeinfo->WMM_enable = 0;
14141 pmlmeinfo->HT_enable = 0;
14142 pmlmeinfo->HT_caps_enable = 0;
14143 pmlmeinfo->HT_info_enable = 0;
14144 pmlmeinfo->agg_enable_bitmap = 0;
14145 pmlmeinfo->candidate_tid_bitmap = 0;
14146
14147 /* cancel link timer */
14148 _cancel_timer_ex(&pmlmeext->link_timer);
14149
14150 /* clear CAM */
14151 flush_all_cam_entry(padapter);
14152
14153 pdev_network->Length = get_WLAN_BSSID_EX_sz(pdev_network);
14154 _rtw_memcpy(pnetwork, pdev_network, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
14155 pnetwork->IELength = pdev_network->IELength;
14156
14157 if (pnetwork->IELength > MAX_IE_SZ) {
14158 ret = H2C_PARAMETERS_ERROR;
14159 goto ibss_post_hdl;
14160 }
14161
14162 _rtw_memcpy(pnetwork->IEs, pdev_network->IEs, pnetwork->IELength);
14163 start_create_ibss(padapter);
14164 } else {
14165 rtw_warn_on(1);
14166 ret = H2C_PARAMETERS_ERROR;
14167 }
14168
14169 ibss_post_hdl:
14170 rtw_create_ibss_post_hdl(padapter, ret);
14171
14172 exit:
14173 return ret;
14174 #else
14175 return H2C_SUCCESS;
14176 #endif /* CONFIG_AP_MODE */
14177 }
14178
join_cmd_hdl(_adapter * padapter,u8 * pbuf)14179 u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
14180 {
14181 u8 join_type;
14182 PNDIS_802_11_VARIABLE_IEs pIE;
14183 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14184 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14185 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
14186 #ifdef CONFIG_ANTENNA_DIVERSITY
14187 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
14188 #endif /* CONFIG_ANTENNA_DIVERSITY */
14189 #ifdef CONFIG_LAYER2_ROAMING
14190 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14191 struct wlan_network *rnetwork = pmlmepriv->roam_network;
14192 struct beacon_keys bcn_keys;
14193 u32 roam_ielen;
14194 _irqL irqL;
14195 #endif
14196 u32 i;
14197 /* u8 initialgain; */
14198 /* u32 acparm; */
14199 u8 u_ch, u_bw, u_offset;
14200 u8 doiqk = _FALSE;
14201
14202 /* check already connecting to AP or not */
14203 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
14204 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
14205 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
14206 pmlmeinfo->state = WIFI_FW_NULL_STATE;
14207
14208 /* clear CAM */
14209 flush_all_cam_entry(padapter);
14210
14211 _cancel_timer_ex(&pmlmeext->link_timer);
14212
14213 /* set MSR to nolink->infra. mode */
14214 /* Set_MSR(padapter, _HW_STATE_NOLINK_); */
14215 Set_MSR(padapter, _HW_STATE_STATION_);
14216
14217
14218 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
14219 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
14220 rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_DISCONNECTED);
14221 }
14222
14223 #ifdef CONFIG_ANTENNA_DIVERSITY
14224 rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
14225 #endif
14226
14227 #ifdef CONFIG_WAPI_SUPPORT
14228 rtw_wapi_clear_all_cam_entry(padapter);
14229 #endif
14230
14231 rtw_joinbss_reset(padapter);
14232
14233 pmlmeinfo->ERP_enable = 0;
14234 pmlmeinfo->WMM_enable = 0;
14235 pmlmeinfo->HT_enable = 0;
14236 pmlmeinfo->HT_caps_enable = 0;
14237 pmlmeinfo->HT_info_enable = 0;
14238 pmlmeinfo->agg_enable_bitmap = 0;
14239 pmlmeinfo->candidate_tid_bitmap = 0;
14240 pmlmeinfo->bwmode_updated = _FALSE;
14241 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
14242 pmlmeinfo->VHT_enable = 0;
14243 #ifdef ROKU_PRIVATE
14244 pmlmeinfo->ht_vht_received = 0;
14245 _rtw_memset(pmlmeinfo->SupportedRates_infra_ap, 0, NDIS_802_11_LENGTH_RATES_EX);
14246 #endif /* ROKU_PRIVATE */
14247 _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
14248 pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
14249
14250 if (pnetwork->IELength > MAX_IE_SZ) /* Check pbuf->IELength */
14251 return H2C_PARAMETERS_ERROR;
14252
14253 if (pnetwork->IELength < 2) {
14254 report_join_res(padapter, (-4), WLAN_STATUS_UNSPECIFIED_FAILURE);
14255 return H2C_SUCCESS;
14256 }
14257 _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
14258
14259 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
14260
14261 /* Check AP vendor to move rtw_joinbss_cmd() */
14262 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength); */
14263
14264 /* sizeof(NDIS_802_11_FIXED_IEs) */
14265 for (i = _FIXED_IE_LENGTH_ ; i < pnetwork->IELength - 2 ;) {
14266 pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
14267
14268 switch (pIE->ElementID) {
14269 case _VENDOR_SPECIFIC_IE_: /* Get WMM IE. */
14270 if (_rtw_memcmp(pIE->data, WMM_OUI, 4))
14271 WMM_param_handler(padapter, pIE);
14272 break;
14273
14274 #ifdef CONFIG_80211N_HT
14275 case _HT_CAPABILITY_IE_: /* Get HT Cap IE. */
14276 pmlmeinfo->HT_caps_enable = 1;
14277 break;
14278
14279 case _HT_EXTRA_INFO_IE_: /* Get HT Info IE. */
14280 pmlmeinfo->HT_info_enable = 1;
14281 break;
14282 #endif /* CONFIG_80211N_HT */
14283
14284 #ifdef CONFIG_80211AC_VHT
14285 case EID_VHTCapability: /* Get VHT Cap IE. */
14286 pmlmeinfo->VHT_enable = 1;
14287 break;
14288
14289 case EID_VHTOperation: /* Get VHT Operation IE. */
14290 break;
14291 #endif /* CONFIG_80211AC_VHT */
14292 default:
14293 break;
14294 }
14295
14296 i += (pIE->Length + 2);
14297 }
14298
14299 rtw_bss_get_chbw(pnetwork
14300 , &pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset, 1, 1);
14301
14302 rtw_adjust_chbw(padapter, pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
14303
14304 #if 0
14305 if (padapter->registrypriv.wifi_spec) {
14306 /* for WiFi test, follow WMM test plan spec */
14307 acparm = 0x002F431C; /* VO */
14308 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
14309 acparm = 0x005E541C; /* VI */
14310 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
14311 acparm = 0x0000A525; /* BE */
14312 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
14313 acparm = 0x0000A549; /* BK */
14314 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
14315
14316 /* for WiFi test, mixed mode with intel STA under bg mode throughput issue */
14317 if (padapter->mlmepriv.htpriv.ht_option == _FALSE) {
14318 acparm = 0x00004320;
14319 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
14320 }
14321 } else {
14322 acparm = 0x002F3217; /* VO */
14323 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
14324 acparm = 0x005E4317; /* VI */
14325 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
14326 acparm = 0x00105320; /* BE */
14327 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
14328 acparm = 0x0000A444; /* BK */
14329 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
14330 }
14331 #endif
14332
14333 /* check channel, bandwidth, offset and switch */
14334 if (rtw_chk_start_clnt_join(padapter, &u_ch, &u_bw, &u_offset) == _FAIL) {
14335 report_join_res(padapter, (-4), WLAN_STATUS_UNSPECIFIED_FAILURE);
14336 return H2C_SUCCESS;
14337 }
14338
14339 /* disable dynamic functions, such as high power, DIG */
14340 /*rtw_phydm_func_disable_all(padapter);*/
14341
14342 /* config the initial gain under linking, need to write the BB registers */
14343 /* initialgain = 0x1E; */
14344 /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
14345
14346 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
14347 if (MLME_IS_STA(padapter))
14348 rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_CONNECTING);
14349 else
14350 rtw_hal_rcr_set_chk_bssid(padapter, MLME_ADHOC_STARTED);
14351
14352 join_type = 0;
14353 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
14354
14355 rtw_btcoex_connect_notify(padapter, join_type);
14356
14357 doiqk = _TRUE;
14358 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
14359
14360 set_channel_bwmode(padapter, u_ch, u_offset, u_bw);
14361
14362 doiqk = _FALSE;
14363 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
14364
14365 /* cancel link timer */
14366 _cancel_timer_ex(&pmlmeext->link_timer);
14367
14368 start_clnt_join(padapter);
14369
14370 #ifdef CONFIG_LAYER2_ROAMING
14371 _enter_critical_bh(&pmlmepriv->clnt_auth_lock, &irqL);
14372 if (rnetwork && (pmlmeinfo->state & (WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE))
14373 #ifdef CONFIG_RTW_80211R
14374 && (!rtw_ft_roam(padapter))
14375 #endif
14376 ) {
14377 struct beacon_keys bcn_keys;
14378 u32 roam_ielen;
14379
14380 roam_ielen = rnetwork->network.IELength;
14381 update_network(&(pmlmepriv->cur_network.network), &(rnetwork->network), padapter, _TRUE);
14382
14383 /* update bcn keys */
14384 if (rtw_get_bcn_keys_from_bss(&rnetwork->network, &bcn_keys) == _TRUE) {
14385 _rtw_memcpy(&pmlmepriv->cur_beacon_keys, &bcn_keys, sizeof(bcn_keys));
14386 if (is_hidden_ssid(bcn_keys.ssid, bcn_keys.ssid_len)) {
14387 _rtw_memcpy(pmlmepriv->cur_beacon_keys.ssid, pmlmeinfo->network.Ssid.Ssid, IW_ESSID_MAX_SIZE);
14388 pmlmepriv->cur_beacon_keys.ssid_len = pmlmeinfo->network.Ssid.SsidLength;
14389 }
14390 } else {
14391 RTW_ERR("%s: get beacon keys failed\n", __func__);
14392 _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(bcn_keys));
14393 }
14394 #ifdef CONFIG_BCN_CNT_CONFIRM_HDL
14395 pmlmepriv->new_beacon_cnts = 0;
14396 #endif
14397
14398 /* check the vendor of the assoc AP */
14399 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(rnetwork->network.IEs, rnetwork->network.IELength);
14400 rtw_phydm_update_ap_vendor_ie(padapter);
14401
14402 /* update TSF Value */
14403 pmlmeext->TSFValue = rnetwork->network.tsf + rtw_get_passing_time_ms(rnetwork->last_scanned)*1000;
14404 pmlmeext->bcn_cnt = 0;
14405 pmlmeext->last_bcn_cnt = 0;
14406 /* start auth */
14407 start_clnt_auth(padapter);
14408 }
14409 _exit_critical_bh(&pmlmepriv->clnt_auth_lock, &irqL);
14410 #endif
14411 return H2C_SUCCESS;
14412
14413 }
14414
disconnect_hdl(_adapter * padapter,unsigned char * pbuf)14415 u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
14416 {
14417 #if CONFIG_DFS
14418 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
14419 #endif
14420 struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
14421 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14422 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14423 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
14424 u8 val8;
14425
14426 if (is_client_associated_to_ap(padapter)
14427 #if CONFIG_DFS
14428 && !IS_RADAR_DETECTED(rfctl) && !rfctl->csa_ch
14429 #endif
14430 ) {
14431 #ifdef CONFIG_PLATFORM_ROCKCHIPS
14432 /* To avoid connecting to AP fail during resume process, change retry count from 5 to 1 */
14433 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
14434 #else
14435 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms / 100, 100);
14436 #endif /* CONFIG_PLATFORM_ROCKCHIPS */
14437 }
14438
14439 #ifndef CONFIG_SUPPORT_MULTI_BCN
14440 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
14441 /* Stop BCN */
14442 val8 = 0;
14443 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
14444 }
14445 #endif
14446
14447 rtw_sta_mstatus_report(padapter);
14448
14449 rtw_mlmeext_disconnect(padapter);
14450
14451 rtw_free_uc_swdec_pending_queue(padapter);
14452
14453 return H2C_SUCCESS;
14454 }
14455
14456 static const char *const _scan_state_str[] = {
14457 "SCAN_DISABLE",
14458 "SCAN_START",
14459 "SCAN_PS_ANNC_WAIT",
14460 "SCAN_ENTER",
14461 "SCAN_PROCESS",
14462 "SCAN_BACKING_OP",
14463 "SCAN_BACK_OP",
14464 "SCAN_LEAVING_OP",
14465 "SCAN_LEAVE_OP",
14466 "SCAN_SW_ANTDIV_BL",
14467 "SCAN_TO_P2P_LISTEN",
14468 "SCAN_P2P_LISTEN",
14469 "SCAN_COMPLETE",
14470 "SCAN_STATE_MAX",
14471 };
14472
scan_state_str(u8 state)14473 const char *scan_state_str(u8 state)
14474 {
14475 state = (state >= SCAN_STATE_MAX) ? SCAN_STATE_MAX : state;
14476 return _scan_state_str[state];
14477 }
14478
scan_abort_hdl(_adapter * adapter)14479 static bool scan_abort_hdl(_adapter *adapter)
14480 {
14481 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
14482 struct ss_res *ss = &pmlmeext->sitesurvey_res;
14483 #ifdef CONFIG_P2P
14484 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
14485 #endif
14486 bool ret = _FALSE;
14487
14488 if (pmlmeext->scan_abort == _TRUE) {
14489 #ifdef CONFIG_P2P
14490 if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
14491 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
14492 ss->channel_idx = 3;
14493 RTW_INFO("%s idx:%d, cnt:%u\n", __FUNCTION__
14494 , ss->channel_idx
14495 , pwdinfo->find_phase_state_exchange_cnt
14496 );
14497 } else
14498 #endif
14499 {
14500 ss->channel_idx = ss->ch_num;
14501 RTW_INFO("%s idx:%d\n", __FUNCTION__
14502 , ss->channel_idx
14503 );
14504 }
14505 ret = _TRUE;
14506 }
14507
14508 return ret;
14509 }
14510
rtw_scan_sparse(_adapter * adapter,struct rtw_ieee80211_channel * ch,u8 ch_num)14511 u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num)
14512 {
14513 /* interval larger than this is treated as backgroud scan */
14514 #ifndef RTW_SCAN_SPARSE_BG_INTERVAL_MS
14515 #define RTW_SCAN_SPARSE_BG_INTERVAL_MS 12000
14516 #endif
14517
14518 #ifndef RTW_SCAN_SPARSE_CH_NUM_MIRACAST
14519 #define RTW_SCAN_SPARSE_CH_NUM_MIRACAST 1
14520 #endif
14521 #ifndef RTW_SCAN_SPARSE_CH_NUM_BG
14522 #define RTW_SCAN_SPARSE_CH_NUM_BG 4
14523 #endif
14524
14525 #define SCAN_SPARSE_CH_NUM_INVALID 255
14526
14527 static u8 token = 255;
14528 u32 interval;
14529 bool busy_traffic = _FALSE;
14530 bool miracast_enabled = _FALSE;
14531 bool bg_scan = _FALSE;
14532 u8 max_allow_ch = SCAN_SPARSE_CH_NUM_INVALID;
14533 u8 scan_division_num;
14534 u8 ret_num = ch_num;
14535 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
14536
14537 if (mlmeext->last_scan_time == 0)
14538 mlmeext->last_scan_time = rtw_get_current_time();
14539
14540 interval = rtw_get_passing_time_ms(mlmeext->last_scan_time);
14541
14542
14543 if (rtw_mi_busy_traffic_check(adapter))
14544 busy_traffic = _TRUE;
14545
14546 if (rtw_mi_check_miracast_enabled(adapter))
14547 miracast_enabled = _TRUE;
14548
14549 if (interval > RTW_SCAN_SPARSE_BG_INTERVAL_MS)
14550 bg_scan = _TRUE;
14551
14552 /* max_allow_ch by conditions*/
14553
14554 #if RTW_SCAN_SPARSE_MIRACAST
14555 if (miracast_enabled == _TRUE && busy_traffic == _TRUE)
14556 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_MIRACAST);
14557 #endif
14558
14559 #if RTW_SCAN_SPARSE_BG
14560 if (bg_scan == _TRUE)
14561 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG);
14562 #endif
14563
14564 if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) {
14565 int i;
14566 int k = 0;
14567
14568 scan_division_num = (ch_num / max_allow_ch) + ((ch_num % max_allow_ch) ? 1 : 0);
14569 token = (token + 1) % scan_division_num;
14570
14571 if (0)
14572 RTW_INFO("scan_division_num:%u, token:%u\n", scan_division_num, token);
14573
14574 for (i = 0; i < ch_num; i++) {
14575 if (ch[i].hw_value && (i % scan_division_num) == token
14576 ) {
14577 if (i != k)
14578 _rtw_memcpy(&ch[k], &ch[i], sizeof(struct rtw_ieee80211_channel));
14579 k++;
14580 }
14581 }
14582
14583 _rtw_memset(&ch[k], 0, sizeof(struct rtw_ieee80211_channel));
14584
14585 ret_num = k;
14586 mlmeext->last_scan_time = rtw_get_current_time();
14587 }
14588
14589 return ret_num;
14590 }
14591
14592 #ifdef CONFIG_SCAN_BACKOP
rtw_scan_backop_decision(_adapter * adapter)14593 u8 rtw_scan_backop_decision(_adapter *adapter)
14594 {
14595 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
14596 struct mi_state mstate;
14597 u8 backop_flags = 0;
14598
14599 rtw_mi_status(adapter, &mstate);
14600
14601 if ((MSTATE_STA_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_sta(mlmeext, SS_BACKOP_EN))
14602 || (MSTATE_STA_NUM(&mstate) && mlmeext_chk_scan_backop_flags_sta(mlmeext, SS_BACKOP_EN_NL)))
14603 backop_flags |= mlmeext_scan_backop_flags_sta(mlmeext);
14604
14605 #ifdef CONFIG_AP_MODE
14606 if ((MSTATE_AP_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_ap(mlmeext, SS_BACKOP_EN))
14607 || (MSTATE_AP_NUM(&mstate) && mlmeext_chk_scan_backop_flags_ap(mlmeext, SS_BACKOP_EN_NL)))
14608 backop_flags |= mlmeext_scan_backop_flags_ap(mlmeext);
14609 #endif
14610
14611 #ifdef CONFIG_RTW_MESH
14612 if ((MSTATE_MESH_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_mesh(mlmeext, SS_BACKOP_EN))
14613 || (MSTATE_MESH_NUM(&mstate) && mlmeext_chk_scan_backop_flags_mesh(mlmeext, SS_BACKOP_EN_NL)))
14614 backop_flags |= mlmeext_scan_backop_flags_mesh(mlmeext);
14615 #endif
14616
14617 return backop_flags;
14618 }
14619 #endif
14620
14621 #define SCANNING_TIMEOUT_EX 2000
rtw_scan_timeout_decision(_adapter * padapter)14622 u32 rtw_scan_timeout_decision(_adapter *padapter)
14623 {
14624 u32 back_op_times= 0;
14625 u8 max_chan_num;
14626 u16 scan_ms;
14627 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14628 struct ss_res *ss = &pmlmeext->sitesurvey_res;
14629
14630 if (is_supported_5g(padapter->registrypriv.wireless_mode)
14631 && IsSupported24G(padapter->registrypriv.wireless_mode))
14632 max_chan_num = MAX_CHANNEL_NUM_2G_5G;/* dual band */
14633 else
14634 max_chan_num = MAX_CHANNEL_NUM_2G;/*single band*/
14635
14636 #ifdef CONFIG_SCAN_BACKOP
14637 if (rtw_scan_backop_decision(padapter))
14638 back_op_times = (max_chan_num / ss->scan_cnt_max) * ss->backop_ms;
14639 #endif
14640
14641 if (ss->duration)
14642 scan_ms = ss->duration;
14643 else
14644 #if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
14645 if (IS_ACS_ENABLE(padapter) && rtw_is_acs_st_valid(padapter))
14646 scan_ms = rtw_acs_get_adv_st(padapter);
14647 else
14648 #endif /*CONFIG_RTW_ACS*/
14649 scan_ms = ss->scan_ch_ms;
14650
14651 ss->scan_timeout_ms = (scan_ms * max_chan_num) + back_op_times + SCANNING_TIMEOUT_EX;
14652 #ifdef DBG_SITESURVEY
14653 RTW_INFO("%s , scan_timeout_ms = %d (ms)\n", __func__, ss->scan_timeout_ms);
14654 #endif /*DBG_SITESURVEY*/
14655 return ss->scan_timeout_ms;
14656 }
14657
rtw_scan_ch_decision(_adapter * padapter,struct rtw_ieee80211_channel * out,u32 out_num,struct rtw_ieee80211_channel * in,u32 in_num,bool no_sparse,int reason)14658 static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
14659 u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num, bool no_sparse, int reason)
14660 {
14661 int i, j;
14662 int set_idx;
14663 u8 chan;
14664 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
14665 struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(padapter));
14666 #ifdef CONFIG_RTW_ROAM_QUICKSCAN
14667 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14668 #endif
14669
14670 /* clear first */
14671 _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel) * out_num);
14672
14673 #ifdef CONFIG_RTW_ROAM_QUICKSCAN
14674 if ((reason == RTW_AUTO_SCAN_REASON_ROAM) && (pmlmeext->quickscan_next)) {
14675 pmlmeext->quickscan_next = _FALSE;
14676 _rtw_memcpy(out, pmlmeext->roam_ch, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
14677 return pmlmeext->roam_ch_num;
14678 }
14679 #endif
14680
14681 /* acquire channels from in */
14682 j = 0;
14683 for (i = 0; i < in_num; i++) {
14684
14685 if (0)
14686 RTW_INFO(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
14687
14688 if (!in[i].hw_value || (in[i].flags & RTW_IEEE80211_CHAN_DISABLED))
14689 continue;
14690 if (rtw_mlme_band_check(padapter, in[i].hw_value) == _FALSE)
14691 continue;
14692
14693 set_idx = rtw_chset_search_ch(rfctl->channel_set, in[i].hw_value);
14694 if (set_idx >= 0) {
14695 if (j >= out_num) {
14696 RTW_PRINT(FUNC_ADPT_FMT" out_num:%u not enough\n",
14697 FUNC_ADPT_ARG(padapter), out_num);
14698 break;
14699 }
14700
14701 _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
14702
14703 if (rfctl->channel_set[set_idx].flags & (RTW_CHF_NO_IR | RTW_CHF_DFS))
14704 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
14705
14706 j++;
14707 }
14708 if (j >= out_num)
14709 break;
14710 }
14711
14712 /* if out is empty, use channel_set as default */
14713 if (j == 0) {
14714 for (i = 0; i < rfctl->max_chan_nums; i++) {
14715 chan = rfctl->channel_set[i].ChannelNum;
14716 if (rtw_mlme_band_check(padapter, chan) == _TRUE) {
14717 if (rtw_mlme_ignore_chan(padapter, chan) == _TRUE)
14718 continue;
14719
14720 if (0)
14721 RTW_INFO(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), chan);
14722
14723 if (j >= out_num) {
14724 RTW_PRINT(FUNC_ADPT_FMT" out_num:%u not enough\n",
14725 FUNC_ADPT_ARG(padapter), out_num);
14726 break;
14727 }
14728
14729 out[j].hw_value = chan;
14730
14731 if (rfctl->channel_set[i].flags & (RTW_CHF_NO_IR | RTW_CHF_DFS))
14732 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
14733
14734 j++;
14735 }
14736 }
14737 }
14738
14739 if (!no_sparse
14740 && !regsty->wifi_spec
14741 && j > 6 /* assume ch_num > 6 is normal scan */
14742 ) {
14743 /* scan_sparse */
14744 j = rtw_scan_sparse(padapter, out, j);
14745 }
14746
14747 return j;
14748 }
14749
sitesurvey_res_reset(_adapter * adapter,struct sitesurvey_parm * parm)14750 static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm)
14751 {
14752 struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
14753 RT_CHANNEL_INFO *chset = adapter_to_chset(adapter);
14754 int i, reason = 0;
14755
14756 ss->bss_cnt = 0;
14757 ss->activate_ch_cnt = 0;
14758 ss->channel_idx = 0;
14759 ss->force_ssid_scan = 0;
14760 ss->igi_scan = 0;
14761 ss->igi_before_scan = 0;
14762 #ifdef CONFIG_SCAN_BACKOP
14763 ss->scan_cnt = 0;
14764 #endif
14765 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14766 ss->is_sw_antdiv_bl_scan = 0;
14767 #endif
14768 ss->ssid_num = 0;
14769 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
14770 if (parm->ssid[i].SsidLength) {
14771 _rtw_memcpy(ss->ssid[i].Ssid, parm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
14772 ss->ssid[i].SsidLength = parm->ssid[i].SsidLength;
14773 ss->ssid_num++;
14774 } else
14775 ss->ssid[i].SsidLength = 0;
14776 }
14777 reason = parm->reason;
14778 ss->ch_num = rtw_scan_ch_decision(adapter
14779 , ss->ch, RTW_CHANNEL_SCAN_AMOUNT
14780 , parm->ch, parm->ch_num
14781 , parm->acs
14782 , reason
14783 );
14784
14785 for (i = 0; i < MAX_CHANNEL_NUM; i++)
14786 chset[i].hidden_bss_cnt = 0;
14787
14788 ss->bw = parm->bw;
14789 ss->igi = parm->igi;
14790 ss->token = parm->token;
14791 ss->duration = parm->duration;
14792 ss->scan_mode = parm->scan_mode;
14793 ss->token = parm->token;
14794 ss->acs = parm->acs;
14795 }
14796
sitesurvey_pick_ch_behavior(_adapter * padapter,u8 * ch,RT_SCAN_TYPE * type)14797 static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE *type)
14798 {
14799 u8 next_state;
14800 u8 scan_ch = 0;
14801 RT_SCAN_TYPE scan_type = SCAN_PASSIVE;
14802 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14803 struct ss_res *ss = &pmlmeext->sitesurvey_res;
14804 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
14805 int ch_set_idx;
14806 #ifdef CONFIG_P2P
14807 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
14808 #endif
14809 #ifdef CONFIG_SCAN_BACKOP
14810 u8 backop_flags = 0;
14811 #endif
14812
14813 /* handle scan abort request */
14814 scan_abort_hdl(padapter);
14815
14816 #ifdef CONFIG_P2P
14817 if (pwdinfo->rx_invitereq_info.scan_op_ch_only || pwdinfo->p2p_info.scan_op_ch_only) {
14818 if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
14819 scan_ch = pwdinfo->rx_invitereq_info.operation_ch[ss->channel_idx];
14820 else
14821 scan_ch = pwdinfo->p2p_info.operation_ch[ss->channel_idx];
14822 scan_type = SCAN_ACTIVE;
14823 } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
14824 /*
14825 * Commented by Albert 2011/06/03
14826 * The driver is in the find phase, it should go through the social channel.
14827 */
14828 scan_ch = pwdinfo->social_chan[ss->channel_idx];
14829 ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, scan_ch);
14830 if (ch_set_idx >= 0)
14831 scan_type = rfctl->channel_set[ch_set_idx].flags & RTW_CHF_NO_IR ? SCAN_PASSIVE : SCAN_ACTIVE;
14832 else
14833 scan_type = SCAN_ACTIVE;
14834 } else
14835 #endif /* CONFIG_P2P */
14836 {
14837 struct rtw_ieee80211_channel *ch;
14838
14839 #ifdef CONFIG_SCAN_BACKOP
14840 backop_flags = rtw_scan_backop_decision(padapter);
14841 #endif
14842
14843 #ifdef CONFIG_SCAN_BACKOP
14844 if (!(backop_flags && ss->scan_cnt >= ss->scan_cnt_max))
14845 #endif
14846 {
14847 #ifdef CONFIG_RTW_WIFI_HAL
14848 if (adapter_to_dvobj(padapter)->nodfs) {
14849 while (ss->channel_idx < ss->ch_num && rtw_chset_is_dfs_ch(rfctl->channel_set, ss->ch[ss->channel_idx].hw_value))
14850 ss->channel_idx++;
14851 } else
14852 #endif
14853 if (ss->channel_idx != 0 && ss->force_ssid_scan == 0
14854 && pmlmeext->sitesurvey_res.ssid_num
14855 && (ss->ch[ss->channel_idx - 1].flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN)
14856 ) {
14857 ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, ss->ch[ss->channel_idx - 1].hw_value);
14858 if (ch_set_idx != -1 && rfctl->channel_set[ch_set_idx].hidden_bss_cnt
14859 && (!IS_DFS_SLAVE_WITH_RD(rfctl)
14860 || rtw_rfctl_dfs_domain_unknown(rfctl)
14861 || !CH_IS_NON_OCP(&rfctl->channel_set[ch_set_idx]))
14862 ) {
14863 ss->channel_idx--;
14864 ss->force_ssid_scan = 1;
14865 }
14866 } else
14867 ss->force_ssid_scan = 0;
14868 }
14869
14870 if (ss->channel_idx < ss->ch_num) {
14871 ch = &ss->ch[ss->channel_idx];
14872 scan_ch = ch->hw_value;
14873
14874 #if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
14875 if (IS_ACS_ENABLE(padapter) && rtw_is_acs_passiv_scan(padapter))
14876 scan_type = SCAN_PASSIVE;
14877 else
14878 #endif /*CONFIG_RTW_ACS*/
14879 scan_type = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
14880 }
14881 }
14882
14883 if (scan_ch != 0) {
14884 next_state = SCAN_PROCESS;
14885
14886 #ifdef CONFIG_SCAN_BACKOP
14887 if (backop_flags) {
14888 if (ss->scan_cnt < ss->scan_cnt_max)
14889 ss->scan_cnt++;
14890 else {
14891 mlmeext_assign_scan_backop_flags(pmlmeext, backop_flags);
14892 next_state = SCAN_BACKING_OP;
14893 }
14894 }
14895 #endif
14896
14897 } else if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
14898 /* go p2p listen */
14899 next_state = SCAN_TO_P2P_LISTEN;
14900
14901 #ifdef CONFIG_ANTENNA_DIVERSITY
14902 } else if (rtw_hal_antdiv_before_linked(padapter)) {
14903 /* go sw antdiv before link */
14904 next_state = SCAN_SW_ANTDIV_BL;
14905 #endif
14906 } else {
14907 next_state = SCAN_COMPLETE;
14908
14909 #if defined(DBG_SCAN_SW_ANTDIV_BL)
14910 {
14911 /* for SCAN_SW_ANTDIV_BL state testing */
14912 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14913 int i;
14914 bool is_linked = _FALSE;
14915
14916 for (i = 0; i < dvobj->iface_nums; i++) {
14917 if (rtw_linked_check(dvobj->padapters[i]))
14918 is_linked = _TRUE;
14919 }
14920
14921 if (!is_linked) {
14922 static bool fake_sw_antdiv_bl_state = 0;
14923
14924 if (fake_sw_antdiv_bl_state == 0) {
14925 next_state = SCAN_SW_ANTDIV_BL;
14926 fake_sw_antdiv_bl_state = 1;
14927 } else
14928 fake_sw_antdiv_bl_state = 0;
14929 }
14930 }
14931 #endif /* defined(DBG_SCAN_SW_ANTDIV_BL) */
14932 }
14933
14934 #ifdef CONFIG_SCAN_BACKOP
14935 if (next_state != SCAN_PROCESS)
14936 ss->scan_cnt = 0;
14937 #endif
14938
14939
14940 #ifdef DBG_FIXED_CHAN
14941 if (pmlmeext->fixed_chan != 0xff && next_state == SCAN_PROCESS)
14942 scan_ch = pmlmeext->fixed_chan;
14943 #endif
14944
14945 if (ch)
14946 *ch = scan_ch;
14947 if (type)
14948 *type = scan_type;
14949
14950 return next_state;
14951 }
14952
site_survey(_adapter * padapter,u8 survey_channel,RT_SCAN_TYPE ScanType)14953 void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType)
14954 {
14955 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14956 struct ss_res *ss = &pmlmeext->sitesurvey_res;
14957 u8 ssid_scan = 0;
14958
14959 #ifdef CONFIG_P2P
14960 #ifndef CONFIG_IOCTL_CFG80211
14961 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
14962 #endif
14963 #endif
14964
14965 if (survey_channel != 0) {
14966 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
14967
14968 if (ScanType == SCAN_PASSIVE && ss->force_ssid_scan)
14969 ssid_scan = 1;
14970 else if (ScanType == SCAN_ACTIVE) {
14971 #ifdef CONFIG_P2P
14972 #ifdef CONFIG_IOCTL_CFG80211
14973 if (rtw_cfg80211_is_p2p_scan(padapter))
14974 #else
14975 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
14976 || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
14977 #endif
14978 {
14979 issue_probereq_p2p(padapter, NULL);
14980 issue_probereq_p2p(padapter, NULL);
14981 issue_probereq_p2p(padapter, NULL);
14982 } else
14983 #endif /* CONFIG_P2P */
14984 {
14985 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
14986 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
14987 if (padapter->registrypriv.wifi_spec)
14988 issue_probereq(padapter, NULL, NULL);
14989 else
14990 issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
14991 issue_probereq(padapter, NULL, NULL);
14992 }
14993
14994 ssid_scan = 1;
14995 }
14996 }
14997
14998 if (ssid_scan) {
14999 int i;
15000
15001 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
15002 if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
15003 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
15004 if (padapter->registrypriv.wifi_spec)
15005 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
15006 else
15007 issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
15008 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
15009 }
15010 }
15011 }
15012 } else {
15013 /* channel number is 0 or this channel is not valid. */
15014 rtw_warn_on(1);
15015 }
15016
15017 return;
15018 }
15019
survey_done_set_ch_bw(_adapter * padapter)15020 void survey_done_set_ch_bw(_adapter *padapter)
15021 {
15022 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15023 u8 cur_channel = 0;
15024 u8 cur_bwmode;
15025 u8 cur_ch_offset;
15026
15027 #ifdef CONFIG_MCC_MODE
15028 if (!rtw_hal_mcc_change_scan_flag(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset)) {
15029 if (0)
15030 RTW_INFO(FUNC_ADPT_FMT" back to AP channel - ch:%u, bw:%u, offset:%u\n",
15031 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
15032 goto exit;
15033 }
15034 #endif
15035
15036 if (rtw_mi_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0) {
15037 if (0)
15038 RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
15039 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
15040 } else {
15041 #ifdef CONFIG_P2P
15042 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
15043 _adapter *iface;
15044 int i;
15045
15046 for (i = 0; i < dvobj->iface_nums; i++) {
15047 iface = dvobj->padapters[i];
15048 if (!iface)
15049 continue;
15050
15051 #ifdef CONFIG_IOCTL_CFG80211
15052 if (iface->wdinfo.driver_interface == DRIVER_CFG80211 && !adapter_wdev_data(iface)->p2p_enabled)
15053 continue;
15054 #endif
15055
15056 if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN)) {
15057 cur_channel = iface->wdinfo.listen_channel;
15058 cur_bwmode = CHANNEL_WIDTH_20;
15059 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15060 if (0)
15061 RTW_INFO(FUNC_ADPT_FMT" back to "ADPT_FMT"'s listen ch - ch:%u, bw:%u, offset:%u\n",
15062 FUNC_ADPT_ARG(padapter), ADPT_ARG(iface), cur_channel, cur_bwmode, cur_ch_offset);
15063 break;
15064 }
15065 }
15066 #endif /* CONFIG_P2P */
15067
15068 if (cur_channel == 0) {
15069 cur_channel = pmlmeext->cur_channel;
15070 cur_bwmode = pmlmeext->cur_bwmode;
15071 cur_ch_offset = pmlmeext->cur_ch_offset;
15072 if (0)
15073 RTW_INFO(FUNC_ADPT_FMT" back to ch:%u, bw:%u, offset:%u\n",
15074 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
15075 }
15076 }
15077 #ifdef CONFIG_MCC_MODE
15078 exit:
15079 #endif
15080 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
15081 }
15082
15083 /**
15084 * rtw_ps_annc - check and doing ps announcement for all the adapters
15085 * @adapter: the requesting adapter
15086 * @ps: power saving or not
15087 *
15088 * Returns: 0: no ps announcement is doing. 1: ps announcement is doing
15089 */
rtw_ps_annc(_adapter * adapter,bool ps)15090 u8 rtw_ps_annc(_adapter *adapter, bool ps)
15091 {
15092 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15093 _adapter *iface;
15094 int i;
15095 u8 ps_anc = 0;
15096
15097 for (i = 0; i < dvobj->iface_nums; i++) {
15098 iface = dvobj->padapters[i];
15099 if (!iface)
15100 continue;
15101
15102 if (MLME_IS_STA(iface)) {
15103 if (is_client_associated_to_ap(iface) == _TRUE) {
15104 /* TODO: TDLS peers */
15105 #ifdef CONFIG_MCC_MODE
15106 /* for two station case */
15107 if (MCC_EN(adapter) && rtw_hal_check_mcc_status(adapter, MCC_STATUS_NEED_MCC)) {
15108 u8 ch = iface->mlmeextpriv.cur_channel;
15109 u8 offset = iface->mlmeextpriv.cur_ch_offset;
15110 u8 bw = iface->mlmeextpriv.cur_bwmode;
15111
15112 set_channel_bwmode(iface, ch, offset, bw);
15113 }
15114 #endif /* CONFIG_MCC_MODE */
15115 issue_nulldata(iface, NULL, ps, 3, 500);
15116 ps_anc = 1;
15117 }
15118 #ifdef CONFIG_RTW_MESH
15119 } else if (MLME_IS_MESH(iface)) {
15120 if (rtw_mesh_ps_annc(iface, ps))
15121 ps_anc = 1;
15122 #endif
15123 }
15124 }
15125 return ps_anc;
15126 }
15127
rtw_leave_opch(_adapter * adapter)15128 void rtw_leave_opch(_adapter *adapter)
15129 {
15130 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
15131
15132 #ifdef CONFIG_MCC_MODE
15133 if (MCC_EN(adapter) && rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))
15134 return;
15135 #endif
15136
15137 _enter_critical_mutex(&rfctl->offch_mutex, NULL);
15138
15139 if (rfctl->offch_state == OFFCHS_NONE) {
15140 /* prepare to leave operating channel */
15141 rfctl->offch_state = OFFCHS_LEAVING_OP;
15142
15143 /* clear HW TX queue */
15144 rtw_hal_set_hwreg(adapter, HW_VAR_CHECK_TXBUF, 0);
15145
15146 rtw_hal_macid_sleep_all_used(adapter);
15147
15148 rtw_ps_annc(adapter, 1);
15149
15150 rfctl->offch_state = OFFCHS_LEAVE_OP;
15151 }
15152
15153 _exit_critical_mutex(&rfctl->offch_mutex, NULL);
15154 }
15155
rtw_back_opch(_adapter * adapter)15156 void rtw_back_opch(_adapter *adapter)
15157 {
15158 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
15159
15160 #ifdef CONFIG_MCC_MODE
15161 if (MCC_EN(adapter) && rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))
15162 return;
15163 #endif
15164
15165 _enter_critical_mutex(&rfctl->offch_mutex, NULL);
15166
15167 if (rfctl->offch_state != OFFCHS_NONE) {
15168 rfctl->offch_state = OFFCHS_BACKING_OP;
15169 rtw_hal_macid_wakeup_all_used(adapter);
15170 rtw_ps_annc(adapter, 0);
15171
15172 rfctl->offch_state = OFFCHS_NONE;
15173 rtw_mi_os_xmit_schedule(adapter);
15174 }
15175
15176 _exit_critical_mutex(&rfctl->offch_mutex, NULL);
15177 }
15178
sitesurvey_set_igi(_adapter * adapter)15179 void sitesurvey_set_igi(_adapter *adapter)
15180 {
15181 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
15182 struct ss_res *ss = &mlmeext->sitesurvey_res;
15183 u8 igi;
15184 #ifdef CONFIG_P2P
15185 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
15186 #endif
15187
15188 switch (mlmeext_scan_state(mlmeext)) {
15189 case SCAN_ENTER:
15190 #ifdef CONFIG_P2P
15191 #ifdef CONFIG_IOCTL_CFG80211
15192 if (pwdinfo->driver_interface == DRIVER_CFG80211 && rtw_cfg80211_is_p2p_scan(adapter))
15193 igi = 0x30;
15194 else
15195 #endif /* CONFIG_IOCTL_CFG80211 */
15196 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
15197 igi = 0x28;
15198 else
15199 #endif /* CONFIG_P2P */
15200
15201 if (ss->igi)
15202 igi = ss->igi;
15203 else
15204 #if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
15205 if (IS_ACS_ENABLE(adapter) && rtw_is_acs_igi_valid(adapter))
15206 igi = rtw_acs_get_adv_igi(adapter);
15207 else
15208 #endif /*CONFIG_RTW_ACS*/
15209 igi = 0x1e;
15210
15211 /* record IGI status */
15212 ss->igi_scan = igi;
15213 rtw_hal_get_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &ss->igi_before_scan, NULL);
15214
15215 /* disable DIG and set IGI for scan */
15216 rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
15217 break;
15218 case SCAN_COMPLETE:
15219 case SCAN_TO_P2P_LISTEN:
15220 /* enable DIG and restore IGI */
15221 igi = 0xff;
15222 rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
15223 break;
15224 #ifdef CONFIG_SCAN_BACKOP
15225 case SCAN_BACKING_OP:
15226 /* write IGI for op channel when DIG is not enabled */
15227 odm_write_dig(adapter_to_phydm(adapter), ss->igi_before_scan);
15228 break;
15229 case SCAN_LEAVE_OP:
15230 /* write IGI for scan when DIG is not enabled */
15231 odm_write_dig(adapter_to_phydm(adapter), ss->igi_scan);
15232 break;
15233 #endif /* CONFIG_SCAN_BACKOP */
15234 default:
15235 rtw_warn_on(1);
15236 break;
15237 }
15238 }
sitesurvey_set_msr(_adapter * adapter,bool enter)15239 void sitesurvey_set_msr(_adapter *adapter, bool enter)
15240 {
15241 u8 network_type;
15242 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
15243 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15244
15245 if (enter) {
15246 #ifdef CONFIG_MI_WITH_MBSSID_CAM
15247 rtw_hal_get_hwreg(adapter, HW_VAR_MEDIA_STATUS, (u8 *)(&pmlmeinfo->hw_media_state));
15248 #endif
15249 /* set MSR to no link state */
15250 network_type = _HW_STATE_NOLINK_;
15251 } else {
15252 #ifdef CONFIG_MI_WITH_MBSSID_CAM
15253 network_type = pmlmeinfo->hw_media_state;
15254 #else
15255 network_type = pmlmeinfo->state & 0x3;
15256 #endif
15257 }
15258 Set_MSR(adapter, network_type);
15259 }
15260
sitesurvey_set_offch_state(_adapter * adapter,u8 scan_state)15261 void sitesurvey_set_offch_state(_adapter *adapter, u8 scan_state)
15262 {
15263 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
15264
15265 _enter_critical_mutex(&rfctl->offch_mutex, NULL);
15266
15267 switch (scan_state) {
15268 case SCAN_DISABLE:
15269 case SCAN_BACK_OP:
15270 rfctl->offch_state = OFFCHS_NONE;
15271 break;
15272 case SCAN_START:
15273 case SCAN_LEAVING_OP:
15274 rfctl->offch_state = OFFCHS_LEAVING_OP;
15275 break;
15276 case SCAN_ENTER:
15277 case SCAN_LEAVE_OP:
15278 rfctl->offch_state = OFFCHS_LEAVE_OP;
15279 break;
15280 case SCAN_COMPLETE:
15281 case SCAN_BACKING_OP:
15282 rfctl->offch_state = OFFCHS_BACKING_OP;
15283 break;
15284 default:
15285 break;
15286 }
15287
15288 _exit_critical_mutex(&rfctl->offch_mutex, NULL);
15289 }
15290
15291 #ifdef CONFIG_RTW_ROAM_QUICKSCAN
15292 extern inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b);
15293 extern int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork);
generate_quickss(_adapter * padapter)15294 void generate_quickss(_adapter *padapter)
15295 {
15296 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
15297 struct wlan_network *pnetwork = NULL;
15298 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15299 struct rtw_ieee80211_channel *roam_ch = pmlmeext->roam_ch;
15300 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
15301 int chan;
15302 _irqL irqL;
15303 _list *plist, *phead;
15304 u8 *target_ssid=NULL, *ssid=NULL, ds_cfg, j, ch_num;
15305 u32 target_ssid_len=0, ssid_len=0;
15306 u8 mark[166];
15307
15308 target_ssid = pmlmepriv->cur_network.network.Ssid.Ssid;
15309 target_ssid_len = pmlmepriv->cur_network.network.Ssid.SsidLength;
15310 _rtw_memset(mark, 0, sizeof(u8)*166);
15311
15312 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
15313 phead = get_list_head(&(pmlmepriv->scanned_queue));
15314 if (!phead) {
15315 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
15316 return;
15317 }
15318 plist = get_next(phead);
15319 if (!plist) {
15320 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
15321 return;
15322 }
15323 while (1) {
15324 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
15325 break;
15326
15327 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
15328 if (!pnetwork)
15329 break;
15330
15331 ds_cfg = pnetwork->network.Configuration.DSConfig;
15332 if (is_same_ess(&pnetwork->network, &pmlmepriv->cur_network.network) &&
15333 rtw_is_desired_network(padapter, pnetwork))
15334 mark[ds_cfg] = 1;
15335
15336 plist = get_next(plist);
15337 }
15338 /* ex: assume roaming channel=1/6/40/165, then mark[1]/[6]/[40]/[165] are 1. */
15339 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
15340
15341 ch_num = 0;
15342 for (j = 0; j < rfctl->max_chan_nums; j++) {
15343 chan = rfctl->channel_set[j].ChannelNum;
15344 if (mark[chan]) {
15345 roam_ch[ch_num].hw_value = chan;
15346 roam_ch[ch_num++].flags = rfctl->channel_set[j].flags;
15347 }
15348 }
15349 pmlmeext->roam_ch_num = ch_num;
15350 }
15351 #endif
15352
sitesurvey_cmd_hdl(_adapter * padapter,u8 * pbuf)15353 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
15354 {
15355 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
15356 #ifdef DBG_CHECK_FW_PS_STATE
15357 struct dvobj_priv *dvobj = padapter->dvobj;
15358 struct debug_priv *pdbgpriv = &dvobj->drv_dbg;
15359 #endif
15360 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15361 struct ss_res *ss = &pmlmeext->sitesurvey_res;
15362 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
15363 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
15364 #endif
15365 u8 val8;
15366
15367 #ifdef CONFIG_P2P
15368 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
15369 #ifdef CONFIG_CONCURRENT_MODE
15370 struct roch_info *prochinfo = &padapter->rochinfo;
15371 #endif
15372 #endif
15373
15374 #ifdef DBG_CHECK_FW_PS_STATE
15375 if (rtw_fw_ps_state(padapter) == _FAIL) {
15376 RTW_INFO("scan without leave 32k\n");
15377 pdbgpriv->dbg_scan_pwr_state_cnt++;
15378 }
15379 #endif /* DBG_CHECK_FW_PS_STATE */
15380
15381 /* increase channel idx */
15382 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
15383 ss->channel_idx++;
15384
15385 /* update scan state to next state (assigned by previous cmd hdl) */
15386 if (mlmeext_scan_state(pmlmeext) != mlmeext_scan_next_state(pmlmeext))
15387 mlmeext_set_scan_state(pmlmeext, mlmeext_scan_next_state(pmlmeext));
15388
15389 operation_by_state:
15390 switch (mlmeext_scan_state(pmlmeext)) {
15391
15392 case SCAN_DISABLE:
15393 /*
15394 * SW parameter initialization
15395 */
15396
15397 sitesurvey_res_reset(padapter, pparm);
15398 mlmeext_set_scan_state(pmlmeext, SCAN_START);
15399 goto operation_by_state;
15400
15401 case SCAN_START:
15402 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
15403 if ((pwdev_priv->pno_mac_addr[0] != 0xFF)
15404 && (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE)
15405 && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE)) {
15406 u16 seq_num;
15407
15408 #ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
15409 rtw_hal_pno_random_gen_mac_addr(padapter);
15410 #endif
15411 rtw_hal_set_hw_macaddr(padapter, pwdev_priv->pno_mac_addr);
15412 get_random_bytes(&seq_num, 2);
15413 pwdev_priv->pno_scan_seq_num = seq_num & 0xFFF;
15414 RTW_INFO("%s pno_scan_seq_num %d\n", __func__,
15415 pwdev_priv->pno_scan_seq_num);
15416 }
15417 #endif
15418
15419 /*
15420 * prepare to leave operating channel
15421 */
15422
15423 #ifdef CONFIG_MCC_MODE
15424 rtw_hal_set_mcc_setting_scan_start(padapter);
15425 #endif /* CONFIG_MCC_MODE */
15426
15427 /* apply rx ampdu setting */
15428 if (ss->rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
15429 || ss->rx_ampdu_size != RX_AMPDU_SIZE_INVALID)
15430 rtw_rx_ampdu_apply(padapter);
15431
15432 /* clear HW TX queue before scan */
15433 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
15434
15435 rtw_hal_macid_sleep_all_used(padapter);
15436
15437 /* power save state announcement */
15438 if (rtw_ps_annc(padapter, 1)) {
15439 mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
15440 mlmeext_set_scan_next_state(pmlmeext, SCAN_ENTER);
15441 set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
15442 } else {
15443 mlmeext_set_scan_state(pmlmeext, SCAN_ENTER);
15444 goto operation_by_state;
15445 }
15446
15447 break;
15448
15449 case SCAN_ENTER:
15450 /*
15451 * HW register and DM setting for enter scan
15452 */
15453
15454 rtw_phydm_ability_backup(padapter);
15455
15456 sitesurvey_set_igi(padapter);
15457
15458 /* config dynamic functions for off channel */
15459 rtw_phydm_func_for_offchannel(padapter);
15460 /* set MSR to no link state */
15461 sitesurvey_set_msr(padapter, _TRUE);
15462
15463 val8 = 1; /* under site survey */
15464 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
15465
15466 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
15467 goto operation_by_state;
15468
15469 case SCAN_PROCESS: {
15470 u8 scan_ch;
15471 RT_SCAN_TYPE scan_type;
15472 u8 next_state;
15473 u32 scan_ms;
15474
15475 #ifdef CONFIG_RTW_ACS
15476 if (IS_ACS_ENABLE(padapter))
15477 rtw_acs_get_rst(padapter);
15478 #endif
15479
15480 next_state = sitesurvey_pick_ch_behavior(padapter, &scan_ch, &scan_type);
15481
15482 if (next_state != SCAN_PROCESS) {
15483 mlmeext_set_scan_state(pmlmeext, next_state);
15484 goto operation_by_state;
15485 }
15486
15487 /* still SCAN_PROCESS state */
15488 #ifdef DBG_SITESURVEY
15489 #ifdef CONFIG_P2P
15490 RTW_INFO(FUNC_ADPT_FMT" %s ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c%c\n"
15491 , FUNC_ADPT_ARG(padapter)
15492 , mlmeext_scan_state_str(pmlmeext)
15493 , scan_ch
15494 , pwdinfo->find_phase_state_exchange_cnt, ss->channel_idx
15495 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
15496 , scan_type ? 'A' : 'P', ss->scan_mode ? 'A' : 'P'
15497 , ss->ssid[0].SsidLength ? 'S' : ' '
15498 , ss->force_ssid_scan ? 'F' : ' '
15499 );
15500 #else
15501 RTW_INFO(FUNC_ADPT_FMT" %s ch:%u (idx:%d) at %dms, %c%c%c%c\n"
15502 , FUNC_ADPT_ARG(padapter)
15503 , mlmeext_scan_state_str(pmlmeext)
15504 , scan_ch
15505 , ss->channel_idx
15506 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
15507 , scan_type ? 'A' : 'P', ss->scan_mode ? 'A' : 'P'
15508 , ss->ssid[0].SsidLength ? 'S' : ' '
15509 , ss->force_ssid_scan ? 'F' : ' '
15510 );
15511 #endif /* CONFIG_P2P */
15512 #endif /*DBG_SITESURVEY*/
15513 #ifdef DBG_FIXED_CHAN
15514 if (pmlmeext->fixed_chan != 0xff)
15515 RTW_INFO(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
15516 #endif
15517
15518 site_survey(padapter, scan_ch, scan_type);
15519
15520 #if defined(CONFIG_ATMEL_RC_PATCH)
15521 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
15522 scan_ms = 20;
15523 else
15524 scan_ms = 40;
15525 #else
15526 #if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
15527 if (IS_ACS_ENABLE(padapter) && rtw_is_acs_st_valid(padapter))
15528 scan_ms = rtw_acs_get_adv_st(padapter);
15529 else
15530 #endif /*CONFIG_RTW_ACS*/
15531 scan_ms = ss->scan_ch_ms;
15532 #endif
15533
15534 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
15535 if (ss->is_sw_antdiv_bl_scan)
15536 scan_ms = scan_ms / 2;
15537 #endif
15538
15539 #ifdef CONFIG_RTW_ACS
15540 if (IS_ACS_ENABLE(padapter)) {
15541 if (pparm->token)
15542 rtw_acs_trigger(padapter, scan_ms, scan_ch, NHM_PID_IEEE_11K_HIGH);
15543 else
15544 rtw_acs_trigger(padapter, scan_ms, scan_ch, NHM_PID_ACS);
15545 }
15546 #endif
15547
15548 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
15549 if (IS_NM_ENABLE(padapter))
15550 rtw_noise_measure(padapter, scan_ch, _FALSE, 0, scan_ms / 2);
15551 #endif
15552 set_survey_timer(pmlmeext, scan_ms);
15553 break;
15554 }
15555
15556 #ifdef CONFIG_SCAN_BACKOP
15557 case SCAN_BACKING_OP: {
15558 u8 back_ch = 0, back_bw = 0, back_ch_offset = 0;
15559 u8 need_ch_setting_union = _TRUE;
15560
15561 #ifdef CONFIG_MCC_MODE
15562 need_ch_setting_union = rtw_hal_mcc_change_scan_flag(padapter,
15563 &back_ch, &back_bw, &back_ch_offset);
15564 #endif /* CONFIG_MCC_MODE */
15565
15566 if (need_ch_setting_union) {
15567 if (rtw_mi_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0) {
15568 rtw_warn_on(1);
15569 back_ch = pmlmeext->cur_channel;
15570 back_bw = pmlmeext->cur_bwmode;
15571 back_ch_offset = pmlmeext->cur_ch_offset;
15572 }
15573 }
15574
15575 #ifdef DBG_SITESURVEY
15576 RTW_INFO(FUNC_ADPT_FMT" %s ch:%u, bw:%u, offset:%u at %dms\n"
15577 , FUNC_ADPT_ARG(padapter)
15578 , mlmeext_scan_state_str(pmlmeext)
15579 , back_ch, back_bw, back_ch_offset
15580 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
15581 );
15582 #endif /*DBG_SITESURVEY*/
15583 set_channel_bwmode(padapter, back_ch, back_ch_offset, back_bw);
15584
15585 sitesurvey_set_msr(padapter, _FALSE);
15586
15587 val8 = 0; /* survey done */
15588 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
15589
15590 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
15591 sitesurvey_set_igi(padapter);
15592 rtw_hal_macid_wakeup_all_used(padapter);
15593 rtw_ps_annc(padapter, 0);
15594 }
15595
15596 mlmeext_set_scan_state(pmlmeext, SCAN_BACK_OP);
15597 ss->backop_time = rtw_get_current_time();
15598
15599 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_TX_RESUME))
15600 rtw_mi_os_xmit_schedule(padapter);
15601
15602
15603 goto operation_by_state;
15604 }
15605
15606 case SCAN_BACK_OP:
15607 if (rtw_get_passing_time_ms(ss->backop_time) >= ss->backop_ms
15608 || pmlmeext->scan_abort
15609 ) {
15610 mlmeext_set_scan_state(pmlmeext, SCAN_LEAVING_OP);
15611 goto operation_by_state;
15612 }
15613 set_survey_timer(pmlmeext, 50);
15614 break;
15615
15616 case SCAN_LEAVING_OP:
15617 /*
15618 * prepare to leave operating channel
15619 */
15620
15621 /* clear HW TX queue before scan */
15622 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
15623
15624 rtw_hal_macid_sleep_all_used(padapter);
15625 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)
15626 && rtw_ps_annc(padapter, 1)
15627 ) {
15628 mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
15629 mlmeext_set_scan_next_state(pmlmeext, SCAN_LEAVE_OP);
15630 set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
15631 } else {
15632 mlmeext_set_scan_state(pmlmeext, SCAN_LEAVE_OP);
15633 goto operation_by_state;
15634 }
15635
15636 break;
15637
15638 case SCAN_LEAVE_OP:
15639 /*
15640 * HW register and DM setting for enter scan
15641 */
15642
15643 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC))
15644 sitesurvey_set_igi(padapter);
15645
15646 sitesurvey_set_msr(padapter, _TRUE);
15647
15648 val8 = 1; /* under site survey */
15649 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
15650
15651 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
15652 goto operation_by_state;
15653
15654 #endif /* CONFIG_SCAN_BACKOP */
15655
15656 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
15657 case SCAN_SW_ANTDIV_BL:
15658 /*
15659 * 20100721
15660 * For SW antenna diversity before link, it needs to switch to another antenna and scan again.
15661 * It compares the scan result and select better one to do connection.
15662 */
15663 ss->bss_cnt = 0;
15664 ss->channel_idx = 0;
15665 ss->is_sw_antdiv_bl_scan = 1;
15666
15667 mlmeext_set_scan_next_state(pmlmeext, SCAN_PROCESS);
15668 set_survey_timer(pmlmeext, ss->scan_ch_ms);
15669 break;
15670 #endif
15671
15672 #ifdef CONFIG_P2P
15673 case SCAN_TO_P2P_LISTEN:
15674 /*
15675 * Set the P2P State to the listen state of find phase
15676 * and set the current channel to the listen channel
15677 */
15678 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
15679 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
15680
15681 /* turn on phy-dynamic functions */
15682 rtw_phydm_ability_restore(padapter);
15683
15684 sitesurvey_set_igi(padapter);
15685
15686 mlmeext_set_scan_state(pmlmeext, SCAN_P2P_LISTEN);
15687 _set_timer(&pwdinfo->find_phase_timer, (u32)((u32)pwdinfo->listen_dwell * 100));
15688 break;
15689
15690 case SCAN_P2P_LISTEN:
15691 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
15692 ss->channel_idx = 0;
15693 goto operation_by_state;
15694 #endif /* CONFIG_P2P */
15695
15696 case SCAN_COMPLETE:
15697 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
15698 rtw_hal_set_hw_macaddr(padapter, adapter_mac_addr(padapter));
15699 #endif
15700 #ifdef CONFIG_P2P
15701 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
15702 || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
15703 ) {
15704 #ifdef CONFIG_CONCURRENT_MODE
15705 if (pwdinfo->driver_interface == DRIVER_WEXT) {
15706 if (rtw_mi_check_status(padapter, MI_LINKED))
15707 _set_timer(&prochinfo->ap_roch_ch_switch_timer, 500);
15708 }
15709 #endif
15710
15711 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
15712 }
15713 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
15714 #endif /* CONFIG_P2P */
15715
15716 /* switch channel */
15717 survey_done_set_ch_bw(padapter);
15718
15719 sitesurvey_set_msr(padapter, _FALSE);
15720
15721 val8 = 0; /* survey done */
15722 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
15723
15724 /* turn on phy-dynamic functions */
15725 rtw_phydm_ability_restore(padapter);
15726
15727 sitesurvey_set_igi(padapter);
15728
15729 #ifdef CONFIG_MCC_MODE
15730 /* start MCC fail, then tx null data */
15731 if (!rtw_hal_set_mcc_setting_scan_complete(padapter))
15732 #endif
15733 {
15734 rtw_hal_macid_wakeup_all_used(padapter);
15735 rtw_ps_annc(padapter, 0);
15736 }
15737
15738 /* apply rx ampdu setting */
15739 rtw_rx_ampdu_apply(padapter);
15740
15741 mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
15742
15743 report_surveydone_event(padapter, ss->acs);
15744 #ifdef CONFIG_RTW_ACS
15745 if (IS_ACS_ENABLE(padapter))
15746 rtw_acs_select_best_chan(padapter);
15747 #endif
15748
15749 #if defined(CONFIG_BACKGROUND_NOISE_MONITOR) && defined(DBG_NOISE_MONITOR)
15750 if (IS_NM_ENABLE(padapter))
15751 rtw_noise_info_dump(RTW_DBGDUMP, padapter);
15752 #endif
15753 issue_action_BSSCoexistPacket(padapter);
15754 issue_action_BSSCoexistPacket(padapter);
15755 issue_action_BSSCoexistPacket(padapter);
15756
15757 #ifdef CONFIG_RTW_80211K
15758 if (ss->token)
15759 rm_post_event(padapter, ss->token, RM_EV_survey_done);
15760 #endif /* CONFIG_RTW_80211K */
15761 #ifdef CONFIG_RTW_ROAM_QUICKSCAN
15762 if (padapter->mlmepriv.need_to_roam == _TRUE)
15763 generate_quickss(padapter);
15764 #endif
15765 break;
15766 }
15767
15768 return H2C_SUCCESS;
15769 }
15770
setauth_hdl(_adapter * padapter,unsigned char * pbuf)15771 u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
15772 {
15773 struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
15774 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15775 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15776
15777 if (pparm->mode < 4)
15778 pmlmeinfo->auth_algo = pparm->mode;
15779
15780 return H2C_SUCCESS;
15781 }
15782
amsdu_spp_enable(_adapter * pdapter,enum security_type type)15783 static u8 amsdu_spp_enable(_adapter *pdapter, enum security_type type)
15784 {
15785 u8 ret = _FALSE;
15786
15787 if (pdapter->registrypriv.amsdu_mode == RTW_AMSDU_MODE_SPP) {
15788 if ( type == _AES_ || type == _CCMP_256_
15789 || type == _GCMP_ || type == _GCMP_256_ )
15790 ret = _SUCCESS;
15791 }
15792
15793 return ret;
15794 }
15795
15796 /*
15797 SEC CAM Entry format (32 bytes)
15798 DW0 - MAC_ADDR[15:0] | Valid[15] | MFB[14:8] | RSVD[7] | GK[6] | MIC_KEY[5] | SEC_TYPE[4:2] | KID[1:0]
15799 DW0 - MAC_ADDR[15:0] | Valid[15] |RSVD[14:9] | RPT_MODE[8] | SPP_MODE[7] | GK[6] | MIC_KEY[5] | SEC_TYPE[4:2] | KID[1:0] (92E/8812A/8814A)
15800 DW1 - MAC_ADDR[47:16]
15801 DW2 - KEY[31:0]
15802 DW3 - KEY[63:32]
15803 DW4 - KEY[95:64]
15804 DW5 - KEY[127:96]
15805 DW6 - RSVD
15806 DW7 - RSVD
15807 */
15808
15809 /*Set WEP key or Group Key*/
setkey_hdl(_adapter * padapter,u8 * pbuf)15810 u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
15811 {
15812 u16 ctrl = 0;
15813 s16 cam_id = 0;
15814 struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
15815 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15816 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15817 unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
15818 u8 *addr;
15819 bool used = _FALSE;
15820
15821 /* main tx key for wep. */
15822 if (pparm->set_tx)
15823 pmlmeinfo->key_index = pparm->keyid;
15824
15825 #ifndef SEC_DEFAULT_KEY_SEARCH
15826 if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE))
15827 cam_id = rtw_iface_bcmc_id_get(padapter);
15828 else
15829 #endif
15830 cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid, 1,
15831 !!(pparm->algorithm & _SEC_TYPE_256_), &used);
15832
15833 if (cam_id < 0)
15834 goto enable_mc;
15835
15836 #ifdef SEC_DEFAULT_KEY_SEARCH
15837 if (cam_id >= 0 && cam_id <= 3) {
15838 /* default key camid */
15839 addr = null_addr;
15840 } else
15841 #endif
15842 {
15843 /* not default key camid */
15844 if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
15845 /* group TX, force sec cam entry_id */
15846 addr = adapter_mac_addr(padapter);
15847 } else {
15848 /* group RX, searched by A2 (TA) */
15849 addr = get_bssid(&padapter->mlmepriv);
15850 }
15851 }
15852
15853 #ifdef CONFIG_LPS_PG
15854 if (adapter_to_pwrctl(padapter)->lps_level == LPS_PG)
15855 LPS_Leave(padapter, "SET_KEY");
15856 #endif
15857
15858 /* cam entry searched is pairwise key */
15859 if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _FALSE) {
15860 s16 camid_clr;
15861
15862 RTW_PRINT(FUNC_ADPT_FMT" group key with "MAC_FMT" id:%u the same key id as pairwise key\n"
15863 , FUNC_ADPT_ARG(padapter), MAC_ARG(addr), pparm->keyid);
15864
15865 /* HW has problem to distinguish this group key with existing pairwise key, stop HW enc and dec for BMC */
15866 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
15867 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
15868
15869 /* clear group key */
15870 while ((camid_clr = rtw_camid_search(padapter, addr, -1, 1)) >= 0) {
15871 RTW_PRINT("clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), camid_clr);
15872 clear_cam_entry(padapter, camid_clr);
15873 rtw_camid_free(padapter, camid_clr);
15874 }
15875
15876 goto enable_mc;
15877 }
15878
15879 ctrl = BIT(15) | BIT(6) | ((pparm->algorithm & 0x07) << 2) | pparm->keyid;
15880
15881 RTW_PRINT("set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
15882 , cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm));
15883
15884 if (pparm->algorithm & _SEC_TYPE_256_) {
15885 RTW_INFO_DUMP("GTK : ", pparm->key, sizeof(pparm->key));
15886 ctrl |= BIT(9);
15887 }
15888 if (amsdu_spp_enable(padapter, pparm->algorithm) == _SUCCESS)
15889 ctrl |= BIT(7);
15890 write_cam(padapter, cam_id, ctrl, addr, pparm->key);
15891
15892 /* if ((cam_id > 3) && (((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)))*/
15893 #ifndef SEC_DEFAULT_KEY_SEARCH
15894 if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
15895 if (is_wep_enc(pparm->algorithm)) {
15896 padapter->securitypriv.dot11Def_camid[pparm->keyid] = cam_id;
15897 padapter->securitypriv.dot118021x_bmc_cam_id =
15898 padapter->securitypriv.dot11Def_camid[padapter->securitypriv.dot11PrivacyKeyIndex];
15899 RTW_PRINT("wep group key - force camid:%d\n", padapter->securitypriv.dot118021x_bmc_cam_id);
15900 } else {
15901 /*u8 org_cam_id = padapter->securitypriv.dot118021x_bmc_cam_id;*/
15902
15903 /*force GK's cam id*/
15904 padapter->securitypriv.dot118021x_bmc_cam_id = cam_id;
15905
15906 /* for GTK rekey
15907 if ((org_cam_id != INVALID_SEC_MAC_CAM_ID) &&
15908 (org_cam_id != cam_id)) {
15909 RTW_PRINT("clear group key for addr:"MAC_FMT", org_camid:%d new_camid:%d\n", MAC_ARG(addr), org_cam_id, cam_id);
15910 clear_cam_entry(padapter, org_cam_id);
15911 rtw_camid_free(padapter, org_cam_id);
15912 }*/
15913 }
15914 }
15915 #else
15916 if (cam_id >= 0 && cam_id <= 3)
15917 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_TRUE);
15918 #endif
15919
15920 /* 8814au should set both broadcast and unicast CAM entry for WEP key in STA mode */
15921 if (is_wep_enc(pparm->algorithm) && check_mlmeinfo_state(pmlmeext, WIFI_FW_STATION_STATE) &&
15922 _rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_BMC)) {
15923 struct set_stakey_parm sta_pparm;
15924
15925 _rtw_memset(&sta_pparm, 0, sizeof(struct set_stakey_parm));
15926 sta_pparm.algorithm = pparm->algorithm;
15927 sta_pparm.keyid = pparm->keyid;
15928 _rtw_memcpy(sta_pparm.key, pparm->key, 16);
15929 _rtw_memcpy(sta_pparm.addr, get_bssid(&padapter->mlmepriv), ETH_ALEN);
15930 set_stakey_hdl(padapter, (u8 *)&sta_pparm);
15931 }
15932
15933 enable_mc:
15934 /* allow multicast packets to driver */
15935 rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr);
15936 #ifdef CONFIG_LAYER2_ROAMING
15937 if (padapter->mlmepriv.roam_network) {
15938 struct xmit_frame *rframe;
15939 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
15940 _list *plist, *phead;
15941 _irqL irqL;
15942 _pkt *pkt;
15943
15944 padapter->mlmepriv.roam_network = NULL;
15945 _enter_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL);
15946 phead = get_list_head(&pxmitpriv->rpkt_queue);
15947 plist = get_next(phead);
15948 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
15949 rframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
15950 plist = get_next(plist);
15951 rtw_list_delete(&rframe->list);
15952 pkt = rframe->pkt;
15953 rtw_xmit_posthandle(padapter, rframe, pkt);
15954 }
15955 _exit_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL);
15956 }
15957 #endif
15958 return H2C_SUCCESS;
15959 }
15960
rtw_ap_wep_pk_setting(_adapter * adapter,struct sta_info * psta)15961 void rtw_ap_wep_pk_setting(_adapter *adapter, struct sta_info *psta)
15962 {
15963 struct security_priv *psecuritypriv = &(adapter->securitypriv);
15964 struct set_stakey_parm sta_pparm;
15965 sint keyid;
15966
15967 if (!is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm))
15968 return;
15969
15970 for (keyid = 0; keyid < 4; keyid++) {
15971 if ((psecuritypriv->key_mask & BIT(keyid)) && (keyid == psecuritypriv->dot11PrivacyKeyIndex)) {
15972 sta_pparm.algorithm = psecuritypriv->dot11PrivacyAlgrthm;
15973 sta_pparm.keyid = keyid;
15974 sta_pparm.gk = 0;
15975 _rtw_memcpy(sta_pparm.key, &(psecuritypriv->dot11DefKey[keyid].skey[0]), 16);
15976 _rtw_memcpy(sta_pparm.addr, psta->cmn.mac_addr, ETH_ALEN);
15977
15978 RTW_PRINT(FUNC_ADPT_FMT"set WEP - PK with "MAC_FMT" keyid:%u\n"
15979 , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr), keyid);
15980
15981 set_stakey_hdl(adapter, (u8 *)&sta_pparm);
15982 }
15983 }
15984 }
15985
set_stakey_hdl(_adapter * padapter,u8 * pbuf)15986 u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
15987 {
15988 u16 ctrl = 0;
15989 s16 cam_id = 0;
15990 bool used;
15991 u8 ret = H2C_SUCCESS;
15992 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15993 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15994 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
15995 struct sta_priv *pstapriv = &padapter->stapriv;
15996 struct sta_info *psta;
15997
15998 if (pparm->algorithm == _NO_PRIVACY_)
15999 goto write_to_cam;
16000
16001 psta = rtw_get_stainfo(pstapriv, pparm->addr);
16002 if (!psta) {
16003 RTW_PRINT("%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr));
16004 ret = H2C_REJECTED;
16005 goto exit;
16006 }
16007
16008 pmlmeinfo->enc_algo = pparm->algorithm;
16009
16010 cam_id = rtw_camid_alloc(padapter, psta, pparm->keyid, pparm->gk,
16011 !!(pparm->algorithm & _SEC_TYPE_256_), &used);
16012 if (cam_id < 0)
16013 goto exit;
16014
16015 #ifdef CONFIG_LPS_PG
16016 if (adapter_to_pwrctl(padapter)->lps_level == LPS_PG)
16017 LPS_Leave(padapter, "SET_KEY");
16018 #endif
16019
16020 /* cam entry searched is group key when setting pariwise key */
16021 if (!pparm->gk && used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _TRUE) {
16022 s16 camid_clr;
16023
16024 RTW_PRINT(FUNC_ADPT_FMT" pairwise key with "MAC_FMT" id:%u the same key id as group key\n"
16025 , FUNC_ADPT_ARG(padapter), MAC_ARG(pparm->addr), pparm->keyid);
16026
16027 /* HW has problem to distinguish this pairwise key with existing group key, stop HW enc and dec for BMC */
16028 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
16029 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
16030
16031 /* clear group key */
16032 while ((camid_clr = rtw_camid_search(padapter, pparm->addr, -1, 1)) >= 0) {
16033 RTW_PRINT("clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), camid_clr);
16034 clear_cam_entry(padapter, camid_clr);
16035 rtw_camid_free(padapter, camid_clr);
16036 }
16037 }
16038
16039 write_to_cam:
16040 if (pparm->algorithm == _NO_PRIVACY_) {
16041 while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1, -1)) >= 0) {
16042 RTW_PRINT("clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id);
16043 clear_cam_entry(padapter, cam_id);
16044 rtw_camid_free(padapter, cam_id);
16045 }
16046 } else {
16047 RTW_PRINT("set %s key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
16048 , pparm->gk ? "group" : "pairwise"
16049 , cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm));
16050 ctrl = BIT(15) | ((pparm->algorithm & 0x07) << 2) | pparm->keyid;
16051 if (pparm->gk)
16052 ctrl |= BIT(6);
16053 if (pparm->algorithm & _SEC_TYPE_256_) {
16054 RTW_INFO_DUMP("PTK : ", pparm->key, sizeof(pparm->key));
16055 ctrl |= BIT(9);
16056 }
16057
16058 if (amsdu_spp_enable(padapter, pparm->algorithm) == _SUCCESS)
16059 ctrl |= BIT(7);
16060
16061 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
16062 if (!(pparm->gk))
16063 ATOMIC_INC(&psta->keytrack); /*CVE-2020-24587*/
16064 }
16065 ret = H2C_SUCCESS_RSP;
16066
16067 exit:
16068 return ret;
16069 }
16070
add_ba_hdl(_adapter * padapter,unsigned char * pbuf)16071 u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
16072 {
16073 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
16074 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
16075 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
16076
16077 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
16078
16079 if (!psta)
16080 return H2C_SUCCESS;
16081
16082 #ifdef CONFIG_80211N_HT
16083 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
16084 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
16085 /* pmlmeinfo->ADDBA_retry_count = 0; */
16086 /* pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid); */
16087 /* psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid); */
16088 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
16089 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
16090 }
16091 #ifdef CONFIG_TDLS
16092 else if ((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
16093 (psta->htpriv.ht_option == _TRUE) &&
16094 (psta->htpriv.ampdu_enable == _TRUE)) {
16095 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
16096 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
16097 }
16098 #endif /* CONFIG */
16099 else
16100 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
16101 #endif /* CONFIG_80211N_HT */
16102 return H2C_SUCCESS;
16103 }
16104
16105
add_ba_rsp_hdl(_adapter * padapter,unsigned char * pbuf)16106 u8 add_ba_rsp_hdl(_adapter *padapter, unsigned char *pbuf)
16107 {
16108 struct addBaRsp_parm *pparm = (struct addBaRsp_parm *)pbuf;
16109 struct recv_reorder_ctrl *preorder_ctrl;
16110 struct sta_priv *pstapriv = &padapter->stapriv;
16111 struct sta_info *psta;
16112 u8 ret = _TRUE;
16113
16114 psta = rtw_get_stainfo(pstapriv, pparm->addr);
16115 if (!psta)
16116 goto exit;
16117
16118 preorder_ctrl = &psta->recvreorder_ctrl[pparm->tid];
16119 ret = issue_addba_rsp_wait_ack(padapter, pparm->addr, pparm->tid, pparm->status, pparm->size, 3, 50);
16120
16121 #ifdef CONFIG_UPDATE_INDICATE_SEQ_WHILE_PROCESS_ADDBA_REQ
16122 /* status = 0 means accept this addba req, so update indicate seq = start_seq under this compile flag */
16123 if (pparm->status == 0) {
16124 preorder_ctrl->indicate_seq = pparm->start_seq;
16125 #ifdef DBG_RX_SEQ
16126 RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_UPDATE indicate_seq:%d, start_seq:%d\n"
16127 , FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, pparm->start_seq);
16128 #endif
16129 }
16130 #else
16131 rtw_set_bit(RTW_RECV_ACK_OR_TIMEOUT, &preorder_ctrl->rec_abba_rsp_ack);
16132 #ifdef DBG_RX_SEQ
16133 RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_CLEAR indicate_seq:%d, start_seq:%d preorder_ctrl->rec_abba_rsp_ack =%lu \n"
16134 , FUNC_ADPT_ARG(padapter)
16135 , preorder_ctrl->tid
16136 , preorder_ctrl->indicate_seq
16137 , pparm->start_seq
16138 ,preorder_ctrl->rec_abba_rsp_ack
16139 );
16140 #endif
16141 #endif
16142
16143 /*
16144 * status = 0 means accept this addba req
16145 * status = 37 means reject this addba req
16146 */
16147 if (pparm->status == 0) {
16148 preorder_ctrl->enable = _TRUE;
16149 preorder_ctrl->ampdu_size = pparm->size;
16150 } else if (pparm->status == 37)
16151 preorder_ctrl->enable = _FALSE;
16152
16153 exit:
16154 return H2C_SUCCESS;
16155 }
16156
chk_bmc_sleepq_cmd(_adapter * padapter)16157 u8 chk_bmc_sleepq_cmd(_adapter *padapter)
16158 {
16159 struct cmd_obj *ph2c;
16160 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
16161 u8 res = _SUCCESS;
16162
16163
16164 ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
16165 if (ph2c == NULL) {
16166 res = _FAIL;
16167 goto exit;
16168 }
16169
16170 init_h2fwcmd_w_parm_no_parm_rsp(ph2c, CMD_CHK_BMCSLEEPQ);
16171
16172 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
16173
16174 exit:
16175
16176
16177 return res;
16178 }
16179
set_tx_beacon_cmd(_adapter * padapter,u8 flags)16180 u8 set_tx_beacon_cmd(_adapter *padapter, u8 flags)
16181 {
16182 struct cmd_obj *ph2c;
16183 struct Tx_Beacon_param *ptxBeacon_parm;
16184 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
16185 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
16186 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
16187 struct submit_ctx sctx;
16188 u8 res = _SUCCESS;
16189 int len_diff = 0;
16190
16191 /*prepare cmd parameter*/
16192 ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param));
16193 if (ptxBeacon_parm == NULL) {
16194 res = _FAIL;
16195 goto exit;
16196 }
16197
16198 _rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
16199
16200 len_diff = update_hidden_ssid(
16201 ptxBeacon_parm->network.IEs + _BEACON_IE_OFFSET_
16202 , ptxBeacon_parm->network.IELength - _BEACON_IE_OFFSET_
16203 , pmlmeinfo->hidden_ssid_mode
16204 );
16205 ptxBeacon_parm->network.IELength += len_diff;
16206
16207
16208 /* need enqueue, prepare cmd_obj and enqueue */
16209 ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
16210 if (ph2c == NULL) {
16211 res = _FAIL;
16212 rtw_mfree((u8 *)ptxBeacon_parm, sizeof(*ptxBeacon_parm));
16213 goto exit;
16214 }
16215
16216 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, CMD_TX_BEACON);
16217
16218 if (flags & RTW_CMDF_WAIT_ACK) {
16219 ph2c->sctx = &sctx;
16220 rtw_sctx_init(&sctx, 10 * 1000);
16221 }
16222
16223 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
16224
16225 if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) {
16226 rtw_sctx_wait(&sctx, __func__);
16227 _enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL);
16228 if (sctx.status == RTW_SCTX_SUBMITTED)
16229 ph2c->sctx = NULL;
16230 _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL);
16231 }
16232
16233
16234 exit:
16235
16236
16237 return res;
16238 }
16239
16240
mlme_evt_hdl(_adapter * padapter,unsigned char * pbuf)16241 u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
16242 {
16243 struct rtw_evt_header *evt_hdr;
16244 u8 *peventbuf;
16245 void (*event_callback)(_adapter *dev, u8 *pbuf);
16246 struct evt_priv *pevt_priv = &(padapter->evtpriv);
16247
16248 if (pbuf == NULL)
16249 goto _abort_event_;
16250
16251 evt_hdr = (struct rtw_evt_header *)pbuf;
16252 peventbuf = pbuf + sizeof(struct rtw_evt_header);
16253
16254 #ifdef CHECK_EVENT_SEQ
16255 /* checking event sequence... */
16256 if (evt_hdr->seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f)) {
16257 pevt_priv->event_seq = (evt_hdr->seq + 1) & 0x7f;
16258 goto _abort_event_;
16259 }
16260 #endif
16261
16262 /* checking if event code is valid */
16263 if (evt_hdr->id >= EVT_ID_MAX) {
16264 goto _abort_event_;
16265 }
16266
16267 /* checking if event size match the event parm size */
16268 if ((wlanevents[evt_hdr->id].parmsize != 0) &&
16269 (wlanevents[evt_hdr->id].parmsize != evt_hdr->len)) {
16270
16271 goto _abort_event_;
16272
16273 }
16274
16275 ATOMIC_INC(&pevt_priv->event_seq);
16276
16277 if (peventbuf) {
16278 event_callback = wlanevents[evt_hdr->id].event_callback;
16279 event_callback(padapter, (u8 *)peventbuf);
16280 pevt_priv->evt_done_cnt++;
16281 }
16282
16283 _abort_event_:
16284 return H2C_SUCCESS;
16285
16286 }
16287
chk_bmc_sleepq_hdl(_adapter * padapter,unsigned char * pbuf)16288 u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf)
16289 {
16290 #ifdef CONFIG_AP_MODE
16291 _irqL irqL;
16292 struct sta_info *psta_bmc;
16293 _list *xmitframe_plist, *xmitframe_phead;
16294 struct xmit_frame *pxmitframe = NULL;
16295 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
16296 struct sta_priv *pstapriv = &padapter->stapriv;
16297
16298 /* for BC/MC Frames */
16299 psta_bmc = rtw_get_bcmc_stainfo(padapter);
16300 if (!psta_bmc)
16301 return H2C_SUCCESS;
16302
16303 if ((rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, 0)) && (psta_bmc->sleepq_len > 0)) {
16304 #ifndef CONFIG_PCI_HCI
16305 rtw_msleep_os(10);/* 10ms, ATIM(HIQ) Windows */
16306 #endif
16307 /* _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL); */
16308 _enter_critical_bh(&pxmitpriv->lock, &irqL);
16309
16310 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
16311 xmitframe_plist = get_next(xmitframe_phead);
16312
16313 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
16314 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
16315
16316 xmitframe_plist = get_next(xmitframe_plist);
16317
16318 rtw_list_delete(&pxmitframe->list);
16319
16320 psta_bmc->sleepq_len--;
16321 if (psta_bmc->sleepq_len > 0)
16322 pxmitframe->attrib.mdata = 1;
16323 else
16324 pxmitframe->attrib.mdata = 0;
16325
16326 pxmitframe->attrib.triggered = 1;
16327
16328 if (xmitframe_hiq_filter(pxmitframe) == _TRUE)
16329 pxmitframe->attrib.qsel = QSLT_HIGH;/* HIQ */
16330
16331 #if 0
16332 _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
16333 if (rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
16334 rtw_os_xmit_complete(padapter, pxmitframe);
16335 _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
16336 #endif
16337 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
16338 }
16339
16340 /* _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); */
16341 _exit_critical_bh(&pxmitpriv->lock, &irqL);
16342
16343 if (rtw_get_intf_type(padapter) != RTW_PCIE) {
16344 /* check hi queue and bmc_sleepq */
16345 rtw_chk_hi_queue_cmd(padapter);
16346 }
16347 }
16348 #endif
16349
16350 return H2C_SUCCESS;
16351 }
16352
tx_beacon_hdl(_adapter * padapter,unsigned char * pbuf)16353 u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
16354 {
16355 #ifdef CONFIG_AP_MODE
16356 /*RTW_INFO(FUNC_ADPT_FMT, FUNC_ADPT_ARG(padapter));*/
16357 #ifdef CONFIG_SWTIMER_BASED_TXBCN
16358
16359 tx_beacon_handlder(padapter->dvobj);
16360
16361 #else
16362
16363 if (send_beacon(padapter) == _FAIL) {
16364 RTW_INFO("issue_beacon, fail!\n");
16365 return H2C_PARAMETERS_ERROR;
16366 }
16367
16368 /* tx bc/mc frames after update TIM */
16369 chk_bmc_sleepq_hdl(padapter, NULL);
16370 #endif
16371 #endif /* CONFIG_AP_MODE */
16372 return H2C_SUCCESS;
16373 }
16374
16375 /*
16376 * according to channel
16377 * add/remove WLAN_BSSID_EX.IEs's ERP ie
16378 * set WLAN_BSSID_EX.SupportedRates
16379 * update WLAN_BSSID_EX.IEs's Supported Rate and Extended Supported Rate ie
16380 */
16381 #ifdef CONFIG_AP_MODE
change_band_update_ie(_adapter * padapter,WLAN_BSSID_EX * pnetwork,u8 ch)16382 void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch)
16383 {
16384 u8 network_type, rate_len, total_rate_len, remainder_rate_len;
16385 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
16386 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
16387 u8 erpinfo = 0x4;
16388
16389 if (ch >= 36) {
16390 network_type = WIRELESS_11A;
16391 total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
16392 rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
16393 #ifdef CONFIG_80211AC_VHT
16394 /* if channel in 5G band, then add vht ie . */
16395 if ((pmlmepriv->htpriv.ht_option == _TRUE)
16396 && REGSTY_IS_11AC_ENABLE(&padapter->registrypriv)
16397 && is_supported_vht(padapter->registrypriv.wireless_mode)
16398 && RFCTL_REG_EN_11AC(rfctl)
16399 ) {
16400 if (pmlmepriv->vhtpriv.upper_layer_setting)
16401 rtw_reattach_vht_ies(padapter, pnetwork);
16402 else if (REGSTY_IS_11AC_AUTO(&padapter->registrypriv))
16403 rtw_vht_ies_attach(padapter, pnetwork);
16404 }
16405 #endif
16406 } else {
16407 network_type = 0;
16408 total_rate_len = 0;
16409 if (padapter->registrypriv.wireless_mode & WIRELESS_11B) {
16410 network_type |= WIRELESS_11B;
16411 total_rate_len += IEEE80211_CCK_RATE_LEN;
16412 }
16413 if (padapter->registrypriv.wireless_mode & WIRELESS_11G) {
16414 network_type |= WIRELESS_11G;
16415 total_rate_len += IEEE80211_NUM_OFDM_RATESLEN;
16416 }
16417 rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
16418 #ifdef CONFIG_80211AC_VHT
16419 rtw_vht_ies_detach(padapter, pnetwork);
16420 #endif
16421 }
16422
16423 rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
16424
16425 UpdateBrateTbl(padapter, pnetwork->SupportedRates);
16426
16427 if (total_rate_len > 8) {
16428 rate_len = 8;
16429 remainder_rate_len = total_rate_len - 8;
16430 } else {
16431 rate_len = total_rate_len;
16432 remainder_rate_len = 0;
16433 }
16434
16435 rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
16436
16437 if (remainder_rate_len)
16438 rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates + 8), remainder_rate_len);
16439 else
16440 rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
16441
16442 pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork);
16443 }
16444 #endif /* CONFIG_AP_MODE */
16445
rtw_join_done_chk_ch(_adapter * adapter,int join_res)16446 void rtw_join_done_chk_ch(_adapter *adapter, int join_res)
16447 {
16448 #define DUMP_ADAPTERS_STATUS 0
16449
16450 struct dvobj_priv *dvobj;
16451 _adapter *iface;
16452 struct mlme_priv *mlme;
16453 struct mlme_ext_priv *mlmeext;
16454 u8 u_ch, u_offset, u_bw;
16455 int i, ret;
16456
16457 dvobj = adapter_to_dvobj(adapter);
16458
16459 if (DUMP_ADAPTERS_STATUS) {
16460 RTW_INFO(FUNC_ADPT_FMT" enter\n", FUNC_ADPT_ARG(adapter));
16461 dump_adapters_status(RTW_DBGDUMP , dvobj);
16462 }
16463
16464 ret = rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset);
16465 if (join_res >= 0 && ret <= 0) {
16466 join_res = -1;
16467 dump_adapters_status(RTW_DBGDUMP , dvobj);
16468 rtw_warn_on(1);
16469 }
16470
16471 if (join_res >= 0) {
16472 #ifdef CONFIG_MCC_MODE
16473 /* MCC setting success, don't go to ch union process */
16474 if (rtw_hal_set_mcc_setting_join_done_chk_ch(adapter))
16475 return;
16476 #endif /* CONFIG_MCC_MODE */
16477
16478 for (i = 0; i < dvobj->iface_nums; i++) {
16479 iface = dvobj->padapters[i];
16480 mlme = &iface->mlmepriv;
16481 mlmeext = &iface->mlmeextpriv;
16482
16483 if (!iface || iface == adapter)
16484 continue;
16485
16486 #ifdef CONFIG_AP_MODE
16487 if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
16488 && check_fwstate(mlme, WIFI_ASOC_STATE)
16489 ) {
16490 u8 ori_ch, ori_bw, ori_offset;
16491 bool is_grouped = rtw_is_chbw_grouped(u_ch, u_bw, u_offset
16492 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
16493
16494 if (is_grouped == _FALSE) {
16495 /* handle AP which need to switch ch setting */
16496
16497 ori_ch = mlmeext->cur_channel;
16498 ori_bw = mlmeext->cur_bwmode;
16499 ori_offset = mlmeext->cur_ch_offset;
16500
16501 /* restore original bw, adjust bw by registry setting on target ch */
16502 mlmeext->cur_bwmode = mlme->ori_bw;
16503 mlmeext->cur_channel = u_ch;
16504 rtw_adjust_chbw(iface, mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset);
16505 #ifdef CONFIG_RTW_MESH
16506 if (MLME_IS_MESH(iface))
16507 rtw_mesh_adjust_chbw(mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset);
16508 #endif
16509
16510 rtw_chset_sync_chbw(adapter_to_chset(adapter)
16511 , &mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset
16512 , &u_ch, &u_bw, &u_offset, 1, 0);
16513
16514 RTW_INFO(FUNC_ADPT_FMT" %u,%u,%u => %u,%u,%u\n", FUNC_ADPT_ARG(iface)
16515 , ori_ch, ori_bw, ori_offset
16516 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
16517
16518 rtw_ap_update_bss_chbw(iface, &(mlmeext->mlmext_info.network)
16519 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
16520
16521 _rtw_memcpy(&(mlme->cur_network.network), &(mlmeext->mlmext_info.network), sizeof(WLAN_BSSID_EX));
16522
16523 rtw_start_bss_hdl_after_chbw_decided(iface);
16524
16525 {
16526 #if defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
16527 u8 ht_option = 0;
16528
16529 #ifdef CONFIG_80211N_HT
16530 ht_option = mlme->htpriv.ht_option;
16531 #endif
16532
16533 rtw_cfg80211_ch_switch_notify(iface
16534 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset
16535 , ht_option, 0);
16536 #endif
16537 }
16538 }
16539
16540 clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
16541 #ifdef CONFIG_ACTIVE_TPC_REPORT
16542 if (MLME_ACTIVE_TPC_REPORT(mlme))
16543 update_beacon(iface, WLAN_EID_TPC_REPORT, NULL, _FALSE, 0);
16544 #endif
16545 update_beacon(iface, 0xFF, NULL, _TRUE, 0);
16546 }
16547 #endif /* CONFIG_AP_MODE */
16548 }
16549
16550 #ifdef CONFIG_DFS_MASTER
16551 rtw_dfs_rd_en_decision(adapter, MLME_STA_CONNECTED, 0);
16552 #endif
16553 } else {
16554 for (i = 0; i < dvobj->iface_nums; i++) {
16555 iface = dvobj->padapters[i];
16556 mlme = &iface->mlmepriv;
16557 mlmeext = &iface->mlmeextpriv;
16558
16559 if (!iface || iface == adapter)
16560 continue;
16561 #ifdef CONFIG_AP_MODE
16562 if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
16563 && check_fwstate(mlme, WIFI_ASOC_STATE)
16564 ) {
16565 clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
16566 update_beacon(iface, 0xFF, NULL, _TRUE, 0);
16567 }
16568 #endif
16569 }
16570
16571 #ifdef CONFIG_80211D
16572 rtw_leavebss_update_regulatory(adapter);
16573 #endif
16574
16575 #ifdef CONFIG_DFS_MASTER
16576 rtw_dfs_rd_en_decision(adapter, MLME_STA_DISCONNECTED, 0);
16577 #endif
16578 }
16579
16580 if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset)) {
16581 RTW_INFO(FUNC_ADPT_FMT" union:%u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
16582 set_channel_bwmode(adapter, u_ch, u_offset, u_bw);
16583 }
16584
16585 rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw);
16586
16587 if (join_res >= 0)
16588 rtw_rfctl_update_op_mode(adapter_to_rfctl(adapter), BIT(adapter->iface_id), 1);
16589
16590 if (DUMP_ADAPTERS_STATUS) {
16591 RTW_INFO(FUNC_ADPT_FMT" exit\n", FUNC_ADPT_ARG(adapter));
16592 dump_adapters_status(RTW_DBGDUMP , dvobj);
16593 }
16594 }
16595
rtw_chk_start_clnt_join(_adapter * adapter,u8 * ch,u8 * bw,u8 * offset)16596 int rtw_chk_start_clnt_join(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
16597 {
16598 #ifdef CONFIG_CONCURRENT_MODE
16599 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
16600 bool chbw_allow = _TRUE;
16601 #endif
16602 bool connect_allow = _TRUE;
16603 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
16604 u8 cur_ch, cur_bw, cur_ch_offset;
16605 u8 u_ch, u_offset, u_bw;
16606
16607 u_ch = cur_ch = pmlmeext->cur_channel;
16608 u_bw = cur_bw = pmlmeext->cur_bwmode;
16609 u_offset = cur_ch_offset = pmlmeext->cur_ch_offset;
16610
16611 if (!ch || !bw || !offset) {
16612 connect_allow = _FALSE;
16613 rtw_warn_on(1);
16614 goto exit;
16615 }
16616
16617 if (cur_ch == 0) {
16618 connect_allow = _FALSE;
16619 RTW_ERR(FUNC_ADPT_FMT" cur_ch:%u\n"
16620 , FUNC_ADPT_ARG(adapter), cur_ch);
16621 rtw_warn_on(1);
16622 goto exit;
16623 }
16624 RTW_INFO(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
16625
16626 #ifdef CONFIG_CONCURRENT_MODE
16627 {
16628 struct dvobj_priv *dvobj;
16629 _adapter *iface;
16630 struct mlme_priv *mlme;
16631 struct mlme_ext_priv *mlmeext;
16632 struct mi_state mstate;
16633 int i;
16634
16635 dvobj = adapter_to_dvobj(adapter);
16636
16637 rtw_mi_status_no_self(adapter, &mstate);
16638 RTW_INFO(FUNC_ADPT_FMT" others ld_sta_num:%u, ap_num:%u, mesh_num:%u\n"
16639 , FUNC_ADPT_ARG(adapter), MSTATE_STA_LD_NUM(&mstate)
16640 , MSTATE_AP_NUM(&mstate), MSTATE_MESH_NUM(&mstate));
16641
16642 if (!MSTATE_STA_LD_NUM(&mstate) && !MSTATE_AP_NUM(&mstate) && !MSTATE_MESH_NUM(&mstate)) {
16643 /* consider linking STA? */
16644 goto connect_allow_hdl;
16645 }
16646
16647 if (rtw_mi_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
16648 dump_adapters_status(RTW_DBGDUMP , dvobj);
16649 rtw_warn_on(1);
16650 }
16651 RTW_INFO(FUNC_ADPT_FMT" others union:%u,%u,%u\n"
16652 , FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
16653
16654 /* chbw_allow? */
16655 chbw_allow = rtw_is_chbw_grouped(pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset
16656 , u_ch, u_bw, u_offset);
16657
16658 RTW_INFO(FUNC_ADPT_FMT" chbw_allow:%d\n"
16659 , FUNC_ADPT_ARG(adapter), chbw_allow);
16660
16661 #ifdef CONFIG_MCC_MODE
16662 /* check setting success, don't go to ch union process */
16663 if (rtw_hal_set_mcc_setting_chk_start_clnt_join(adapter, &u_ch, &u_bw, &u_offset, chbw_allow))
16664 goto exit;
16665 #endif
16666
16667 if (chbw_allow == _TRUE) {
16668 rtw_sync_chbw(&cur_ch, &cur_bw, &cur_ch_offset, &u_ch, &u_bw, &u_offset);
16669 rtw_warn_on(cur_ch != pmlmeext->cur_channel);
16670 rtw_warn_on(cur_bw != pmlmeext->cur_bwmode);
16671 rtw_warn_on(cur_ch_offset != pmlmeext->cur_ch_offset);
16672 goto connect_allow_hdl;
16673 }
16674
16675 #ifdef CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT
16676 /* chbw_allow is _FALSE, connect allow? */
16677 for (i = 0; i < dvobj->iface_nums; i++) {
16678 iface = dvobj->padapters[i];
16679 mlme = &iface->mlmepriv;
16680 mlmeext = &iface->mlmeextpriv;
16681
16682 if (check_fwstate(mlme, WIFI_STATION_STATE)
16683 && check_fwstate(mlme, WIFI_ASOC_STATE)
16684 #if defined(CONFIG_P2P)
16685 && rtw_p2p_chk_state(&(iface->wdinfo), P2P_STATE_NONE)
16686 #endif
16687 ) {
16688 connect_allow = _FALSE;
16689 break;
16690 }
16691 }
16692 #endif /* CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT */
16693
16694 if (MSTATE_STA_LD_NUM(&mstate) + MSTATE_AP_LD_NUM(&mstate) + MSTATE_MESH_LD_NUM(&mstate) >= 4)
16695 connect_allow = _FALSE;
16696
16697 RTW_INFO(FUNC_ADPT_FMT" connect_allow:%d\n"
16698 , FUNC_ADPT_ARG(adapter), connect_allow);
16699
16700 if (connect_allow == _FALSE)
16701 goto exit;
16702
16703 connect_allow_hdl:
16704 /* connect_allow == _TRUE */
16705
16706 if (chbw_allow == _FALSE) {
16707 u_ch = cur_ch;
16708 u_bw = cur_bw;
16709 u_offset = cur_ch_offset;
16710
16711 for (i = 0; i < dvobj->iface_nums; i++) {
16712 iface = dvobj->padapters[i];
16713 mlme = &iface->mlmepriv;
16714 mlmeext = &iface->mlmeextpriv;
16715
16716 if (!iface || iface == adapter)
16717 continue;
16718
16719 #ifdef CONFIG_AP_MODE
16720 if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
16721 && check_fwstate(mlme, WIFI_ASOC_STATE)
16722 ) {
16723 #ifdef CONFIG_SPCT_CH_SWITCH
16724 if (1)
16725 rtw_ap_inform_ch_switch(iface, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
16726 else
16727 #endif
16728 if (rfctl->ap_csa_en == AP_CSA_DISABLE)
16729 rtw_sta_flush(iface, _FALSE);
16730
16731 rtw_hal_set_hwreg(iface, HW_VAR_CHECK_TXBUF, 0);
16732 set_fwstate(mlme, WIFI_OP_CH_SWITCHING);
16733 } else
16734 #endif /* CONFIG_AP_MODE */
16735 if (check_fwstate(mlme, WIFI_STATION_STATE)
16736 && check_fwstate(mlme, WIFI_ASOC_STATE)
16737 ) {
16738 rtw_disassoc_cmd(iface, 500, RTW_CMDF_DIRECTLY);
16739 rtw_indicate_disconnect(iface, 0, _FALSE);
16740 rtw_free_assoc_resources(iface, _TRUE);
16741 }
16742 }
16743 }
16744 }
16745 #endif /* CONFIG_CONCURRENT_MODE */
16746
16747 #ifdef CONFIG_80211D
16748 rtw_joinbss_update_regulatory(adapter, &adapter->mlmeextpriv.mlmext_info.network);
16749 #endif
16750
16751 #ifdef CONFIG_DFS_MASTER
16752 rtw_dfs_rd_en_decision(adapter, MLME_STA_CONNECTING, 0);
16753 #endif
16754
16755 exit:
16756
16757 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
16758 if (rfctl->ap_csa_en != AP_CSA_DISABLE) {
16759 u8 enable = 0;
16760 rfctl->ap_csa_en = AP_CSA_DISABLE;
16761 rtw_hal_set_hwreg(adapter, HW_VAR_BCN_EARLY_C2H_RPT, &enable);
16762 }
16763 #endif
16764
16765 if (connect_allow == _TRUE) {
16766 RTW_INFO(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
16767 rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw);
16768 *ch = u_ch;
16769 *bw = u_bw;
16770 *offset = u_offset;
16771
16772 #if defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
16773 {
16774 u8 ht_option = 0;
16775
16776 #ifdef CONFIG_80211N_HT
16777 ht_option = adapter->mlmepriv.htpriv.ht_option;
16778 #endif /* CONFIG_80211N_HT */
16779
16780 /*
16781 when supplicant send the mlme frame,
16782 the bss freq is updated by channel switch event.
16783 */
16784 rtw_cfg80211_ch_switch_notify(adapter,
16785 cur_ch, cur_bw, cur_ch_offset, ht_option, 1);
16786 }
16787 #endif
16788 }
16789
16790 return connect_allow == _TRUE ? _SUCCESS : _FAIL;
16791 }
16792
rtw_set_external_auth_status(_adapter * padapter,const void * data,int len)16793 void rtw_set_external_auth_status(_adapter *padapter,
16794 const void *data, int len)
16795 {
16796 #ifdef CONFIG_IOCTL_CFG80211
16797 struct net_device *dev = padapter->pnetdev;
16798 struct wiphy *wiphy = adapter_to_wiphy(padapter);
16799 struct rtw_external_auth_params params;
16800
16801 /* convert data to external_auth_params */
16802 params.action = RTW_GET_BE32((u8 *)data);
16803 _rtw_memcpy(¶ms.bssid, (u8 *)data + 4, ETH_ALEN);
16804 _rtw_memcpy(¶ms.ssid.ssid, (u8 *)data + 10, WLAN_SSID_MAXLEN);
16805 params.ssid.ssid_len = RTW_GET_BE64((u8 *)data + 42);
16806 params.key_mgmt_suite = RTW_GET_BE32((u8 *)data + 58);
16807 params.status = RTW_GET_BE16((u8 *)data + 62);
16808 _rtw_memcpy(¶ms.pmkid, (u8 *)data + 64, PMKID_LEN);
16809
16810 rtw_cfg80211_external_auth_status(wiphy, dev, ¶ms);
16811 #endif /* CONFIG_IOCTL_CFG80211 */
16812 }
16813
rtw_iqk_hdl(_adapter * padapter,unsigned char * pbuf)16814 u8 rtw_iqk_hdl(_adapter *padapter, unsigned char *pbuf)
16815 {
16816 rtw_hal_phydm_cal_trigger(padapter);
16817 return H2C_SUCCESS;
16818 }
16819
rtw_set_chbw_hdl(_adapter * padapter,u8 * pbuf)16820 u8 rtw_set_chbw_hdl(_adapter *padapter, u8 *pbuf)
16821 {
16822 struct set_ch_parm *set_ch_parm;
16823 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
16824 u8 ifbmp_s = rtw_mi_get_ld_sta_ifbmp(padapter);
16825 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
16826 u8 u_ch, u_bw, u_offset;
16827
16828 if (!pbuf)
16829 return H2C_PARAMETERS_ERROR;
16830
16831 set_ch_parm = (struct set_ch_parm *)pbuf;
16832
16833 RTW_INFO(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
16834 FUNC_NDEV_ARG(padapter->pnetdev),
16835 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
16836
16837 /* update ch, bw, offset for all asoc STA ifaces */
16838 if (ifbmp_s) {
16839 _adapter *iface;
16840 int i;
16841
16842 for (i = 0; i < dvobj->iface_nums; i++) {
16843 iface = dvobj->padapters[i];
16844 if (!iface || !(ifbmp_s & BIT(iface->iface_id)))
16845 continue;
16846
16847 /* update STA mode ch/bw/offset */
16848 iface->mlmeextpriv.cur_channel = set_ch_parm->ch;
16849 iface->mlmeextpriv.cur_bwmode = set_ch_parm->bw;
16850 iface->mlmeextpriv.cur_ch_offset = set_ch_parm->ch_offset;
16851 /* updaet STA mode DSConfig , ap mode will update in rtw_change_bss_chbw_cmd */
16852 iface->mlmepriv.cur_network.network.Configuration.DSConfig = set_ch_parm->ch;
16853 }
16854 }
16855
16856 LeaveAllPowerSaveModeDirect(padapter);
16857
16858 set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
16859
16860 rtw_mi_get_ch_setting_union(padapter, &u_ch, &u_bw, &u_offset);
16861 rtw_mi_update_union_chan_inf(padapter, u_ch, u_offset, u_bw);
16862 rtw_rfctl_update_op_mode(dvobj_to_rfctl(dvobj), 0, 0);
16863
16864 return H2C_SUCCESS;
16865 }
16866
get_str_of_set_chplan_keys(char * buf,u8 buf_len,struct SetChannelPlan_param * param)16867 static void get_str_of_set_chplan_keys(char *buf, u8 buf_len, struct SetChannelPlan_param *param)
16868 {
16869 char *pos = buf;
16870
16871 #ifdef CONFIG_80211D
16872 if (param->has_cisr) {
16873 pos += snprintf(pos, buf_len - (pos - buf), "alpha2:"ALPHA2_FMT" %s"
16874 , ALPHA2_ARG(param->cisr.alpha2), cis_status_str(param->cisr.status));
16875 } else
16876 #endif
16877 if (param->has_country)
16878 pos += snprintf(pos, buf_len - (pos - buf), "alpha2:"ALPHA2_FMT, ALPHA2_ARG(param->country_ent.alpha2));
16879 else {
16880 if (param->channel_plan == RTW_CHPLAN_UNSPECIFIED)
16881 pos += snprintf(pos, buf_len - (pos - buf), "chplan:NA");
16882 else
16883 pos += snprintf(pos, buf_len - (pos - buf), "chplan:0x%02X", param->channel_plan);
16884
16885 #if CONFIG_IEEE80211_BAND_6GHZ
16886 if (param->channel_plan_6g == RTW_CHPLAN_6G_UNSPECIFIED)
16887 pos += snprintf(pos, buf_len - (pos - buf), " chplan_6g:NA");
16888 else
16889 pos += snprintf(pos, buf_len - (pos - buf), " chplan_6g:0x%02X", param->channel_plan_6g);
16890 #endif
16891 }
16892 }
16893
16894 #ifdef CONFIG_80211D
rtw_chplan_rtk_priv_req_prehdl_country_ie(_adapter * adapter,struct SetChannelPlan_param * param,const char * caller)16895 static bool rtw_chplan_rtk_priv_req_prehdl_country_ie(_adapter *adapter, struct SetChannelPlan_param *param, const char *caller)
16896 {
16897 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
16898 int i;
16899 bool effected = 1;
16900
16901 #ifdef CONFIG_RTW_DEBUG
16902 if (rtw_drv_log_level >= _DRV_DEBUG_) {
16903 RTW_PRINT("%s cisr before\n", caller);
16904 dump_country_ie_slave_records(RTW_DBGDUMP, rfctl, 0);
16905 }
16906 #endif
16907
16908 if (param->inr == RTW_REGD_SET_BY_USER
16909 && rfctl->effected_cisr_id != CONFIG_IFACE_NUMBER
16910 ) {
16911 /* country IE setting is applied, user setting is only recorded but not applied */
16912 effected = 0;
16913 goto exit;
16914 }
16915
16916 if (param->inr == RTW_REGD_SET_BY_COUNTRY_IE) {
16917 struct country_ie_slave_record ori_cisr = rfctl->cisr[adapter->iface_id];
16918 struct country_ie_slave_record ori_ecisr;
16919 u8 ori_ecisr_id = rfctl->effected_cisr_id;
16920 u8 new_ecisr_id = CONFIG_IFACE_NUMBER;
16921 u8 status_score[] = { /* conservative policy */
16922 [COUNTRY_IE_SLAVE_UNKNOWN] = 3,
16923 [COUNTRY_IE_SLAVE_OPCH_NOEXIST] = 2,
16924 [COUNTRY_IE_SLAVE_APPLICABLE] = 1,
16925 };
16926 char buf[32];
16927
16928 if (_rtw_memcmp(&rfctl->cisr[adapter->iface_id], ¶m->cisr, sizeof(param->cisr)) == _TRUE) {
16929 /* record no change */
16930 effected = 0;
16931 goto exit;
16932 }
16933
16934 if (ori_ecisr_id != CONFIG_IFACE_NUMBER)
16935 _rtw_memcpy(&ori_ecisr, &rfctl->cisr[ori_ecisr_id], sizeof(ori_ecisr));
16936
16937 _rtw_memcpy(&rfctl->cisr[adapter->iface_id], ¶m->cisr, sizeof(param->cisr));
16938 if ((ori_cisr.status == COUNTRY_IE_SLAVE_NOCOUNTRY
16939 && rfctl->cisr[adapter->iface_id].status == COUNTRY_IE_SLAVE_NOCOUNTRY)
16940 || (ori_cisr.status == COUNTRY_IE_SLAVE_UNKNOWN
16941 && rfctl->cisr[adapter->iface_id].status == COUNTRY_IE_SLAVE_UNKNOWN)
16942 ) {
16943 /* will take no effect */
16944 effected = 0;
16945 goto exit;
16946 }
16947
16948 for (i = 0; i < CONFIG_IFACE_NUMBER; i++) {
16949 if (rfctl->cisr[i].status == COUNTRY_IE_SLAVE_NOCOUNTRY)
16950 continue;
16951 if (new_ecisr_id == CONFIG_IFACE_NUMBER
16952 /* high score */
16953 || status_score[rfctl->cisr[i].status] > status_score[rfctl->cisr[new_ecisr_id].status]
16954 /* same score, prefer the same alpha2 as current effected(same score) one */
16955 || (status_score[rfctl->cisr[i].status] == status_score[rfctl->cisr[new_ecisr_id].status]
16956 && ori_ecisr_id != CONFIG_IFACE_NUMBER
16957 && rfctl->cisr[ori_ecisr_id].status == rfctl->cisr[new_ecisr_id].status
16958 && _rtw_memcmp(rfctl->cisr[ori_ecisr_id].alpha2, rfctl->cisr[new_ecisr_id].alpha2, 2) == _FALSE
16959 && _rtw_memcmp(rfctl->cisr[ori_ecisr_id].alpha2, rfctl->cisr[i].alpha2, 2) == _TRUE)
16960 )
16961 new_ecisr_id = i;
16962 }
16963
16964 rfctl->effected_cisr_id = new_ecisr_id;
16965
16966 if (rfctl->effected_cisr_id == CONFIG_IFACE_NUMBER) {
16967 /* no country IE setting */
16968 const char *alpha2;
16969
16970 if (strncmp(rfctl->user_alpha2, "\x00\x00", 2) != 0) {
16971 /* restore to user setting */
16972 param->inr = RTW_REGD_SET_BY_USER;
16973 alpha2 = rfctl->user_alpha2;
16974 param->channel_plan = rfctl->user_ChannelPlan;
16975 #if CONFIG_IEEE80211_BAND_6GHZ
16976 param->channel_plan_6g = rfctl->user_chplan_6g;
16977 #endif
16978 } else {
16979 /* restore to init setting */
16980 param->inr = RTW_REGD_SET_BY_INIT;
16981 alpha2 = rfctl->init_alpha2;
16982 param->channel_plan = rfctl->init_ChannelPlan;
16983 #if CONFIG_IEEE80211_BAND_6GHZ
16984 param->channel_plan_6g = rfctl->init_chplan_6g;
16985 #endif
16986 }
16987
16988 if (IS_ALPHA2_UNSPEC(alpha2) || IS_ALPHA2_WORLDWIDE(alpha2))
16989 param->has_country = 0;
16990 else if (rtw_get_chplan_from_country(alpha2, ¶m->country_ent)) {
16991 param->channel_plan = param->country_ent.chplan;
16992 #if CONFIG_IEEE80211_BAND_6GHZ
16993 param->channel_plan_6g = param->country_ent.chplan_6g;
16994 #endif
16995 param->has_country = 1;
16996 } else {
16997 RTW_WARN("%s unexpected country_code:\"%c%c\", set to \"00\"\n", caller, alpha2[0], alpha2[1]);
16998 rtw_warn_on(1);
16999 rtw_get_chplan_worldwide(¶m->country_ent);
17000 param->channel_plan = param->country_ent.chplan;
17001 #if CONFIG_IEEE80211_BAND_6GHZ
17002 param->channel_plan_6g = param->country_ent.chplan_6g;
17003 #endif
17004 param->has_country = 1;
17005 }
17006 param->has_cisr = 0;
17007
17008 get_str_of_set_chplan_keys(buf, 32, param);
17009 RTW_INFO("%s restore inr:%s %s\n", caller, regd_inr_str(param->inr), buf);
17010 }
17011 else {
17012 /* has country IE setting */
17013 if (ori_ecisr_id != CONFIG_IFACE_NUMBER) {
17014 /* has country IE setting originally */
17015 if (_rtw_memcmp(&ori_ecisr, &rfctl->cisr[new_ecisr_id], sizeof(ori_ecisr)) == _TRUE) {
17016 /* same record content, no effect */
17017 effected = 0;
17018 goto exit;
17019 }
17020 }
17021 rtw_get_chplan_from_cisrs(rfctl, ¶m->country_ent, caller);
17022 param->channel_plan = param->country_ent.chplan;
17023 #if CONFIG_IEEE80211_BAND_6GHZ
17024 param->channel_plan_6g = param->country_ent.chplan_6g;
17025 #endif
17026 param->has_country = 1;
17027 param->has_cisr = 0;
17028
17029 get_str_of_set_chplan_keys(buf, 32, param);
17030 RTW_INFO("%s trigger inr:%s %s\n", caller, regd_inr_str(param->inr), buf);
17031 }
17032 }
17033
17034 exit:
17035 #ifdef CONFIG_RTW_DEBUG
17036 if (rtw_drv_log_level >= _DRV_DEBUG_) {
17037 RTW_PRINT("%s cisr after\n", caller);
17038 dump_country_ie_slave_records(RTW_DBGDUMP, rfctl, 0);
17039 }
17040 #endif
17041
17042 return effected;
17043 }
17044 #endif /* CONFIG_80211D */
17045
rtw_chplan_rtk_priv_req_prehdl_domain_code(_adapter * adapter,struct SetChannelPlan_param * param,const char * caller)17046 static bool rtw_chplan_rtk_priv_req_prehdl_domain_code(_adapter *adapter, struct SetChannelPlan_param *param, const char *caller)
17047 {
17048 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
17049
17050 /* disallow invalid input */
17051 if ((param->channel_plan != RTW_CHPLAN_UNSPECIFIED
17052 && !rtw_is_channel_plan_valid(param->channel_plan))
17053 ) {
17054 RTW_WARN("%s invalid chplan:0x%02X\n", caller, param->channel_plan);
17055 return _FAIL;
17056 }
17057
17058 #if CONFIG_IEEE80211_BAND_6GHZ
17059 if (param->channel_plan_6g != RTW_CHPLAN_6G_UNSPECIFIED
17060 && !rtw_is_channel_plan_6g_valid(param->channel_plan_6g)
17061 ) {
17062 RTW_WARN("%s invalid chplan_6g:0x%02X\n", caller, param->channel_plan_6g);
17063 return _FAIL;
17064 }
17065 #endif
17066
17067 /* use original value when unspecified */
17068 if (param->channel_plan == RTW_CHPLAN_UNSPECIFIED)
17069 param->channel_plan = rfctl->ChannelPlan;
17070 #if CONFIG_IEEE80211_BAND_6GHZ
17071 if (param->channel_plan_6g == RTW_CHPLAN_6G_UNSPECIFIED)
17072 param->channel_plan_6g = rfctl->chplan_6g;
17073 #endif
17074
17075 return _SUCCESS;
17076 }
17077
rtw_chplan_rtk_priv_req_prehdl_country_ent(struct SetChannelPlan_param * param)17078 static void rtw_chplan_rtk_priv_req_prehdl_country_ent(struct SetChannelPlan_param *param)
17079 {
17080 if (!param->has_country) {
17081 u8 chplan_6g = RTW_CHPLAN_6G_NULL;
17082
17083 #if CONFIG_IEEE80211_BAND_6GHZ
17084 chplan_6g = param->channel_plan_6g;
17085 #endif
17086
17087 if (rtw_chplan_ids_is_world_wide(param->channel_plan, chplan_6g))
17088 rtw_get_chplan_worldwide(¶m->country_ent);
17089 else {
17090 SET_UNSPEC_ALPHA2(param->country_ent.alpha2);
17091 param->country_ent.edcca_mode_2g_override = RTW_EDCCA_DEF;
17092 #if CONFIG_IEEE80211_BAND_5GHZ
17093 param->country_ent.edcca_mode_5g_override = RTW_EDCCA_DEF;
17094 #endif
17095 #if CONFIG_IEEE80211_BAND_6GHZ
17096 param->country_ent.edcca_mode_6g_override = RTW_EDCCA_DEF;
17097 #endif
17098 param->country_ent.txpwr_lmt_override = TXPWR_LMT_DEF;
17099 #if defined(CONFIG_80211AX_HE) || defined(CONFIG_80211AC_VHT)
17100 param->country_ent.proto_en = CHPLAN_PROTO_EN_ALL;
17101 #endif
17102 }
17103 param->has_country = 1;
17104 }
17105 }
17106
rtw_set_chplan_hdl(_adapter * padapter,unsigned char * pbuf)17107 u8 rtw_set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
17108 {
17109 struct SetChannelPlan_param *param;
17110 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
17111 bool effected = 1;
17112 char buf[32];
17113 enum rtw_regd_inr ori_inr;
17114 #ifdef CONFIG_IOCTL_CFG80211
17115 struct get_chplan_resp *chplan;
17116 #endif
17117
17118 if (!pbuf)
17119 return H2C_PARAMETERS_ERROR;
17120
17121 param = (struct SetChannelPlan_param *)pbuf;
17122 ori_inr = param->inr;
17123
17124 get_str_of_set_chplan_keys(buf, 32, param);
17125 RTW_INFO("%s iface_id:%u src:%s inr:%s %s\n", __func__, padapter->iface_id
17126 , regd_src_str(param->regd_src), regd_inr_str(param->inr), buf);
17127
17128 /* check input parameter */
17129 if (param->regd_src == REGD_SRC_RTK_PRIV) {
17130 #ifdef CONFIG_80211D
17131 effected = rtw_chplan_rtk_priv_req_prehdl_country_ie(padapter, param, __func__);
17132 #endif
17133
17134 if (rtw_chplan_rtk_priv_req_prehdl_domain_code(padapter, param, __func__) != _SUCCESS)
17135 return H2C_PARAMETERS_ERROR;
17136
17137 rtw_chplan_rtk_priv_req_prehdl_country_ent(param);
17138 }
17139
17140 rtw_warn_on(!param->has_country);
17141
17142 if (param->inr == RTW_REGD_SET_BY_USER) {
17143 rfctl->user_alpha2[0] = param->country_ent.alpha2[0];
17144 rfctl->user_alpha2[1] = param->country_ent.alpha2[1];
17145 rfctl->user_ChannelPlan = param->channel_plan;
17146 #if CONFIG_IEEE80211_BAND_6GHZ
17147 rfctl->user_chplan_6g = param->channel_plan_6g;
17148 #endif
17149 }
17150
17151 if (!effected)
17152 goto exit;
17153
17154 rfctl->regd_src = param->regd_src;
17155 rfctl->regd_inr = param->inr;
17156 rfctl->alpha2[0] = param->country_ent.alpha2[0];
17157 rfctl->alpha2[1] = param->country_ent.alpha2[1];
17158 rfctl->edcca_mode_2g_override = param->country_ent.edcca_mode_2g_override;
17159 #if CONFIG_IEEE80211_BAND_5GHZ
17160 rfctl->edcca_mode_5g_override = param->country_ent.edcca_mode_5g_override;
17161 #endif
17162 #if CONFIG_IEEE80211_BAND_6GHZ
17163 rfctl->edcca_mode_6g_override = param->country_ent.edcca_mode_6g_override;
17164 #endif
17165 #if CONFIG_TXPWR_LIMIT
17166 rfctl->txpwr_lmt_override = param->country_ent.txpwr_lmt_override;
17167 #endif
17168 #if defined(CONFIG_80211AX_HE) || defined(CONFIG_80211AC_VHT)
17169 rfctl->proto_en = param->country_ent.proto_en;
17170 #endif
17171
17172 rfctl->ChannelPlan = param->channel_plan;
17173 #if CONFIG_IEEE80211_BAND_6GHZ
17174 rfctl->chplan_6g = param->channel_plan_6g;
17175 #endif
17176
17177 #if CONFIG_TXPWR_LIMIT
17178 rtw_txpwr_init_regd(rfctl);
17179 #endif
17180
17181 rtw_edcca_mode_update(rfctl_to_dvobj(rfctl));
17182 rtw_odm_adaptivity_update(rfctl_to_dvobj(rfctl));
17183
17184 rtw_rfctl_chplan_init(padapter);
17185
17186 #ifdef CONFIG_IOCTL_CFG80211
17187 if (rfctl->regd_src != REGD_SRC_OS)
17188 rtw_chset_hook_os_channels(rfctl);
17189
17190 if (rtw_get_chplan_cmd(padapter, RTW_CMDF_DIRECTLY, &chplan) == _SUCCESS) {
17191 if (!param->rtnl_lock_needed)
17192 rtw_regd_change_complete_sync(adapter_to_wiphy(padapter), chplan, 0);
17193 else
17194 rtw_warn_on(rtw_regd_change_complete_async(adapter_to_wiphy(padapter), chplan) != _SUCCESS);
17195 } else
17196 rtw_warn_on(1);
17197 #endif
17198
17199 rtw_nlrtw_reg_change_event(padapter);
17200
17201 #ifdef CONFIG_LPS
17202 LPS_Leave(padapter, "SET_CHPLAN");
17203 #endif
17204
17205 if (GET_HAL_DATA(padapter)->txpwr_limit_loaded
17206 && rtw_get_hw_init_completed(padapter))
17207 rtw_hal_update_txpwr_level(padapter);
17208
17209 exit:
17210 return H2C_SUCCESS;
17211 }
17212
rtw_get_chplan_hdl(_adapter * padapter,unsigned char * pbuf)17213 u8 rtw_get_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
17214 {
17215 struct get_channel_plan_param *param;
17216 struct get_chplan_resp *chplan;
17217 struct rf_ctl_t *rfctl;
17218 int i;
17219
17220 if (!pbuf)
17221 return H2C_PARAMETERS_ERROR;
17222
17223 rfctl = adapter_to_rfctl(padapter);
17224 param = (struct get_channel_plan_param *)pbuf;
17225
17226 chplan = rtw_vmalloc(sizeof(struct get_chplan_resp) + sizeof(RT_CHANNEL_INFO) * rfctl->max_chan_nums);
17227 if (!chplan)
17228 return H2C_CMD_FAIL;
17229
17230 chplan->regd_src = rfctl->regd_src;
17231 chplan->regd_inr = rfctl->regd_inr;
17232
17233 chplan->alpha2[0] = rfctl->alpha2[0];
17234 chplan->alpha2[1] = rfctl->alpha2[1];
17235
17236 chplan->channel_plan = rfctl->ChannelPlan;
17237 #if CONFIG_IEEE80211_BAND_6GHZ
17238 chplan->chplan_6g = rfctl->chplan_6g;
17239 #endif
17240 #if CONFIG_TXPWR_LIMIT
17241 for (i = 0; i < BAND_MAX; i++)
17242 chplan->txpwr_lmt_name[i] = rfctl->txpwr_lmt_name[i];
17243 #endif
17244 chplan->edcca_mode_2g = rfctl->edcca_mode_2g;
17245 #if CONFIG_IEEE80211_BAND_5GHZ
17246 chplan->edcca_mode_5g = rfctl->edcca_mode_5g;
17247 #endif
17248 #if CONFIG_IEEE80211_BAND_6GHZ
17249 chplan->edcca_mode_6g = rfctl->edcca_mode_6g;
17250 #endif
17251 #ifdef CONFIG_DFS_MASTER
17252 chplan->dfs_domain = rtw_rfctl_get_dfs_domain(rfctl);
17253 #endif
17254
17255 chplan->proto_en = 0
17256 #if defined(CONFIG_80211AX_HE) || defined(CONFIG_80211AC_VHT)
17257 | rfctl->proto_en
17258 #endif
17259 ;
17260
17261 chplan->chset_num = rfctl->max_chan_nums;
17262 _rtw_memcpy(chplan->chset, rfctl->channel_set, sizeof(RT_CHANNEL_INFO) * rfctl->max_chan_nums);
17263 *param->chplan = chplan;
17264
17265 return H2C_SUCCESS;
17266 }
17267
led_blink_hdl(_adapter * padapter,unsigned char * pbuf)17268 u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
17269 {
17270 struct LedBlink_param *ledBlink_param;
17271
17272 if (!pbuf)
17273 return H2C_PARAMETERS_ERROR;
17274
17275 ledBlink_param = (struct LedBlink_param *)pbuf;
17276
17277 #ifdef CONFIG_RTW_LED_HANDLED_BY_CMD_THREAD
17278 BlinkHandler((PLED_DATA)ledBlink_param->pLed);
17279 #endif
17280
17281 return H2C_SUCCESS;
17282 }
17283
csa_timer_hdl(void * FunctionContext)17284 void csa_timer_hdl(void *FunctionContext)
17285 {
17286 _adapter *padapter = (_adapter *)FunctionContext;
17287 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
17288 struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj);
17289 u8 i;
17290
17291 for (i = 0; i < dvobj->iface_nums; i++) {
17292 _adapter *iface;
17293 iface = dvobj->padapters[i];
17294 if (!iface)
17295 continue;
17296 if (check_fwstate(&(iface->mlmepriv), WIFI_CSA_UPDATE_BEACON)) {
17297 clr_fwstate(&(iface->mlmepriv), WIFI_CSA_UPDATE_BEACON);
17298 RTW_INFO(FUNC_ADPT_FMT" wait beacons more than 70 seconds\n", FUNC_ADPT_ARG(iface));
17299 return;
17300 }
17301 }
17302
17303 if (rfctl->csa_ch == 0) {
17304 RTW_INFO("channel switch done\n");
17305 return ;
17306 }
17307
17308 /* channel switch */
17309 if (rtw_set_csa_cmd(padapter) != _SUCCESS) {
17310 rfctl->csa_ch = 0;
17311 rfctl->csa_switch_cnt = 0;
17312 rfctl->csa_ch_offset = 0;
17313 rfctl->csa_ch_width = 0;
17314 rfctl->csa_ch_freq_seg0 = 0;
17315 rfctl->csa_ch_freq_seg1 = 0;
17316 }
17317 }
17318
set_csa_hdl(_adapter * adapter,unsigned char * pbuf)17319 u8 set_csa_hdl(_adapter *adapter, unsigned char *pbuf)
17320 {
17321 #if CONFIG_DFS
17322 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
17323
17324 if (rfctl->csa_ch)
17325 rtw_dfs_ch_switch_hdl(adapter_to_dvobj(adapter));
17326 #endif
17327 return H2C_SUCCESS;
17328 }
17329
set_ap_csa_hdl(_adapter * adapter,unsigned char * pbuf)17330 u8 set_ap_csa_hdl(_adapter *adapter, unsigned char *pbuf)
17331 {
17332 #ifdef CONFIG_AP_MODE
17333 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
17334 u8 ifbmp_m = rtw_mi_get_ap_mesh_ifbmp(adapter);
17335 u8 enable = 1;
17336 int i;
17337 _adapter *iface;
17338
17339 for (i = 0; i < dvobj->iface_nums; i++) {
17340 iface = dvobj->padapters[i];
17341 if (!iface || !(ifbmp_m & BIT(iface->iface_id)))
17342 continue;
17343 RTW_INFO("%s, HW_VAR_BCN_EARLY_C2H_RPT enable=%d\n", __FUNCTION__, enable);
17344 rtw_hal_set_hwreg(iface, HW_VAR_BCN_EARLY_C2H_RPT, &enable);
17345 }
17346 #endif
17347 return H2C_SUCCESS;
17348 }
17349
tdls_hdl(_adapter * padapter,unsigned char * pbuf)17350 u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
17351 {
17352 #ifdef CONFIG_TDLS
17353 _irqL irqL;
17354 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
17355 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
17356 #ifdef CONFIG_TDLS_CH_SW
17357 struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
17358 #endif
17359 struct TDLSoption_param *TDLSoption;
17360 struct sta_info *ptdls_sta = NULL;
17361 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
17362 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
17363 struct sta_info *ap_sta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(&(pmlmeinfo->network)));
17364 u8 survey_channel, i, min, option;
17365 struct tdls_txmgmt txmgmt;
17366 u32 setchtime, resp_sleep = 0, wait_time;
17367 u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
17368 u8 ret;
17369 u8 doiqk;
17370 u64 tx_ra_bitmap = 0;
17371
17372 if (!pbuf)
17373 return H2C_PARAMETERS_ERROR;
17374
17375 TDLSoption = (struct TDLSoption_param *)pbuf;
17376 option = TDLSoption->option;
17377
17378 if (!_rtw_memcmp(TDLSoption->addr, zaddr, ETH_ALEN)) {
17379 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), TDLSoption->addr);
17380 if (ptdls_sta == NULL)
17381 return H2C_REJECTED;
17382 } else {
17383 if (!(option == TDLS_RS_RCR))
17384 return H2C_REJECTED;
17385 }
17386
17387 /* _enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); */
17388 /* RTW_INFO("[%s] option:%d\n", __FUNCTION__, option); */
17389
17390 switch (option) {
17391 case TDLS_ESTABLISHED: {
17392 /* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
17393 /* So we can receive all kinds of data frames. */
17394 u8 sta_band = 0;
17395
17396 /* leave ALL PS when TDLS is established */
17397 rtw_pwr_wakeup(padapter);
17398
17399 rtw_hal_rcr_set_chk_bssid(padapter, MLME_TDLS_LINKED);
17400 RTW_INFO("Created Direct Link with "MAC_FMT"\n", MAC_ARG(ptdls_sta->cmn.mac_addr));
17401
17402 /* Set TDLS sta rate. */
17403 /* Update station supportRate */
17404 rtw_hal_update_sta_ra_info(padapter, ptdls_sta);
17405 tx_ra_bitmap = ptdls_sta->cmn.ra_info.ramask;
17406
17407 if (pmlmeext->cur_channel > 14) {
17408 if (tx_ra_bitmap & 0xffff000)
17409 sta_band |= WIRELESS_11_5N ;
17410
17411 if (tx_ra_bitmap & 0xff0)
17412 sta_band |= WIRELESS_11A;
17413
17414 /* 5G band */
17415 #ifdef CONFIG_80211AC_VHT
17416 if (ptdls_sta->vhtpriv.vht_option)
17417 sta_band = WIRELESS_11_5AC;
17418 #endif
17419
17420 } else {
17421 if (tx_ra_bitmap & 0xffff000)
17422 sta_band |= WIRELESS_11_24N;
17423
17424 if (tx_ra_bitmap & 0xff0)
17425 sta_band |= WIRELESS_11G;
17426
17427 if (tx_ra_bitmap & 0x0f)
17428 sta_band |= WIRELESS_11B;
17429 }
17430 ptdls_sta->wireless_mode = sta_band;
17431 rtw_hal_update_sta_wset(padapter, ptdls_sta);
17432 /* Sta mode */
17433 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, ptdls_sta, _TRUE);
17434
17435 set_sta_rate(padapter, ptdls_sta);
17436 rtw_sta_media_status_rpt(padapter, ptdls_sta, 1);
17437 break;
17438 }
17439 case TDLS_ISSUE_PTI:
17440 ptdls_sta->tdls_sta_state |= TDLS_WAIT_PTR_STATE;
17441 issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
17442 _set_timer(&ptdls_sta->pti_timer, TDLS_PTI_TIME);
17443 break;
17444 #ifdef CONFIG_TDLS_CH_SW
17445 case TDLS_CH_SW_RESP:
17446 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
17447 txmgmt.status_code = 0;
17448 _rtw_memcpy(txmgmt.peer, ptdls_sta->cmn.mac_addr, ETH_ALEN);
17449
17450 if (ap_sta)
17451 rtw_hal_macid_sleep(padapter, ap_sta->cmn.mac_id);
17452 issue_nulldata(padapter, NULL, 1, 3, 3);
17453
17454 RTW_INFO("[TDLS ] issue tdls channel switch response\n");
17455 ret = issue_tdls_ch_switch_rsp(padapter, &txmgmt, _TRUE);
17456
17457 /* If we receive TDLS_CH_SW_REQ at off channel which it's target is AP's channel */
17458 /* then we just switch to AP's channel*/
17459 if (padapter->mlmeextpriv.cur_channel == pchsw_info->off_ch_num) {
17460 rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_END_TO_BASE_CHNL);
17461 break;
17462 }
17463
17464 if (ret == _SUCCESS)
17465 rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_TO_OFF_CHNL);
17466 else
17467 RTW_INFO("[TDLS] issue_tdls_ch_switch_rsp wait ack fail !!!!!!!!!!\n");
17468
17469 break;
17470 case TDLS_CH_SW_PREPARE:
17471 pchsw_info->ch_sw_state |= TDLS_CH_SWITCH_PREPARE_STATE;
17472
17473 /* to collect IQK info of off-chnl */
17474 doiqk = _TRUE;
17475 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
17476 set_channel_bwmode(padapter, pchsw_info->off_ch_num, pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20);
17477 doiqk = _FALSE;
17478 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
17479
17480 /* switch back to base-chnl */
17481 doiqk = _TRUE;
17482 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
17483 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
17484 doiqk = _FALSE;
17485 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
17486
17487 rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START);
17488
17489 pchsw_info->ch_sw_state &= ~(TDLS_CH_SWITCH_PREPARE_STATE);
17490
17491 break;
17492 case TDLS_CH_SW_START:
17493 rtw_tdls_set_ch_sw_oper_control(padapter, _TRUE);
17494 break;
17495 case TDLS_CH_SW_TO_OFF_CHNL:
17496 if (ap_sta)
17497 rtw_hal_macid_sleep(padapter, ap_sta->cmn.mac_id);
17498 issue_nulldata(padapter, NULL, 1, 3, 3);
17499
17500 if (padapter->registrypriv.wifi_spec == 0) {
17501 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
17502 _set_timer(&ptdls_sta->ch_sw_timer, (u32)(ptdls_sta->ch_switch_timeout) / 1000);
17503 }
17504
17505 if (rtw_tdls_do_ch_sw(padapter, ptdls_sta, TDLS_CH_SW_OFF_CHNL, pchsw_info->off_ch_num,
17506 pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20, ptdls_sta->ch_switch_time) == _SUCCESS) {
17507 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
17508 if (pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) {
17509 if (issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->cmn.mac_addr, 0, 1,
17510 (padapter->registrypriv.wifi_spec == 0) ? 3 : 0) == _FAIL)
17511 rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_TO_BASE_CHNL);
17512 }
17513 } else {
17514 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
17515 _cancel_timer_ex(&ptdls_sta->ch_sw_timer);
17516 }
17517
17518
17519 break;
17520 case TDLS_CH_SW_END:
17521 case TDLS_CH_SW_END_TO_BASE_CHNL:
17522 rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
17523 _cancel_timer_ex(&ptdls_sta->ch_sw_timer);
17524 _cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);
17525 _cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
17526 #if 0
17527 _rtw_memset(pHalData->tdls_ch_sw_iqk_info_base_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_base_chnl));
17528 _rtw_memset(pHalData->tdls_ch_sw_iqk_info_off_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_off_chnl));
17529 #endif
17530
17531 if (option == TDLS_CH_SW_END_TO_BASE_CHNL)
17532 rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_TO_BASE_CHNL);
17533
17534 break;
17535 case TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED:
17536 case TDLS_CH_SW_TO_BASE_CHNL:
17537 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE | TDLS_WAIT_CH_RSP_STATE);
17538
17539 if (option == TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED) {
17540 if (ptdls_sta != NULL) {
17541 /* Send unsolicited channel switch rsp. to peer */
17542 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
17543 txmgmt.status_code = 0;
17544 _rtw_memcpy(txmgmt.peer, ptdls_sta->cmn.mac_addr, ETH_ALEN);
17545 issue_tdls_ch_switch_rsp(padapter, &txmgmt, _FALSE);
17546 }
17547 }
17548
17549 if (rtw_tdls_do_ch_sw(padapter, ptdls_sta, TDLS_CH_SW_BASE_CHNL, pmlmeext->cur_channel,
17550 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode, ptdls_sta->ch_switch_time) == _SUCCESS) {
17551 if (ap_sta)
17552 rtw_hal_macid_wakeup(padapter, ap_sta->cmn.mac_id);
17553 issue_nulldata(padapter, NULL, 0, 3, 3);
17554 /* set ch sw monitor timer for responder */
17555 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
17556 _set_timer(&ptdls_sta->ch_sw_monitor_timer, TDLS_CH_SW_MONITOR_TIMEOUT);
17557 }
17558
17559 break;
17560 #endif
17561 case TDLS_RS_RCR:
17562 rtw_hal_rcr_set_chk_bssid(padapter, MLME_TDLS_NOLINK);
17563 break;
17564 case TDLS_TEARDOWN_STA:
17565 case TDLS_TEARDOWN_STA_NO_WAIT:
17566 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
17567 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
17568 _rtw_memcpy(txmgmt.peer, ptdls_sta->cmn.mac_addr, ETH_ALEN);
17569
17570 issue_tdls_teardown(padapter, &txmgmt, (option == TDLS_TEARDOWN_STA) ? _TRUE : _FALSE);
17571
17572 break;
17573 case TDLS_TEARDOWN_STA_LOCALLY:
17574 case TDLS_TEARDOWN_STA_LOCALLY_POST:
17575 #ifdef CONFIG_TDLS_CH_SW
17576 if (_rtw_memcmp(TDLSoption->addr, pchsw_info->addr, ETH_ALEN) == _TRUE) {
17577 pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
17578 TDLS_CH_SWITCH_ON_STATE |
17579 TDLS_PEER_AT_OFF_STATE);
17580 rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
17581 _rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
17582 }
17583 #endif
17584
17585 if (option == TDLS_TEARDOWN_STA_LOCALLY)
17586 rtw_tdls_teardown_pre_hdl(padapter, ptdls_sta);
17587
17588 rtw_tdls_teardown_post_hdl(padapter, ptdls_sta, _FALSE);
17589
17590 if (ptdlsinfo->tdls_sctx != NULL)
17591 rtw_sctx_done(&(ptdlsinfo->tdls_sctx));
17592
17593 break;
17594 }
17595
17596 /* _exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); */
17597
17598 return H2C_SUCCESS;
17599 #else
17600 return H2C_REJECTED;
17601 #endif /* CONFIG_TDLS */
17602
17603 }
17604
run_in_thread_hdl(_adapter * padapter,u8 * pbuf)17605 u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf)
17606 {
17607 struct RunInThread_param *p;
17608
17609
17610 if (NULL == pbuf)
17611 return H2C_PARAMETERS_ERROR;
17612 p = (struct RunInThread_param *)pbuf;
17613
17614 if (p->func)
17615 p->func(p->context);
17616
17617 return H2C_SUCCESS;
17618 }
17619
rtw_sae_preprocess(_adapter * adapter,const u8 * buf,u32 len,u8 tx)17620 int rtw_sae_preprocess(_adapter *adapter, const u8 *buf, u32 len, u8 tx)
17621 {
17622 #ifdef CONFIG_IOCTL_CFG80211
17623 const u8 *frame_body = buf + sizeof(struct rtw_ieee80211_hdr_3addr);
17624 u16 alg;
17625 u16 seq;
17626 u16 status;
17627 int ret = _FAIL;
17628
17629 alg = RTW_GET_LE16(frame_body);
17630 if (alg != WLAN_AUTH_SAE)
17631 goto exit;
17632
17633 seq = RTW_GET_LE16(frame_body + 2);
17634 status = RTW_GET_LE16(frame_body + 4);
17635
17636 RTW_INFO("RTW_%s:AUTH alg:0x%04x, seq:0x%04x, status:0x%04x, mesg:%s\n",
17637 (tx == _TRUE) ? "Tx" : "Rx", alg, seq, status,
17638 (seq == 1) ? "Commit" : "Confirm");
17639
17640 ret = _SUCCESS;
17641
17642 #ifdef CONFIG_RTW_MESH
17643 if (MLME_IS_MESH(adapter)) {
17644 rtw_mesh_sae_check_frames(adapter, buf, len, tx, alg, seq, status);
17645 goto exit;
17646 }
17647 #endif
17648
17649 if (tx && (seq == 2) && (status == 0)) {
17650 /* quere commit frame until external auth statue update */
17651 struct sta_priv *pstapriv = &adapter->stapriv;
17652 struct sta_info *psta = NULL;
17653 _irqL irqL;
17654
17655 psta = rtw_get_stainfo(pstapriv, GetAddr1Ptr(buf));
17656 if (psta) {
17657 _enter_critical_bh(&psta->lock, &irqL);
17658 if (psta->pauth_frame) {
17659 rtw_mfree(psta->pauth_frame, psta->auth_len);
17660 psta->pauth_frame = NULL;
17661 psta->auth_len = 0;
17662 }
17663
17664 psta->pauth_frame = rtw_zmalloc(len);
17665 if (psta->pauth_frame) {
17666 _rtw_memcpy(psta->pauth_frame, buf, len);
17667 psta->auth_len = len;
17668 }
17669 _exit_critical_bh(&psta->lock, &irqL);
17670
17671 ret = 2;
17672 }
17673 }
17674 exit:
17675 return ret;
17676 #else
17677 return _SUCCESS;
17678 #endif /* CONFIG_IOCTL_CFG80211 */
17679 }
17680
17681 /* Needs to confirm with FW the value of REG_RX_BEACON_LENGTH */
rtw_write_bcnlen_hdl(_adapter * padapter,u8 * pbuf)17682 u8 rtw_write_bcnlen_hdl(_adapter *padapter, u8 *pbuf)
17683 {
17684 #ifdef CONFIG_WRITE_BCN_LEN_TO_FW
17685 struct write_bcnlen_param *parm = (struct write_bcnlen_param *)pbuf;
17686 u16 bcn_len = parm->bcn_len;
17687
17688 rtw_write16(padapter, REG_RX_BEACON_LENGTH + 2, bcn_len);
17689 #endif
17690 return H2C_SUCCESS;
17691 }
17692
rtw_reqtxrpt_cmd_hdl(_adapter * adapter,u8 * pbuf)17693 u8 rtw_reqtxrpt_cmd_hdl(_adapter *adapter, u8 *pbuf)
17694 {
17695 struct reqtxrpt_param *parm = (struct reqtxrpt_param *)pbuf;
17696
17697 rtw_hal_reqtxrpt(adapter, parm->macid);
17698
17699 return H2C_SUCCESS;
17700 }
17701
17702