1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
14 ******************************************************************************/
15 #define _RTW_MLME_EXT_C_
17 #include <osdep_service.h>
18 #include <drv_types.h>
20 #include <rtw_mlme_ext.h>
21 #include <wlan_bssdef.h>
22 #include <mlme_osdep.h>
23 #include <recv_osdep.h>
24 #include <linux/ieee80211.h>
25 #include <rtl8723a_hal.h>
27 static int OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
28 static int OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
29 static int OnProbeReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
30 static int OnProbeRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
31 static int DoReserved23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
32 static int OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
33 static int OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
34 static int OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
35 static int OnAuth23aClient23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
36 static int OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
37 static int OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
39 static int on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
40 static int OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
41 static int OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
42 static int OnAction23a_back23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
43 static int on_action_public23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
44 static int OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
45 static int OnAction23a_wmm(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
46 static int OnAction23a_p2p(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
48 static void issue_assocreq(struct rtw_adapter *padapter);
49 static void issue_probereq(struct rtw_adapter *padapter,
50 struct cfg80211_ssid *pssid, u8 *da);
51 static int issue_probereq_ex(struct rtw_adapter *padapter,
52 struct cfg80211_ssid *pssid,
53 u8 *da, int try_cnt, int wait_ms);
54 static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da,
55 u8 is_valid_p2p_probereq);
56 static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
57 unsigned short status);
58 static int issue_deauth_ex(struct rtw_adapter *padapter, u8 *da,
59 unsigned short reason, int try_cnt, int wait_ms);
60 static void start_clnt_assoc(struct rtw_adapter *padapter);
61 static void start_clnt_auth(struct rtw_adapter *padapter);
62 static void start_clnt_join(struct rtw_adapter *padapter);
63 static void start_create_ibss(struct rtw_adapter *padapter);
64 static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter,
65 struct recv_frame *precv_frame);
67 #ifdef CONFIG_8723AU_AP_MODE
68 static int OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
69 static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
70 struct sta_info *pstat, u16 pkt_type);
73 static struct mlme_handler mlme_sta_tbl[]={
74 {"OnAssocReq23a", &OnAssocReq23a},
75 {"OnAssocRsp23a", &OnAssocRsp23a},
76 {"OnReAssocReq", &OnAssocReq23a},
77 {"OnReAssocRsp", &OnAssocRsp23a},
78 {"OnProbeReq23a", &OnProbeReq23a},
79 {"OnProbeRsp23a", &OnProbeRsp23a},
81 /*----------------------------------------------------------
83 -----------------------------------------------------------*/
84 {"DoReserved23a", &DoReserved23a},
85 {"DoReserved23a", &DoReserved23a},
86 {"OnBeacon23a", &OnBeacon23a},
87 {"OnATIM", &OnAtim23a},
88 {"OnDisassoc23a", &OnDisassoc23a},
89 {"OnAuth23a", &OnAuth23aClient23a},
90 {"OnDeAuth23a", &OnDeAuth23a},
91 {"OnAction23a", &OnAction23a},
94 static struct action_handler OnAction23a_tbl[]={
95 {WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct23a},
96 {WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction23a_qos},
97 {WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction23a_dls},
98 {WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction23a_back23a},
99 {WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public23a},
100 {WLAN_CATEGORY_HT, "ACTION_HT", &OnAction23a_ht},
101 {WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved23a},
102 {WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction23a_wmm},
103 {WLAN_CATEGORY_VENDOR_SPECIFIC, "ACTION_P2P", &OnAction23a_p2p},
106 static u8 null_addr[ETH_ALEN]= {0, 0, 0, 0, 0, 0};
108 /**************************************************
109 OUI definitions for the vendor specific IE
110 ***************************************************/
111 unsigned char WMM_OUI23A[] = {0x00, 0x50, 0xf2, 0x02};
112 unsigned char WPS_OUI23A[] = {0x00, 0x50, 0xf2, 0x04};
113 unsigned char P2P_OUI23A[] = {0x50, 0x6F, 0x9A, 0x09};
114 unsigned char WFD_OUI23A[] = {0x50, 0x6F, 0x9A, 0x0A};
116 unsigned char WMM_INFO_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
117 unsigned char WMM_PARA_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
119 static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
121 /********************************************************
123 *********************************************************/
124 unsigned char MCS_rate_2R23A[16] = {
125 0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0,
126 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
127 unsigned char MCS_rate_1R23A[16] = {
128 0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0,
129 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
131 /********************************************************
132 ChannelPlan definitions
133 *********************************************************/
135 static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
136 /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
137 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
138 /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
139 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
140 /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
141 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
142 /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
143 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
144 /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
145 {{10, 11, 12, 13}, 4},
146 /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
150 static struct rt_channel_plan_5g RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
151 /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
153 /* 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 */
154 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
155 116, 120, 124, 128, 132, 136, 140}, 19},
156 /* 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 */
157 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
158 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
159 /* 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 */
160 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
161 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22},
162 /* 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */
163 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
164 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
165 /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
166 {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},
167 /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
168 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},
169 /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
170 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12},
171 /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
172 {{149, 153, 157, 161, 165}, 5},
173 /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
174 {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
175 /* 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 */
176 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
177 116, 136, 140, 149, 153, 157, 161, 165}, 20},
178 /* 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 */
179 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
180 116, 120, 124, 149, 153, 157, 161, 165}, 20},
181 /* 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 */
182 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
183 116, 120, 124, 128, 132, 136, 140}, 19},
184 /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
185 {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
186 /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
187 {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},
188 /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
189 {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149,
190 153, 157, 161, 165}, 15},
191 /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
192 {{56, 60, 64, 149, 153, 157, 161, 165}, 8},
194 /* Driver self defined for old channel plan Compatible,
195 Remember to modify if have new channel plan definition ===== */
196 /* 0x11, RT_CHANNEL_DOMAIN_5G_FCC */
197 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
198 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},
199 /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
200 {{36, 40, 44, 48}, 4},
201 /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
202 {{36, 40, 44, 48, 149, 153, 157, 161}, 8},
205 static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
206 /* 0x00 ~ 0x1F , Old Define ===== */
207 {0x02, 0x11}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
208 {0x02, 0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
209 {0x01, 0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
210 {0x01, 0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
211 {0x01, 0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
212 {0x03, 0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
213 {0x03, 0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
214 {0x01, 0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
215 {0x03, 0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
216 {0x03, 0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
217 {0x00, 0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
218 {0x02, 0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
219 {0x01, 0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
220 {0x02, 0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
221 {0x02, 0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
222 {0x02, 0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
223 {0x01, 0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
224 {0x02, 0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
225 {0x01, 0x12}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
226 {0x00, 0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
227 {0x02, 0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
228 {0x00, 0x12}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
229 {0x00, 0x13}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
230 {0x03, 0x12}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
231 {0x05, 0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
232 {0x02, 0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
233 {0x00, 0x00}, /* 0x1A, */
234 {0x00, 0x00}, /* 0x1B, */
235 {0x00, 0x00}, /* 0x1C, */
236 {0x00, 0x00}, /* 0x1D, */
237 {0x00, 0x00}, /* 0x1E, */
238 {0x05, 0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
239 /* 0x20 ~ 0x7F , New Define ===== */
240 {0x00, 0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
241 {0x01, 0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
242 {0x02, 0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
243 {0x03, 0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
244 {0x04, 0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
245 {0x02, 0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
246 {0x00, 0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
247 {0x03, 0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
248 {0x00, 0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
249 {0x00, 0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
250 {0x00, 0x00}, /* 0x2A, */
251 {0x00, 0x00}, /* 0x2B, */
252 {0x00, 0x00}, /* 0x2C, */
253 {0x00, 0x00}, /* 0x2D, */
254 {0x00, 0x00}, /* 0x2E, */
255 {0x00, 0x00}, /* 0x2F, */
256 {0x00, 0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
257 {0x00, 0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
258 {0x00, 0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
259 {0x00, 0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
260 {0x02, 0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
261 {0x00, 0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
262 {0x00, 0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
263 {0x03, 0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
264 {0x03, 0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
265 {0x02, 0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
266 {0x00, 0x00}, /* 0x3A, */
267 {0x00, 0x00}, /* 0x3B, */
268 {0x00, 0x00}, /* 0x3C, */
269 {0x00, 0x00}, /* 0x3D, */
270 {0x00, 0x00}, /* 0x3E, */
271 {0x00, 0x00}, /* 0x3F, */
272 {0x02, 0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
273 {0x03, 0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
276 static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE =
277 {0x03, 0x02}; /* use the conbination for max channel numbers */
279 static void dummy_event_callback(struct rtw_adapter *adapter, const u8 *pbuf)
283 static struct fwevent wlanevents[] =
285 {0, &dummy_event_callback}, /*0*/
293 {0, &rtw_survey_event_cb23a}, /*8*/
294 {sizeof (struct surveydone_event), &rtw_surveydone_event_callback23a},
295 {0, &rtw23a_joinbss_event_cb}, /*10*/
296 {sizeof(struct stassoc_event), &rtw_stassoc_event_callback23a},
297 {sizeof(struct stadel_event), &rtw_stadel_event_callback23a},
298 {0, &dummy_event_callback},
299 {0, &dummy_event_callback},
304 {0, &dummy_event_callback},
308 {0, &dummy_event_callback},
313 static void rtw_correct_TSF(struct rtw_adapter *padapter)
315 hw_var_set_correct_tsf(padapter);
319 rtw_update_TSF(struct mlme_ext_priv *pmlmeext, struct ieee80211_mgmt *mgmt)
321 pmlmeext->TSFValue = get_unaligned_le64(&mgmt->u.beacon.timestamp);
325 * Search the @param channel_num in given @param channel_set
326 * @ch_set: the given channel set
327 * @ch: the given channel number
329 * return the index of channel_num in channel_set, -1 if not found
331 int rtw_ch_set_search_ch23a(struct rt_channel_info *ch_set, const u32 ch)
334 for (i = 0; ch_set[i]. ChannelNum != 0; i++) {
335 if (ch == ch_set[i].ChannelNum)
339 if (i >= ch_set[i].ChannelNum)
344 /****************************************************************************
346 Following are the initialization functions for WiFi MLME
348 *****************************************************************************/
350 int init_hw_mlme_ext23a(struct rtw_adapter *padapter)
352 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
354 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
355 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
359 static void init_mlme_ext_priv23a_value(struct rtw_adapter* padapter)
361 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
362 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
363 unsigned char mixed_datarate[NumRates] = {
364 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
365 _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_,
366 _48M_RATE_, _54M_RATE_, 0xff};
367 unsigned char mixed_basicrate[NumRates] = {
368 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
369 _12M_RATE_, _24M_RATE_, 0xff,};
371 atomic_set(&pmlmeext->event_seq, 0);
372 /* reset to zero when disconnect at client mode */
373 pmlmeext->mgnt_seq = 0;
375 pmlmeext->cur_channel = padapter->registrypriv.channel;
376 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
377 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
381 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
383 memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
384 memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
386 if (pmlmeext->cur_channel > 14)
387 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
389 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
391 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
392 pmlmeext->sitesurvey_res.channel_idx = 0;
393 pmlmeext->sitesurvey_res.bss_cnt = 0;
394 pmlmeext->scan_abort = false;
396 pmlmeinfo->state = WIFI_FW_NULL_STATE;
397 pmlmeinfo->reauth_count = 0;
398 pmlmeinfo->reassoc_count = 0;
399 pmlmeinfo->link_count = 0;
400 pmlmeinfo->auth_seq = 0;
401 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
402 pmlmeinfo->key_index = 0;
405 pmlmeinfo->enc_algo = 0;
406 pmlmeinfo->authModeToggle = 0;
408 memset(pmlmeinfo->chg_txt, 0, 128);
410 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
411 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
413 pmlmeinfo->dialogToken = 0;
415 pmlmeext->action_public_rxseq = 0xffff;
416 pmlmeext->action_public_dialog_token = 0xff;
419 static int has_channel(struct rt_channel_info *channel_set,
420 u8 chanset_size, u8 chan) {
423 for (i = 0; i < chanset_size; i++) {
424 if (channel_set[i].ChannelNum == chan)
431 static void init_channel_list(struct rtw_adapter *padapter,
432 struct rt_channel_info *channel_set,
434 struct p2p_channels *channel_list)
436 struct p2p_oper_class_map op_class[] = {
437 { IEEE80211G, 81, 1, 13, 1, BW20 },
438 { IEEE80211G, 82, 14, 14, 1, BW20 },
439 { IEEE80211A, 115, 36, 48, 4, BW20 },
440 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
441 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
442 { IEEE80211A, 124, 149, 161, 4, BW20 },
443 { IEEE80211A, 125, 149, 169, 4, BW20 },
444 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
445 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
446 { -1, 0, 0, 0, 0, BW20 }
453 for (op = 0; op_class[op].op_class; op++) {
455 struct p2p_oper_class_map *o = &op_class[op];
456 struct p2p_reg_class *reg = NULL;
458 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
459 if (!has_channel(channel_set, chanset_size, ch))
462 if ((0 == padapter->registrypriv.ht_enable) &&
466 if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) &&
467 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
471 reg = &channel_list->reg_class[cla];
473 reg->reg_class = o->op_class;
476 reg->channel[reg->channels] = ch;
480 channel_list->reg_classes = cla;
483 static u8 init_channel_set(struct rtw_adapter* padapter, u8 cplan,
484 struct rt_channel_info *c_set)
487 u8 b5GBand = false, b2_4GBand = false;
488 u8 Index2G = 0, Index5G = 0;
490 memset(c_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM);
492 if (cplan >= RT_CHANNEL_DOMAIN_MAX &&
493 cplan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) {
494 DBG_8723A("ChannelPlan ID %x error !!!!!\n", cplan);
498 if (padapter->registrypriv.wireless_mode & WIRELESS_11G) {
500 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
501 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
503 Index2G = RTW_ChannelPlanMap[cplan].Index2G;
506 if (padapter->registrypriv.wireless_mode & WIRELESS_11A) {
508 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
509 Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
511 Index5G = RTW_ChannelPlanMap[cplan].Index5G;
515 for (i = 0; i < RTW_ChannelPlan2G[Index2G].Len; i++) {
516 c_set[ch_size].ChannelNum =
517 RTW_ChannelPlan2G[Index2G].Channel[i];
519 if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == cplan) ||
520 /* Channel 1~11 is active, and 12~14 is passive */
521 RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == cplan) {
522 if (c_set[ch_size].ChannelNum >= 1 &&
523 c_set[ch_size].ChannelNum <= 11)
524 c_set[ch_size].ScanType = SCAN_ACTIVE;
525 else if (c_set[ch_size].ChannelNum >= 12 &&
526 c_set[ch_size].ChannelNum <= 14)
527 c_set[ch_size].ScanType = SCAN_PASSIVE;
528 } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == cplan ||
529 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == cplan ||
530 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) {
531 /* channel 12~13, passive scan */
532 if (c_set[ch_size].ChannelNum <= 11)
533 c_set[ch_size].ScanType = SCAN_ACTIVE;
535 c_set[ch_size].ScanType = SCAN_PASSIVE;
537 c_set[ch_size].ScanType = SCAN_ACTIVE;
544 for (i = 0; i < RTW_ChannelPlan5G[Index5G].Len; i++) {
545 if (RTW_ChannelPlan5G[Index5G].Channel[i] <= 48 ||
546 RTW_ChannelPlan5G[Index5G].Channel[i] >= 149) {
547 c_set[ch_size].ChannelNum =
548 RTW_ChannelPlan5G[Index5G].Channel[i];
549 if (RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == cplan) {
550 /* passive scan for all 5G channels */
551 c_set[ch_size].ScanType =
554 c_set[ch_size].ScanType =
556 DBG_8723A("%s(): channel_set[%d].ChannelNum = "
557 "%d\n", __func__, ch_size,
558 c_set[ch_size].ChannelNum);
567 int init_mlme_ext_priv23a(struct rtw_adapter* padapter)
570 struct registry_priv* pregistrypriv = &padapter->registrypriv;
571 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
572 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
573 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
575 pmlmeext->padapter = padapter;
577 init_mlme_ext_priv23a_value(padapter);
578 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
580 init_mlme_ext_timer23a(padapter);
582 #ifdef CONFIG_8723AU_AP_MODE
583 init_mlme_ap_info23a(padapter);
586 pmlmeext->max_chan_nums = init_channel_set(padapter,
587 pmlmepriv->ChannelPlan,
588 pmlmeext->channel_set);
589 init_channel_list(padapter, pmlmeext->channel_set,
590 pmlmeext->max_chan_nums, &pmlmeext->channel_list);
592 pmlmeext->chan_scan_time = SURVEY_TO;
593 pmlmeext->mlmeext_init = true;
595 pmlmeext->active_keep_alive_check = true;
599 void free_mlme_ext_priv23a (struct mlme_ext_priv *pmlmeext)
601 struct rtw_adapter *padapter = pmlmeext->padapter;
606 if (padapter->bDriverStopped == true) {
607 del_timer_sync(&pmlmeext->survey_timer);
608 del_timer_sync(&pmlmeext->link_timer);
609 /* del_timer_sync(&pmlmeext->ADDBA_timer); */
614 _mgt_dispatcher23a(struct rtw_adapter *padapter, struct mlme_handler *ptable,
615 struct recv_frame *precv_frame)
617 struct sk_buff *skb = precv_frame->pkt;
618 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
621 /* receive the frames that ra(a1) is my address
622 or ra(a1) is bc address. */
623 if (!ether_addr_equal(hdr->addr1, myid(&padapter->eeprompriv))&&
624 !is_broadcast_ether_addr(hdr->addr1))
627 ptable->func(padapter, precv_frame);
631 void mgt_dispatcher23a(struct rtw_adapter *padapter,
632 struct recv_frame *precv_frame)
634 struct mlme_handler *ptable;
635 #ifdef CONFIG_8723AU_AP_MODE
636 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
637 #endif /* CONFIG_8723AU_AP_MODE */
638 struct sk_buff *skb = precv_frame->pkt;
639 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
640 struct sta_info *psta;
644 if (!ieee80211_is_mgmt(mgmt->frame_control))
647 /* receive the frames that ra(a1) is my address or ra(a1) is
649 if (!ether_addr_equal(mgmt->da, myid(&padapter->eeprompriv)) &&
650 !is_broadcast_ether_addr(mgmt->da))
653 ptable = mlme_sta_tbl;
655 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
659 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
660 ("Currently we do not support reserved sub-fr-type ="
666 psta = rtw_get_stainfo23a(&padapter->stapriv, mgmt->sa);
669 if (ieee80211_has_retry(mgmt->frame_control)) {
670 if (precv_frame->attrib.seq_num ==
671 psta->RxMgmtFrameSeqNum) {
672 /* drop the duplicate management frame */
673 DBG_8723A("Drop duplicate management frame "
674 "with seq_num = %d.\n",
675 precv_frame->attrib.seq_num);
679 psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num;
682 #ifdef CONFIG_8723AU_AP_MODE
685 case IEEE80211_STYPE_AUTH:
686 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
687 ptable->func = &OnAuth23a;
689 ptable->func = &OnAuth23aClient23a;
691 case IEEE80211_STYPE_ASSOC_REQ:
692 case IEEE80211_STYPE_REASSOC_REQ:
693 _mgt_dispatcher23a(padapter, ptable, precv_frame);
695 case IEEE80211_STYPE_PROBE_REQ:
696 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
697 _mgt_dispatcher23a(padapter, ptable, precv_frame);
699 _mgt_dispatcher23a(padapter, ptable, precv_frame);
701 case IEEE80211_STYPE_BEACON:
702 _mgt_dispatcher23a(padapter, ptable, precv_frame);
704 case IEEE80211_STYPE_ACTION:
705 /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) */
706 _mgt_dispatcher23a(padapter, ptable, precv_frame);
709 _mgt_dispatcher23a(padapter, ptable, precv_frame);
713 _mgt_dispatcher23a(padapter, ptable, precv_frame);
717 /****************************************************************************
719 Following are the callback functions for each subtype of the management frames
721 *****************************************************************************/
724 OnProbeReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
727 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
728 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
729 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
730 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
731 struct sk_buff *skb = precv_frame->pkt;
732 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
735 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
738 if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
739 !check_fwstate(pmlmepriv,
740 WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
743 if (unlikely(!ieee80211_is_probe_req(mgmt->frame_control))) {
744 printk(KERN_WARNING "%s: Received non probe request frame\n",
749 len -= offsetof(struct ieee80211_mgmt, u.probe_req.variable);
751 ie = cfg80211_find_ie(WLAN_EID_SSID, mgmt->u.probe_req.variable, len);
753 /* check (wildcard) SSID */
757 if ((ie[1] && memcmp(ie + 2, cur->Ssid.ssid, cur->Ssid.ssid_len)) ||
758 (ie[1] == 0 && pmlmeinfo->hidden_ssid_mode)) {
762 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
763 pmlmepriv->cur_network.join_res)
764 issue_probersp(padapter, mgmt->sa, false);
771 OnProbeRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
773 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
775 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
776 report_survey_event23a(padapter, precv_frame);
784 OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
787 struct sta_info *psta;
788 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
789 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
790 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
791 struct sta_priv *pstapriv = &padapter->stapriv;
792 struct sk_buff *skb = precv_frame->pkt;
793 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
794 int pkt_len = skb->len;
795 struct wlan_bssid_ex *pbss;
801 pie = mgmt->u.beacon.variable;
802 pie_len = pkt_len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
803 p = rtw_get_ie23a(pie, WLAN_EID_EXT_SUPP_RATES, &ielen, pie_len);
804 if (p && ielen > 0) {
805 if (p[1 + ielen] == 0x2D && p[2 + ielen] != 0x2D) {
806 /* Invalid value 0x2D is detected in Extended Supported
807 * Rates (ESR) IE. Try to fix the IE length to avoid
808 * failed Beacon parsing.
810 DBG_8723A("[WIFIDBG] Error in ESR IE is detected in "
811 "Beacon of BSSID: %pM. Fix the length of "
812 "ESR IE to avoid failed Beacon parsing.\n",
818 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
819 report_survey_event23a(padapter, precv_frame);
823 if (!ether_addr_equal(mgmt->bssid,
824 get_my_bssid23a(&pmlmeinfo->network)))
827 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
828 /* we should update current network before auth,
829 or some IE is wrong */
830 pbss = collect_bss_info(padapter, precv_frame);
832 update_network23a(&pmlmepriv->cur_network.network, pbss,
834 rtw_get_bcn_info23a(&pmlmepriv->cur_network);
838 /* check the vendor of the assoc AP */
839 pmlmeinfo->assoc_AP_vendor =
840 check_assoc_AP23a((u8 *)&mgmt->u.beacon, pkt_len -
841 offsetof(struct ieee80211_mgmt, u));
843 /* update TSF Value */
844 rtw_update_TSF(pmlmeext, mgmt);
847 start_clnt_auth(padapter);
852 if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) &&
853 (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
854 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
856 ret = rtw_check_bcn_info23a(padapter, mgmt, pkt_len);
857 if (ret != _SUCCESS) {
858 DBG_8723A_LEVEL(_drv_always_, "ap has changed, "
860 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress, 65535);
863 /* update WMM, ERP in the beacon */
864 /* todo: the timer is used instead of
865 the number of the beacon received */
866 if ((sta_rx_pkts(psta) & 0xf) == 0) {
867 /* DBG_8723A("update_bcn_info\n"); */
868 update_beacon23a_info(padapter, mgmt,
872 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
873 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
875 /* update WMM, ERP in the beacon */
876 /* todo: the timer is used instead of the
877 number of the beacon received */
878 if ((sta_rx_pkts(psta) & 0xf) == 0) {
879 /* DBG_8723A("update_bcn_info\n"); */
880 update_beacon23a_info(padapter, mgmt,
884 /* allocate a new CAM entry for IBSS station */
885 cam_idx = allocate_fw_sta_entry23a(padapter);
886 if (cam_idx == NUM_STA)
889 /* get supported rate */
890 if (update_sta_support_rate23a(padapter, pie, pie_len,
892 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
896 /* update TSF Value */
897 rtw_update_TSF(pmlmeext, mgmt);
899 /* report sta add event */
900 report_add_sta_event23a(padapter, mgmt->sa,
910 #ifdef CONFIG_8723AU_AP_MODE
912 OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
914 static struct sta_info stat;
915 struct sta_info *pstat = NULL;
916 struct sta_priv *pstapriv = &padapter->stapriv;
917 struct security_priv *psecuritypriv = &padapter->securitypriv;
918 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
919 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
920 struct sk_buff *skb = precv_frame->pkt;
921 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
925 u16 auth_mode, seq, algorithm;
926 int status, len = skb->len;
928 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
931 DBG_8723A("+OnAuth23a\n");
935 auth_mode = psecuritypriv->dot11AuthAlgrthm;
937 pframe = mgmt->u.auth.variable;
938 len = skb->len - offsetof(struct ieee80211_mgmt, u.auth.variable);
940 seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
941 algorithm = le16_to_cpu(mgmt->u.auth.auth_alg);
943 DBG_8723A("auth alg =%x, seq =%X\n", algorithm, seq);
945 if (auth_mode == 2 &&
946 psecuritypriv->dot11PrivacyAlgrthm != WLAN_CIPHER_SUITE_WEP40 &&
947 psecuritypriv->dot11PrivacyAlgrthm != WLAN_CIPHER_SUITE_WEP104)
950 /* rx a shared-key auth but shared not enabled, or */
951 /* rx a open-system auth but shared-key is enabled */
952 if ((algorithm != WLAN_AUTH_OPEN && auth_mode == 0) ||
953 (algorithm == WLAN_AUTH_OPEN && auth_mode == 1)) {
954 DBG_8723A("auth rejected due to bad alg [alg =%d, auth_mib "
955 "=%d] %02X%02X%02X%02X%02X%02X\n",
956 algorithm, auth_mode,
957 sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
959 status = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
964 if (rtw_access_ctrl23a(padapter, sa) == false) {
965 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
969 pstat = rtw_get_stainfo23a(pstapriv, sa);
971 /* allocate a new one */
972 DBG_8723A("going to alloc stainfo for sa ="MAC_FMT"\n",
974 pstat = rtw_alloc_stainfo23a(pstapriv, sa, GFP_ATOMIC);
976 DBG_8723A(" Exceed the upper limit of supported "
978 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
982 pstat->state = WIFI_FW_AUTH_NULL;
985 /* pstat->flags = 0; */
986 /* pstat->capability = 0; */
988 spin_lock_bh(&pstapriv->asoc_list_lock);
989 if (!list_empty(&pstat->asoc_list)) {
990 list_del_init(&pstat->asoc_list);
991 pstapriv->asoc_list_cnt--;
992 if (pstat->expire_to > 0) {
993 /* TODO: STA re_auth within expire_to */
996 spin_unlock_bh(&pstapriv->asoc_list_lock);
999 /* TODO: STA re_auth and auth timeout */
1003 spin_lock_bh(&pstapriv->auth_list_lock);
1004 if (list_empty(&pstat->auth_list)) {
1005 list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
1006 pstapriv->auth_list_cnt++;
1008 spin_unlock_bh(&pstapriv->auth_list_lock);
1010 if (pstat->auth_seq == 0)
1011 pstat->expire_to = pstapriv->auth_to;
1013 if ((pstat->auth_seq + 1) != seq) {
1014 DBG_8723A("(1)auth rejected because out of seq [rx_seq =%d, "
1015 "exp_seq =%d]!\n", seq, pstat->auth_seq+1);
1016 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1020 if (algorithm == WLAN_AUTH_OPEN && (auth_mode == 0 || auth_mode == 2)) {
1022 pstat->state &= ~WIFI_FW_AUTH_NULL;
1023 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1024 pstat->expire_to = pstapriv->assoc_to;
1025 pstat->authalg = algorithm;
1027 DBG_8723A("(2)auth rejected because out of seq "
1028 "[rx_seq =%d, exp_seq =%d]!\n",
1029 seq, pstat->auth_seq+1);
1030 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1033 } else { /* shared system or auto authentication */
1035 /* prepare for the challenging txt... */
1036 pstat->state &= ~WIFI_FW_AUTH_NULL;
1037 pstat->state |= WIFI_FW_AUTH_STATE;
1038 pstat->authalg = algorithm;
1039 pstat->auth_seq = 2;
1040 } else if (seq == 3) {
1041 /* checking for challenging txt... */
1042 DBG_8723A("checking for challenging txt...\n");
1044 p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pframe, len);
1045 if (!p || p[1] <= 0) {
1046 DBG_8723A("auth rejected because challenge "
1048 status = WLAN_STATUS_CHALLENGE_FAIL;
1052 if (!memcmp(p + 2, pstat->chg_txt, 128)) {
1053 pstat->state &= ~WIFI_FW_AUTH_STATE;
1054 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1055 /* challenging txt is correct... */
1056 pstat->expire_to = pstapriv->assoc_to;
1058 DBG_8723A("auth rejected because challenge "
1060 status = WLAN_STATUS_CHALLENGE_FAIL;
1064 DBG_8723A("(3)auth rejected because out of seq "
1065 "[rx_seq =%d, exp_seq =%d]!\n",
1066 seq, pstat->auth_seq+1);
1067 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1072 /* Now, we are going to issue_auth... */
1073 pstat->auth_seq = seq + 1;
1075 issue_auth(padapter, pstat, WLAN_STATUS_SUCCESS);
1077 if (pstat->state & WIFI_FW_AUTH_SUCCESS)
1078 pstat->auth_seq = 0;
1085 rtw_free_stainfo23a(padapter, pstat);
1088 memset((char *)pstat, '\0', sizeof(stat));
1089 pstat->auth_seq = 2;
1090 ether_addr_copy(pstat->hwaddr, sa);
1092 issue_auth(padapter, pstat, (unsigned short)status);
1099 OnAuth23aClient23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1101 unsigned int seq, status, algthm;
1102 unsigned int go2asoc = 0;
1103 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1104 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1105 struct sk_buff *skb = precv_frame->pkt;
1106 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1109 int plen = skb->len;
1111 DBG_8723A("%s\n", __func__);
1113 /* check A1 matches or not */
1114 if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
1117 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
1120 pie = mgmt->u.auth.variable;
1121 plen -= offsetof(struct ieee80211_mgmt, u.auth.variable);
1123 algthm = le16_to_cpu(mgmt->u.auth.auth_alg);
1124 seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
1125 status = le16_to_cpu(mgmt->u.auth.status_code);
1128 DBG_8723A("clnt auth fail, status: %d\n", status);
1129 /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
1130 if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
1131 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1132 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1134 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
1135 /* pmlmeinfo->reauth_count = 0; */
1138 set_link_timer(pmlmeext, 1);
1143 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
1144 /* legendary shared system */
1145 p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pie, plen);
1148 /* DBG_8723A("marc: no challenge text?\n"); */
1152 memcpy((void *)(pmlmeinfo->chg_txt), p + 2, p[1]);
1153 pmlmeinfo->auth_seq = 3;
1154 issue_auth(padapter, NULL, 0);
1155 set_link_timer(pmlmeext, REAUTH_TO);
1162 } else if (seq == 4) {
1163 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1168 /* this is also illegal */
1169 /* DBG_8723A("marc: clnt auth failed due to illegal seq =%x\n",
1175 DBG_8723A_LEVEL(_drv_always_, "auth success, start assoc\n");
1176 start_clnt_assoc(padapter);
1182 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
1187 #ifdef CONFIG_8723AU_AP_MODE
1188 static int rtw_validate_vendor_specific_ies(const u8 *pos, int elen)
1192 /* first 3 bytes in vendor specific information element are the IEEE
1193 * OUI of the vendor. The following byte is used a vendor specific
1196 DBG_8723A("short vendor specific information element "
1197 "ignored (len =%i)\n", elen);
1201 oui = RTW_GET_BE24(pos);
1203 case WLAN_OUI_MICROSOFT:
1204 /* Microsoft/Wi-Fi information elements are further typed and
1207 case WLAN_OUI_TYPE_MICROSOFT_WPA:
1208 /* Microsoft OUI (00:50:F2) with OUI Type 1:
1209 * real WPA information element */
1211 case WLAN_OUI_TYPE_MICROSOFT_WMM:
1213 DBG_8723A("short WME information element "
1214 "ignored (len =%i)\n", elen);
1218 case WME_OUI_SUBTYPE_INFORMATION_ELEMENT:
1219 case WME_OUI_SUBTYPE_PARAMETER_ELEMENT:
1221 case WME_OUI_SUBTYPE_TSPEC_ELEMENT:
1224 DBG_8723A("unknown WME information element "
1225 "ignored (subtype =%d len =%i)\n",
1230 case WLAN_OUI_TYPE_MICROSOFT_WPS:
1231 /* Wi-Fi Protected Setup (WPS) IE */
1234 DBG_8723A("Unknown Microsoft information element "
1235 "ignored (type =%d len =%i)\n",
1243 case VENDOR_HT_CAPAB_OUI_TYPE:
1246 DBG_8723A("Unknown Broadcom information element "
1247 "ignored (type =%d len =%i)\n", pos[3], elen);
1253 DBG_8723A("unknown vendor specific information element "
1254 "ignored (vendor OUI %02x:%02x:%02x len =%i)\n",
1255 pos[0], pos[1], pos[2], elen);
1262 static int rtw_validate_frame_ies(const u8 *start, uint len)
1264 const u8 *pos = start;
1276 DBG_8723A("%s: IEEE 802.11 failed (id =%d elen =%d "
1277 "left =%i)\n", __func__, id, elen, left);
1283 case WLAN_EID_SUPP_RATES:
1284 case WLAN_EID_FH_PARAMS:
1285 case WLAN_EID_DS_PARAMS:
1286 case WLAN_EID_CF_PARAMS:
1288 case WLAN_EID_IBSS_PARAMS:
1289 case WLAN_EID_CHALLENGE:
1290 case WLAN_EID_ERP_INFO:
1291 case WLAN_EID_EXT_SUPP_RATES:
1293 case WLAN_EID_VENDOR_SPECIFIC:
1294 if (rtw_validate_vendor_specific_ies(pos, elen))
1298 case WLAN_EID_PWR_CAPABILITY:
1299 case WLAN_EID_SUPPORTED_CHANNELS:
1300 case WLAN_EID_MOBILITY_DOMAIN:
1301 case WLAN_EID_FAST_BSS_TRANSITION:
1302 case WLAN_EID_TIMEOUT_INTERVAL:
1303 case WLAN_EID_HT_CAPABILITY:
1304 case WLAN_EID_HT_OPERATION:
1307 DBG_8723A("%s IEEE 802.11 ignored unknown element "
1308 "(id =%d elen =%d)\n", __func__, id, elen);
1324 OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1326 #ifdef CONFIG_8723AU_AP_MODE
1327 u16 capab_info, listen_interval;
1328 struct sta_info *pstat;
1329 unsigned char reassoc;
1330 int i, wpa_ie_len, left;
1331 unsigned char supportRate[16];
1333 unsigned short status = WLAN_STATUS_SUCCESS;
1334 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1335 struct security_priv *psecuritypriv = &padapter->securitypriv;
1336 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1337 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1338 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
1339 struct sta_priv *pstapriv = &padapter->stapriv;
1340 struct sk_buff *skb = precv_frame->pkt;
1341 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1342 const u8 *pos, *p, *wpa_ie, *wps_ie;
1343 u8 *pframe = skb->data;
1344 uint pkt_len = skb->len;
1347 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
1350 left = pkt_len - sizeof(struct ieee80211_hdr_3addr);
1351 if (ieee80211_is_assoc_req(mgmt->frame_control)) {
1353 pos = mgmt->u.assoc_req.variable;
1354 left -= offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
1355 } else { /* WIFI_REASSOCREQ */
1357 pos = mgmt->u.reassoc_req.variable;
1358 left -= offsetof(struct ieee80211_mgmt, u.reassoc_req.variable);
1362 DBG_8723A("handle_assoc(reassoc =%d) - too short payload "
1363 "(len =%lu)\n", reassoc, (unsigned long)pkt_len);
1367 pstat = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1369 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1370 goto asoc_class2_error;
1373 /* These two are located at the same offsets whether it's an
1374 * assoc_req or a reassoc_req */
1375 capab_info = get_unaligned_le16(&mgmt->u.assoc_req.capab_info);
1377 get_unaligned_le16(&mgmt->u.assoc_req.listen_interval);
1379 DBG_8723A("%s\n", __func__);
1381 /* check if this stat has been successfully authenticated/assocated */
1382 if (!(pstat->state & WIFI_FW_AUTH_SUCCESS)) {
1383 if (!(pstat->state & WIFI_FW_ASSOC_SUCCESS)) {
1384 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1385 goto asoc_class2_error;
1387 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
1388 pstat->state |= WIFI_FW_ASSOC_STATE;
1391 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1392 pstat->state |= WIFI_FW_ASSOC_STATE;
1395 pstat->capability = capab_info;
1397 /* now parse all ieee802_11 ie to point to elems */
1399 if (rtw_validate_frame_ies(pos, left)) {
1400 DBG_8723A("STA " MAC_FMT " sent invalid association request\n",
1401 MAC_ARG(pstat->hwaddr));
1402 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1403 goto OnAssocReq23aFail;
1406 /* now we should check all the fields... */
1408 p = cfg80211_find_ie(WLAN_EID_SSID, pos, left);
1409 if (!p || p[1] == 0) {
1410 /* broadcast ssid, however it is not allowed in assocreq */
1411 DBG_8723A("STA " MAC_FMT " sent invalid association request "
1412 "lacking an SSID\n", MAC_ARG(pstat->hwaddr));
1413 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1414 goto OnAssocReq23aFail;
1416 /* check if ssid match */
1417 if (memcmp(p + 2, cur->Ssid.ssid, cur->Ssid.ssid_len))
1418 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1420 if (p[1] != cur->Ssid.ssid_len)
1421 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1424 if (status != WLAN_STATUS_SUCCESS)
1425 goto OnAssocReq23aFail;
1427 /* check if the supported rate is ok */
1428 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, pos, left);
1430 DBG_8723A("Rx a sta assoc-req which supported rate is "
1432 /* use our own rate set as statoin used */
1433 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
1434 /* supportRateNum = AP_BSSRATE_LEN; */
1436 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1437 goto OnAssocReq23aFail;
1439 memcpy(supportRate, p + 2, p[1]);
1440 supportRateNum = p[1];
1442 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, pos, left);
1444 if (supportRateNum <= sizeof(supportRate)) {
1445 memcpy(supportRate+supportRateNum, p + 2, p[1]);
1446 supportRateNum += p[1];
1451 /* todo: mask supportRate between AP & STA -> move to update raid */
1452 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
1454 /* update station supportRate */
1455 pstat->bssratelen = supportRateNum;
1456 memcpy(pstat->bssrateset, supportRate, supportRateNum);
1457 Update23aTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
1459 /* check RSN/WPA/WPS */
1460 pstat->dot8021xalg = 0;
1462 pstat->wpa_group_cipher = 0;
1463 pstat->wpa2_group_cipher = 0;
1464 pstat->wpa_pairwise_cipher = 0;
1465 pstat->wpa2_pairwise_cipher = 0;
1466 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
1468 wpa_ie = cfg80211_find_ie(WLAN_EID_RSN, pos, left);
1470 wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1471 WLAN_OUI_TYPE_MICROSOFT_WPA,
1474 int group_cipher = 0, pairwise_cipher = 0;
1476 wpa_ie_len = wpa_ie[1];
1477 if (psecuritypriv->wpa_psk & BIT(1)) {
1478 r = rtw_parse_wpa2_ie23a(wpa_ie, wpa_ie_len + 2,
1480 &pairwise_cipher, NULL);
1481 if (r == _SUCCESS) {
1482 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1483 pstat->wpa_psk |= BIT(1);
1485 pstat->wpa2_group_cipher = group_cipher &
1486 psecuritypriv->wpa2_group_cipher;
1487 pstat->wpa2_pairwise_cipher = pairwise_cipher &
1488 psecuritypriv->wpa2_pairwise_cipher;
1490 status = WLAN_STATUS_INVALID_IE;
1491 } else if (psecuritypriv->wpa_psk & BIT(0)) {
1492 r = rtw_parse_wpa_ie23a(wpa_ie, wpa_ie_len + 2,
1493 &group_cipher, &pairwise_cipher,
1495 if (r == _SUCCESS) {
1496 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1497 pstat->wpa_psk |= BIT(0);
1499 pstat->wpa_group_cipher = group_cipher &
1500 psecuritypriv->wpa_group_cipher;
1501 pstat->wpa_pairwise_cipher = pairwise_cipher &
1502 psecuritypriv->wpa_pairwise_cipher;
1504 status = WLAN_STATUS_INVALID_IE;
1509 if (wpa_ie && status == WLAN_STATUS_SUCCESS) {
1510 if (!pstat->wpa_group_cipher)
1511 status = WLAN_STATUS_INVALID_GROUP_CIPHER;
1513 if (!pstat->wpa_pairwise_cipher)
1514 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
1518 if (status != WLAN_STATUS_SUCCESS)
1519 goto OnAssocReq23aFail;
1521 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
1523 wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1524 WLAN_OUI_TYPE_MICROSOFT_WPS,
1529 DBG_8723A("STA included WPS IE in (Re)Association "
1530 "Request - assume WPS is used\n");
1531 pstat->flags |= WLAN_STA_WPS;
1533 DBG_8723A("STA did not include WPA/RSN IE in (Re)"
1534 "Association Request - possible WPS use\n");
1535 pstat->flags |= WLAN_STA_MAYBE_WPS;
1540 if (psecuritypriv->wpa_psk == 0) {
1541 DBG_8723A("STA " MAC_FMT ": WPA/RSN IE in association "
1542 "request, but AP don't support WPA/RSN\n",
1543 MAC_ARG(pstat->hwaddr));
1545 status = WLAN_STATUS_INVALID_IE;
1547 goto OnAssocReq23aFail;
1551 DBG_8723A("STA included WPS IE in (Re)Association "
1552 "Request - WPS is used\n");
1553 pstat->flags |= WLAN_STA_WPS;
1556 copy_len = ((wpa_ie_len + 2) > sizeof(pstat->wpa_ie)) ?
1557 sizeof(pstat->wpa_ie) : (wpa_ie_len + 2);
1561 memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len);
1564 /* check if there is WMM IE & support WWM-PS */
1565 pstat->flags &= ~WLAN_STA_WME;
1566 pstat->qos_option = 0;
1567 pstat->qos_info = 0;
1568 pstat->has_legacy_ac = true;
1569 pstat->uapsd_vo = 0;
1570 pstat->uapsd_vi = 0;
1571 pstat->uapsd_be = 0;
1572 pstat->uapsd_bk = 0;
1573 if (pmlmepriv->qos_option) {
1574 const u8 *end = pos + left;
1579 p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1580 WLAN_OUI_TYPE_MICROSOFT_WMM,
1583 pstat->flags |= WLAN_STA_WME;
1585 pstat->qos_option = 1;
1586 pstat->qos_info = *(p + 8);
1589 (pstat->qos_info >> 5) & 0x3;
1591 if ((pstat->qos_info & 0xf) != 0xf)
1592 pstat->has_legacy_ac = true;
1594 pstat->has_legacy_ac = false;
1596 if (pstat->qos_info & 0xf) {
1597 if (pstat->qos_info & BIT(0))
1598 pstat->uapsd_vo = BIT(0)|BIT(1);
1600 pstat->uapsd_vo = 0;
1602 if (pstat->qos_info & BIT(1))
1603 pstat->uapsd_vi = BIT(0)|BIT(1);
1605 pstat->uapsd_vi = 0;
1607 if (pstat->qos_info & BIT(2))
1608 pstat->uapsd_bk = BIT(0)|BIT(1);
1610 pstat->uapsd_bk = 0;
1612 if (pstat->qos_info & BIT(3))
1613 pstat->uapsd_be = BIT(0)|BIT(1);
1615 pstat->uapsd_be = 0;
1626 /* save HT capabilities in the sta object */
1627 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
1628 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pos, left);
1630 if (p && p[1] >= sizeof(struct ieee80211_ht_cap)) {
1631 pstat->flags |= WLAN_STA_HT;
1633 pstat->flags |= WLAN_STA_WME;
1635 memcpy(&pstat->htpriv.ht_cap, p + 2,
1636 sizeof(struct ieee80211_ht_cap));
1638 pstat->flags &= ~WLAN_STA_HT;
1640 if (!pmlmepriv->htpriv.ht_option && pstat->flags & WLAN_STA_HT){
1641 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1642 goto OnAssocReq23aFail;
1645 if (pstat->flags & WLAN_STA_HT &&
1646 (pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP ||
1647 pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) {
1648 DBG_8723A("HT: " MAC_FMT " tried to use TKIP with HT "
1649 "association\n", MAC_ARG(pstat->hwaddr));
1651 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
1652 /* goto OnAssocReq23aFail; */
1655 pstat->flags |= WLAN_STA_NONERP;
1656 for (i = 0; i < pstat->bssratelen; i++) {
1657 if ((pstat->bssrateset[i] & 0x7f) > 22) {
1658 pstat->flags &= ~WLAN_STA_NONERP;
1663 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1664 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
1666 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1668 if (status != WLAN_STATUS_SUCCESS)
1669 goto OnAssocReq23aFail;
1671 /* TODO: identify_proprietary_vendor_ie(); */
1672 /* Realtek proprietary IE */
1673 /* identify if this is Broadcom sta */
1674 /* identify if this is ralink sta */
1675 /* Customer proprietary IE */
1677 /* get a unique AID */
1678 if (pstat->aid > 0) {
1679 DBG_8723A(" old AID %d\n", pstat->aid);
1681 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
1682 if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
1685 if (pstat->aid > NUM_STA)
1686 pstat->aid = NUM_STA;
1687 if (pstat->aid > pstapriv->max_num_sta) {
1691 DBG_8723A(" no room for more AIDs\n");
1693 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1695 goto OnAssocReq23aFail;
1697 pstapriv->sta_aid[pstat->aid - 1] = pstat;
1698 DBG_8723A("allocate new AID = (%d)\n", pstat->aid);
1702 pstat->state &= ~WIFI_FW_ASSOC_STATE;
1703 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
1705 spin_lock_bh(&pstapriv->auth_list_lock);
1706 if (!list_empty(&pstat->auth_list)) {
1707 list_del_init(&pstat->auth_list);
1708 pstapriv->auth_list_cnt--;
1710 spin_unlock_bh(&pstapriv->auth_list_lock);
1712 spin_lock_bh(&pstapriv->asoc_list_lock);
1713 if (list_empty(&pstat->asoc_list)) {
1714 pstat->expire_to = pstapriv->expire_to;
1715 list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
1716 pstapriv->asoc_list_cnt++;
1718 spin_unlock_bh(&pstapriv->asoc_list_lock);
1720 /* now the station is qualified to join our BSS... */
1721 if (pstat && pstat->state & WIFI_FW_ASSOC_SUCCESS &&
1722 status == WLAN_STATUS_SUCCESS) {
1723 #ifdef CONFIG_8723AU_AP_MODE
1724 /* 1 bss_cap_update & sta_info_update23a */
1725 bss_cap_update_on_sta_join23a(padapter, pstat);
1726 sta_info_update23a(padapter, pstat);
1728 /* issue assoc rsp before notify station join event. */
1729 if (ieee80211_is_assoc_req(mgmt->frame_control))
1730 issue_assocrsp(padapter, status, pstat,
1731 IEEE80211_STYPE_ASSOC_RESP);
1733 issue_assocrsp(padapter, status, pstat,
1734 IEEE80211_STYPE_REASSOC_RESP);
1736 /* 2 - report to upper layer */
1737 DBG_8723A("indicate_sta_join_event to upper layer - hostapd\n");
1738 rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
1740 /* 3-(1) report sta add event */
1741 report_add_sta_event23a(padapter, pstat->hwaddr, pstat->aid);
1749 #ifdef CONFIG_8723AU_AP_MODE
1750 issue_deauth23a(padapter, mgmt->sa, status);
1756 #ifdef CONFIG_8723AU_AP_MODE
1758 if (ieee80211_is_assoc_req(mgmt->frame_control))
1759 issue_assocrsp(padapter, status, pstat,
1760 IEEE80211_STYPE_ASSOC_RESP);
1762 issue_assocrsp(padapter, status, pstat,
1763 IEEE80211_STYPE_REASSOC_RESP);
1766 #endif /* CONFIG_8723AU_AP_MODE */
1772 OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1774 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1775 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1776 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1777 struct sk_buff *skb = precv_frame->pkt;
1778 struct ieee80211_mgmt *pmgmt = (struct ieee80211_mgmt *) skb->data;
1780 unsigned short status;
1782 u8 *pframe = skb->data;
1783 int pkt_len = skb->len;
1786 DBG_8723A("%s\n", __func__);
1788 /* check A1 matches or not */
1789 if (!ether_addr_equal(myid(&padapter->eeprompriv), pmgmt->da))
1792 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
1795 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1798 del_timer_sync(&pmlmeext->link_timer);
1801 status = le16_to_cpu(pmgmt->u.assoc_resp.status_code);
1803 DBG_8723A("assoc reject, status code: %d\n", status);
1804 pmlmeinfo->state = WIFI_FW_NULL_STATE;
1806 goto report_assoc_result;
1809 /* get capabilities */
1810 pmlmeinfo->capability = le16_to_cpu(pmgmt->u.assoc_resp.capab_info);
1813 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
1816 res = pmlmeinfo->aid = le16_to_cpu(pmgmt->u.assoc_resp.aid) & 0x3fff;
1818 pie = pframe + offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
1820 offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
1822 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
1823 pmgmt->u.assoc_resp.variable, pielen);
1825 HT_caps_handler23a(padapter, p);
1827 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
1828 pmgmt->u.assoc_resp.variable, pielen);
1830 HT_info_handler23a(padapter, p);
1832 p = cfg80211_find_ie(WLAN_EID_ERP_INFO,
1833 pmgmt->u.assoc_resp.variable, pielen);
1835 ERP_IE_handler23a(padapter, p);
1837 pie = pframe + offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
1839 p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1840 WLAN_OUI_TYPE_MICROSOFT_WMM,
1841 pie, pframe + pkt_len - pie);
1846 /* if this IE is too short, try the next */
1849 /* if this IE is WMM params, we found what we wanted */
1855 WMM_param_handler23a(padapter, p);
1857 pmlmeinfo->state &= ~WIFI_FW_ASSOC_STATE;
1858 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
1860 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
1861 UpdateBrateTbl23a(padapter, pmlmeinfo->network.SupportedRates);
1863 report_assoc_result:
1864 pmlmepriv->assoc_rsp_len = 0;
1866 kfree(pmlmepriv->assoc_rsp);
1867 pmlmepriv->assoc_rsp = kmalloc(pkt_len, GFP_ATOMIC);
1868 if (pmlmepriv->assoc_rsp) {
1869 memcpy(pmlmepriv->assoc_rsp, pframe, pkt_len);
1870 pmlmepriv->assoc_rsp_len = pkt_len;
1873 kfree(pmlmepriv->assoc_rsp);
1875 report_join_res23a(padapter, res);
1881 OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1883 unsigned short reason;
1884 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1885 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1886 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1887 struct sk_buff *skb = precv_frame->pkt;
1888 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1890 if (!ether_addr_equal(mgmt->bssid,
1891 get_my_bssid23a(&pmlmeinfo->network)))
1894 reason = le16_to_cpu(mgmt->u.deauth.reason_code);
1896 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1898 #ifdef CONFIG_8723AU_AP_MODE
1899 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1900 struct sta_info *psta;
1901 struct sta_priv *pstapriv = &padapter->stapriv;
1903 DBG_8723A_LEVEL(_drv_always_, "ap recv deauth reason code(%d) "
1904 "sta:%pM\n", reason, mgmt->sa);
1906 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1910 spin_lock_bh(&pstapriv->asoc_list_lock);
1911 if (!list_empty(&psta->asoc_list)) {
1912 list_del_init(&psta->asoc_list);
1913 pstapriv->asoc_list_cnt--;
1914 updated = ap_free_sta23a(padapter, psta,
1917 spin_unlock_bh(&pstapriv->asoc_list_lock);
1919 associated_clients_update23a(padapter, updated);
1926 DBG_8723A_LEVEL(_drv_always_, "sta recv deauth reason code(%d) "
1927 "sta:%pM\n", reason, mgmt->bssid);
1929 receive_disconnect23a(padapter, mgmt->bssid, reason);
1931 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1937 OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1939 unsigned short reason;
1940 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1941 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1942 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1943 struct sk_buff *skb = precv_frame->pkt;
1944 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1946 if (!ether_addr_equal(mgmt->bssid,
1947 get_my_bssid23a(&pmlmeinfo->network)))
1950 reason = le16_to_cpu(mgmt->u.disassoc.reason_code);
1952 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1954 #ifdef CONFIG_8723AU_AP_MODE
1955 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1956 struct sta_info *psta;
1957 struct sta_priv *pstapriv = &padapter->stapriv;
1959 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason code(%d)"
1960 " sta:%pM\n", reason, mgmt->sa);
1962 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1966 spin_lock_bh(&pstapriv->asoc_list_lock);
1967 if (!list_empty(&psta->asoc_list)) {
1968 list_del_init(&psta->asoc_list);
1969 pstapriv->asoc_list_cnt--;
1970 updated = ap_free_sta23a(padapter, psta,
1973 spin_unlock_bh(&pstapriv->asoc_list_lock);
1975 associated_clients_update23a(padapter, updated);
1982 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason "
1983 "code(%d) sta:%pM\n", reason, mgmt->bssid);
1985 receive_disconnect23a(padapter, mgmt->bssid, reason);
1987 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1992 OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1994 DBG_8723A("%s\n", __func__);
1999 on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2005 OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2011 OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2016 static int OnAction23a_back23a(struct rtw_adapter *padapter,
2017 struct recv_frame *precv_frame)
2020 struct sta_info *psta = NULL;
2021 struct recv_reorder_ctrl *preorder_ctrl;
2022 unsigned char category, action;
2023 unsigned short tid, status, capab, params, reason_code = 0;
2024 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2025 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2026 struct sk_buff *skb = precv_frame->pkt;
2027 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
2028 struct sta_priv *pstapriv = &padapter->stapriv;
2030 /* check RA matches or not */
2031 if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
2034 DBG_8723A("%s\n", __func__);
2036 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2037 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
2041 psta = rtw_get_stainfo23a(pstapriv, addr);
2046 category = mgmt->u.action.category;
2047 if (category == WLAN_CATEGORY_BACK) { /* representing Block Ack */
2048 if (!pmlmeinfo->HT_enable)
2050 /* action_code is located in the same place for all
2051 action events, so pick any */
2052 action = mgmt->u.action.u.wme_action.action_code;
2053 DBG_8723A("%s, action =%d\n", __func__, action);
2055 case WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
2056 memcpy(&pmlmeinfo->ADDBA_req,
2057 &mgmt->u.action.u.addba_req.dialog_token,
2058 sizeof(struct ADDBA_request));
2059 process_addba_req23a(padapter,
2060 (u8 *)&pmlmeinfo->ADDBA_req, addr);
2061 if (pmlmeinfo->bAcceptAddbaReq == true)
2062 issue_action_BA23a(padapter, addr,
2063 WLAN_ACTION_ADDBA_RESP, 0);
2065 /* reject ADDBA Req */
2066 issue_action_BA23a(padapter, addr,
2067 WLAN_ACTION_ADDBA_RESP, 37);
2070 case WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
2071 status = get_unaligned_le16(
2072 &mgmt->u.action.u.addba_resp.status);
2073 capab = get_unaligned_le16(
2074 &mgmt->u.action.u.addba_resp.capab);
2075 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
2076 if (status == 0) { /* successful */
2077 DBG_8723A("agg_enable for TID =%d\n", tid);
2078 psta->htpriv.agg_enable_bitmap |= BIT(tid);
2079 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
2081 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
2084 case WLAN_ACTION_DELBA: /* DELBA */
2085 params = get_unaligned_le16(
2086 &mgmt->u.action.u.delba.params);
2089 if (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) {
2090 preorder_ctrl = &psta->recvreorder_ctrl[tid];
2091 preorder_ctrl->enable = false;
2092 preorder_ctrl->indicate_seq = 0xffff;
2094 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
2095 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
2097 reason_code = get_unaligned_le16(
2098 &mgmt->u.action.u.delba.reason_code);
2099 /* todo: how to notify the host while receiving
2109 static int on_action_public23a(struct rtw_adapter *padapter,
2110 struct recv_frame *precv_frame)
2112 struct sk_buff *skb = precv_frame->pkt;
2113 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2114 u8 *pframe = skb->data;
2117 /* check RA matches or not */
2118 if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
2121 channel = rtw_get_oper_ch23a(padapter);
2123 if (channel <= RTW_CH_MAX_2G_CHANNEL)
2124 freq = ieee80211_channel_to_frequency(channel,
2125 IEEE80211_BAND_2GHZ);
2127 freq = ieee80211_channel_to_frequency(channel,
2128 IEEE80211_BAND_5GHZ);
2130 if (cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, pframe,
2131 skb->len, 0, GFP_ATOMIC))
2138 OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2144 OnAction23a_wmm(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2150 OnAction23a_p2p(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2156 OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2160 struct action_handler *ptable;
2161 struct sk_buff *skb = precv_frame->pkt;
2162 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
2164 category = mgmt->u.action.category;
2167 i < sizeof(OnAction23a_tbl) / sizeof(struct action_handler); i++) {
2168 ptable = &OnAction23a_tbl[i];
2170 if (category == ptable->num)
2171 ptable->func(padapter, precv_frame);
2177 static int DoReserved23a(struct rtw_adapter *padapter,
2178 struct recv_frame *precv_frame)
2183 struct xmit_frame *alloc_mgtxmitframe23a(struct xmit_priv *pxmitpriv)
2185 struct xmit_frame *pmgntframe;
2186 struct xmit_buf *pxmitbuf;
2188 pmgntframe = rtw_alloc_xmitframe23a_ext(pxmitpriv);
2191 DBG_8723A("%s(%s): alloc xmitframe fail\n", __func__,
2192 pxmitpriv->adapter->pnetdev->name);
2196 pxmitbuf = rtw_alloc_xmitbuf23a_ext(pxmitpriv);
2198 DBG_8723A("%s(%s): alloc xmitbuf fail\n", __func__,
2199 pxmitpriv->adapter->pnetdev->name);
2200 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
2205 pmgntframe->frame_tag = MGNT_FRAMETAG;
2206 pmgntframe->pxmitbuf = pxmitbuf;
2207 pmgntframe->buf_addr = pxmitbuf->pbuf;
2208 pxmitbuf->priv_data = pmgntframe;
2214 /****************************************************************************
2216 Following are some TX fuctions for WiFi MLME
2218 *****************************************************************************/
2220 void update_mgnt_tx_rate23a(struct rtw_adapter *padapter, u8 rate)
2222 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2224 pmlmeext->tx_rate = rate;
2225 DBG_8723A("%s(): rate = %x\n", __func__, rate);
2228 void update_mgntframe_attrib23a(struct rtw_adapter *padapter,
2229 struct pkt_attrib *pattrib)
2231 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2233 memset((u8 *)pattrib, 0, sizeof(struct pkt_attrib));
2235 pattrib->hdrlen = 24;
2236 pattrib->nr_frags = 1;
2237 pattrib->priority = 7;
2238 pattrib->mac_id = 0;
2239 pattrib->qsel = 0x12;
2241 pattrib->pktlen = 0;
2243 if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
2244 pattrib->raid = 6;/* b mode */
2246 pattrib->raid = 5;/* a/g mode */
2248 pattrib->encrypt = 0;
2249 pattrib->bswenc = false;
2251 pattrib->qos_en = false;
2252 pattrib->ht_en = false;
2253 pattrib->bwmode = HT_CHANNEL_WIDTH_20;
2254 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2255 pattrib->sgi = false;
2257 pattrib->seqnum = pmlmeext->mgnt_seq;
2259 pattrib->retry_ctrl = true;
2262 void dump_mgntframe23a(struct rtw_adapter *padapter,
2263 struct xmit_frame *pmgntframe)
2265 if (padapter->bSurpriseRemoved == true ||
2266 padapter->bDriverStopped == true)
2269 rtl8723au_mgnt_xmit(padapter, pmgntframe);
2272 int dump_mgntframe23a_and_wait(struct rtw_adapter *padapter,
2273 struct xmit_frame *pmgntframe, int timeout_ms)
2277 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2278 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
2279 struct submit_ctx sctx;
2281 if (padapter->bSurpriseRemoved == true ||
2282 padapter->bDriverStopped == true)
2285 rtw_sctx_init23a(&sctx, timeout_ms);
2286 pxmitbuf->sctx = &sctx;
2288 ret = rtl8723au_mgnt_xmit(padapter, pmgntframe);
2290 if (ret == _SUCCESS)
2291 ret = rtw_sctx_wait23a(&sctx);
2293 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
2294 pxmitbuf->sctx = NULL;
2295 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
2300 int dump_mgntframe23a_and_wait_ack23a(struct rtw_adapter *padapter,
2301 struct xmit_frame *pmgntframe)
2304 u32 timeout_ms = 500;/* 500ms */
2305 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2307 if (padapter->bSurpriseRemoved == true ||
2308 padapter->bDriverStopped == true)
2311 mutex_lock(&pxmitpriv->ack_tx_mutex);
2312 pxmitpriv->ack_tx = true;
2314 pmgntframe->ack_report = 1;
2315 if (rtl8723au_mgnt_xmit(padapter, pmgntframe) == _SUCCESS)
2316 ret = rtw_ack_tx_wait23a(pxmitpriv, timeout_ms);
2318 pxmitpriv->ack_tx = false;
2319 mutex_unlock(&pxmitpriv->ack_tx_mutex);
2324 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
2332 ssid_ie = rtw_get_ie23a(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
2334 /* DBG_8723A("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n",
2335 __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
2337 if (ssid_ie && ssid_len_ori > 0) {
2338 switch (hidden_ssid_mode)
2341 next_ie = ssid_ie + 2 + ssid_len_ori;
2344 remain_len = ies_len -(next_ie-ies);
2347 memcpy(ssid_ie+2, next_ie, remain_len);
2348 len_diff -= ssid_len_ori;
2352 memset(&ssid_ie[2], 0, ssid_len_ori);
2362 void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
2364 struct xmit_frame *pmgntframe;
2365 struct pkt_attrib *pattrib;
2366 unsigned char *pframe;
2367 struct ieee80211_mgmt *mgmt;
2368 unsigned int rate_len;
2369 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2370 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2371 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2372 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2373 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2374 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2379 /* DBG_8723A("%s\n", __func__); */
2381 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2383 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2386 #ifdef CONFIG_8723AU_AP_MODE
2387 spin_lock_bh(&pmlmepriv->bcn_update_lock);
2390 /* update attribute */
2391 pattrib = &pmgntframe->attrib;
2392 update_mgntframe_attrib23a(padapter, pattrib);
2393 pattrib->qsel = 0x10;
2395 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2397 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2398 mgmt = (struct ieee80211_mgmt *)pframe;
2400 mgmt->frame_control =
2401 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
2404 ether_addr_copy(mgmt->da, bc_addr);
2405 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
2406 ether_addr_copy(mgmt->bssid, get_my_bssid23a(cur_network));
2408 /* timestamp will be inserted by hardware */
2410 put_unaligned_le16(cur_network->beacon_interval,
2411 &mgmt->u.beacon.beacon_int);
2413 put_unaligned_le16(cur_network->capability,
2414 &mgmt->u.beacon.capab_info);
2416 pframe = mgmt->u.beacon.variable;
2417 pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
2419 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
2422 /* DBG_8723A("ie len =%d\n", cur_network->IELength); */
2423 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2424 len_diff = update_hidden_ssid(pframe, cur_network->IELength,
2425 pmlmeinfo->hidden_ssid_mode);
2426 pframe += (cur_network->IELength+len_diff);
2427 pattrib->pktlen += (cur_network->IELength+len_diff);
2429 iebuf = mgmt->u.beacon.variable;
2430 buflen = pattrib->pktlen -
2431 offsetof(struct ieee80211_mgmt, u.beacon.variable);
2432 wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
2433 WLAN_OUI_TYPE_MICROSOFT_WPS,
2436 if (wps_ie && wps_ie[1] > 0) {
2437 rtw_get_wps_attr_content23a(wps_ie, wps_ie[1],
2438 WPS_ATTR_SELECTED_REGISTRAR,
2442 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
2444 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
2450 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2451 cur_network->Ssid.ssid_len,
2452 cur_network->Ssid.ssid, &pattrib->pktlen);
2454 /* supported rates... */
2455 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2456 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2457 ((rate_len > 8)? 8: rate_len),
2458 cur_network->SupportedRates, &pattrib->pktlen);
2460 /* DS parameter set */
2461 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)
2462 &cur_network->DSConfig, &pattrib->pktlen);
2464 /* if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
2468 /* IBSS Parameter Set... */
2469 /* ATIMWindow = cur->ATIMWindow; */
2471 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2472 (unsigned char *)&ATIMWindow,
2476 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2477 &erpinfo, &pattrib->pktlen);
2480 /* EXTERNDED SUPPORTED RATE */
2482 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2484 cur_network->SupportedRates + 8,
2487 /* todo:HT for adhoc */
2491 #ifdef CONFIG_8723AU_AP_MODE
2492 pmlmepriv->update_bcn = false;
2494 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
2497 if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
2498 DBG_8723A("beacon frame too large\n");
2502 pattrib->last_txcmdsz = pattrib->pktlen;
2504 /* DBG_8723A("issue bcn_sz =%d\n", pattrib->last_txcmdsz); */
2506 dump_mgntframe23a_and_wait(padapter, pmgntframe, timeout_ms);
2508 dump_mgntframe23a(padapter, pmgntframe);
2511 static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da,
2512 u8 is_valid_p2p_probereq)
2514 struct xmit_frame *pmgntframe;
2515 struct pkt_attrib *pattrib;
2516 unsigned char *pframe;
2517 struct ieee80211_mgmt *mgmt;
2518 unsigned char *mac, *bssid;
2519 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2520 #ifdef CONFIG_8723AU_AP_MODE
2524 int ssid_ielen_diff;
2527 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2528 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2529 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2530 unsigned int rate_len;
2532 /* DBG_8723A("%s\n", __func__); */
2534 if (cur_network->IELength > MAX_IE_SZ)
2537 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2539 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2543 /* update attribute */
2544 pattrib = &pmgntframe->attrib;
2545 update_mgntframe_attrib23a(padapter, pattrib);
2547 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2549 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
2550 mgmt = (struct ieee80211_mgmt *)pframe;
2552 mac = myid(&padapter->eeprompriv);
2553 bssid = cur_network->MacAddress;
2555 mgmt->frame_control =
2556 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
2558 ether_addr_copy(mgmt->da, da);
2559 ether_addr_copy(mgmt->sa, mac);
2560 ether_addr_copy(mgmt->bssid, bssid);
2562 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
2563 pmlmeext->mgnt_seq++;
2565 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2567 /* timestamp will be inserted by hardware */
2568 put_unaligned_le16(cur_network->beacon_interval,
2569 &mgmt->u.probe_resp.beacon_int);
2571 put_unaligned_le16(cur_network->capability,
2572 &mgmt->u.probe_resp.capab_info);
2574 pframe = mgmt->u.probe_resp.variable;
2576 offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
2578 /* below for ad-hoc mode */
2580 #ifdef CONFIG_8723AU_AP_MODE
2581 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
2582 pwps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
2583 WLAN_OUI_TYPE_MICROSOFT_WPS,
2585 cur_network->IELength);
2587 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2588 pframe += cur_network->IELength;
2589 pattrib->pktlen += cur_network->IELength;
2591 /* retrieve SSID IE from cur_network->Ssid */
2593 ssid_ie = rtw_get_ie23a(mgmt->u.probe_resp.variable,
2594 WLAN_EID_SSID, &ssid_ielen,
2595 pframe - mgmt->u.probe_resp.variable);
2597 ssid_ielen_diff = cur_network->Ssid.ssid_len - ssid_ielen;
2599 if (ssid_ie && cur_network->Ssid.ssid_len) {
2600 uint remainder_ielen;
2602 remainder_ie = ssid_ie + 2;
2603 remainder_ielen = pframe - remainder_ie;
2605 DBG_8723A_LEVEL(_drv_warning_, "%s(%s): "
2606 "remainder_ielen > MAX_IE_SZ\n",
2607 __func__, padapter->pnetdev->name);
2608 if (remainder_ielen > MAX_IE_SZ)
2609 remainder_ielen = MAX_IE_SZ;
2611 memcpy(buf, remainder_ie, remainder_ielen);
2612 memcpy(remainder_ie + ssid_ielen_diff, buf,
2614 *(ssid_ie + 1) = cur_network->Ssid.ssid_len;
2615 memcpy(ssid_ie + 2, cur_network->Ssid.ssid,
2616 cur_network->Ssid.ssid_len);
2618 pframe += ssid_ielen_diff;
2619 pattrib->pktlen += ssid_ielen_diff;
2625 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2626 cur_network->Ssid.ssid_len,
2627 cur_network->Ssid.ssid,
2630 /* supported rates... */
2631 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2632 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2633 ((rate_len > 8)? 8: rate_len),
2634 cur_network->SupportedRates,
2637 /* DS parameter set */
2638 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1,
2639 (unsigned char *)&cur_network->DSConfig,
2642 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
2645 /* IBSS Parameter Set... */
2646 /* ATIMWindow = cur->ATIMWindow; */
2648 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2649 (unsigned char *)&ATIMWindow,
2653 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2654 &erpinfo, &pattrib->pktlen);
2657 /* EXTERNDED SUPPORTED RATE */
2659 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2661 cur_network->SupportedRates + 8,
2664 /* todo:HT for adhoc */
2667 pattrib->last_txcmdsz = pattrib->pktlen;
2669 dump_mgntframe23a(padapter, pmgntframe);
2674 static int _issue_probereq(struct rtw_adapter *padapter,
2675 struct cfg80211_ssid *pssid, u8 *da, int wait_ack)
2678 struct xmit_frame *pmgntframe;
2679 struct pkt_attrib *pattrib;
2680 unsigned char *pframe;
2681 struct ieee80211_hdr *pwlanhdr;
2683 unsigned char bssrate[NumRates];
2684 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2685 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2686 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2687 int bssrate_len = 0;
2688 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2690 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2691 ("+%s\n", __func__));
2693 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2697 /* update attribute */
2698 pattrib = &pmgntframe->attrib;
2699 update_mgntframe_attrib23a(padapter, pattrib);
2701 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2703 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2704 pwlanhdr = (struct ieee80211_hdr *)pframe;
2706 mac = myid(&padapter->eeprompriv);
2708 pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2709 IEEE80211_STYPE_PROBE_REQ);
2712 /* unicast probe request frame */
2713 ether_addr_copy(pwlanhdr->addr1, da);
2714 ether_addr_copy(pwlanhdr->addr3, da);
2716 /* broadcast probe request frame */
2717 ether_addr_copy(pwlanhdr->addr1, bc_addr);
2718 ether_addr_copy(pwlanhdr->addr3, bc_addr);
2721 ether_addr_copy(pwlanhdr->addr2, mac);
2723 pwlanhdr->seq_ctrl =
2724 cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
2726 pmlmeext->mgnt_seq++;
2728 pframe += sizeof (struct ieee80211_hdr_3addr);
2729 pattrib->pktlen = sizeof (struct ieee80211_hdr_3addr);
2732 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, pssid->ssid_len,
2733 pssid->ssid, &pattrib->pktlen);
2735 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, 0, NULL,
2738 get_rate_set23a(padapter, bssrate, &bssrate_len);
2740 if (bssrate_len > 8) {
2741 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
2742 bssrate, &pattrib->pktlen);
2743 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2744 (bssrate_len - 8), (bssrate + 8),
2747 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2748 bssrate_len, bssrate, &pattrib->pktlen);
2751 /* add wps_ie for wps2.0 */
2752 if (pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie) {
2753 memcpy(pframe, pmlmepriv->wps_probe_req_ie,
2754 pmlmepriv->wps_probe_req_ie_len);
2755 pframe += pmlmepriv->wps_probe_req_ie_len;
2756 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
2759 pattrib->last_txcmdsz = pattrib->pktlen;
2761 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2762 ("issuing probe_req, tx_len =%d\n", pattrib->last_txcmdsz));
2765 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
2767 dump_mgntframe23a(padapter, pmgntframe);
2775 static inline void issue_probereq(struct rtw_adapter *padapter,
2776 struct cfg80211_ssid *pssid, u8 *da)
2778 _issue_probereq(padapter, pssid, da, false);
2781 static int issue_probereq_ex(struct rtw_adapter *padapter,
2782 struct cfg80211_ssid *pssid, u8 *da,
2783 int try_cnt, int wait_ms)
2787 unsigned long start = jiffies;
2790 ret = _issue_probereq(padapter, pssid, da,
2791 wait_ms > 0 ? true : false);
2795 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
2798 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
2801 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
2808 if (try_cnt && wait_ms) {
2810 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
2811 "in %u ms\n", __func__,
2812 padapter->pnetdev->name,
2813 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
2814 ret == _SUCCESS?", acked":"", i, try_cnt,
2815 jiffies_to_msecs(jiffies - start));
2817 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
2818 __func__, padapter->pnetdev->name,
2819 rtw_get_oper_ch23a(padapter),
2820 ret == _SUCCESS?", acked":"", i, try_cnt,
2821 jiffies_to_msecs(jiffies - start));
2827 /* if psta == NULL, indiate we are station(client) now... */
2828 static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
2829 unsigned short status)
2831 struct xmit_frame *pmgntframe;
2832 struct pkt_attrib *pattrib;
2833 unsigned char *pframe;
2834 struct ieee80211_mgmt *mgmt;
2837 int use_shared_key = 0;
2838 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2839 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2840 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2842 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2846 /* update attribute */
2847 pattrib = &pmgntframe->attrib;
2848 update_mgntframe_attrib23a(padapter, pattrib);
2850 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2852 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2853 mgmt = (struct ieee80211_mgmt *)pframe;
2855 mgmt->frame_control =
2856 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2857 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
2858 pmlmeext->mgnt_seq++;
2860 pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.auth.variable);
2862 if (psta) { /* for AP mode */
2863 #ifdef CONFIG_8723AU_AP_MODE
2864 unsigned short val16;
2865 ether_addr_copy(mgmt->da, psta->hwaddr);
2866 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
2867 ether_addr_copy(mgmt->bssid, myid(&padapter->eeprompriv));
2869 /* setting auth algo number */
2870 val16 = (u16)psta->authalg;
2872 if (status != WLAN_STATUS_SUCCESS)
2878 mgmt->u.auth.auth_alg = cpu_to_le16(val16);
2880 /* setting auth seq number */
2881 mgmt->u.auth.auth_transaction =
2882 cpu_to_le16((u16)psta->auth_seq);
2884 /* setting status code... */
2885 mgmt->u.auth.status_code = cpu_to_le16(status);
2887 pframe = mgmt->u.auth.variable;
2888 /* added challenging text... */
2889 if ((psta->auth_seq == 2) &&
2890 (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
2891 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
2892 psta->chg_txt, &pattrib->pktlen);
2895 struct ieee80211_mgmt *iv_mgmt;
2897 ether_addr_copy(mgmt->da, get_my_bssid23a(&pmlmeinfo->network));
2898 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
2899 ether_addr_copy(mgmt->bssid,
2900 get_my_bssid23a(&pmlmeinfo->network));
2902 /* setting auth algo number */
2903 /* 0:OPEN System, 1:Shared key */
2904 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
2906 auth_algo = WLAN_AUTH_SHARED_KEY;
2908 auth_algo = WLAN_AUTH_OPEN;
2910 /* DBG_8723A("%s auth_algo = %s auth_seq =%d\n", __func__,
2911 (pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED",
2912 pmlmeinfo->auth_seq); */
2914 /* setting IV for auth seq #3 */
2915 if ((pmlmeinfo->auth_seq == 3) &&
2916 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
2917 (use_shared_key == 1)) {
2918 u32 *piv = (u32 *)&mgmt->u.auth;
2920 iv_mgmt = (struct ieee80211_mgmt *)(pframe + 4);
2921 /* DBG_8723A("==> iv(%d), key_index(%d)\n",
2922 pmlmeinfo->iv, pmlmeinfo->key_index); */
2923 val32 = (pmlmeinfo->iv & 0x3fffffff) |
2924 (pmlmeinfo->key_index << 30);
2926 put_unaligned_le32(val32, piv);
2928 pattrib->pktlen += 4;
2930 pattrib->iv_len = IEEE80211_WEP_IV_LEN;
2934 iv_mgmt->u.auth.auth_alg = cpu_to_le16(auth_algo);
2936 /* setting auth seq number */
2937 iv_mgmt->u.auth.auth_transaction =
2938 cpu_to_le16(pmlmeinfo->auth_seq);
2940 /* setting status code... */
2941 iv_mgmt->u.auth.status_code = cpu_to_le16(status);
2943 pframe = iv_mgmt->u.auth.variable;
2945 /* then checking to see if sending challenging text... */
2946 if ((pmlmeinfo->auth_seq == 3) &&
2947 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
2948 (use_shared_key == 1)) {
2949 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
2953 mgmt->frame_control |=
2954 cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2956 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2958 pattrib->encrypt = WLAN_CIPHER_SUITE_WEP40;
2960 pattrib->icv_len = IEEE80211_WEP_ICV_LEN;
2962 pattrib->pktlen += pattrib->icv_len;
2966 pattrib->last_txcmdsz = pattrib->pktlen;
2968 rtw_wep_encrypt23a(padapter, pmgntframe);
2969 DBG_8723A("%s\n", __func__);
2970 dump_mgntframe23a(padapter, pmgntframe);
2975 #ifdef CONFIG_8723AU_AP_MODE
2976 static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
2977 struct sta_info *pstat, u16 pkt_type)
2979 struct xmit_frame *pmgntframe;
2980 struct ieee80211_mgmt *mgmt;
2981 struct pkt_attrib *pattrib;
2982 unsigned char *pframe;
2983 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2984 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2985 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2986 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2987 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
2989 u8 *ie = pnetwork->IEs;
2991 DBG_8723A("%s\n", __func__);
2993 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2997 /* update attribute */
2998 pattrib = &pmgntframe->attrib;
2999 update_mgntframe_attrib23a(padapter, pattrib);
3001 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3003 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3004 mgmt = (struct ieee80211_mgmt *)pframe;
3006 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | pkt_type);
3008 ether_addr_copy(mgmt->da, pstat->hwaddr);
3009 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
3010 ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
3012 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3014 pmlmeext->mgnt_seq++;
3016 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3018 offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
3020 mgmt->u.assoc_resp.capab_info = cpu_to_le16(pnetwork->capability);
3021 mgmt->u.assoc_resp.status_code = cpu_to_le16(status);
3022 mgmt->u.assoc_resp.aid = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
3024 pframe = mgmt->u.assoc_resp.variable;
3026 if (pstat->bssratelen <= 8) {
3027 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3028 pstat->bssratelen, pstat->bssrateset,
3031 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3032 pstat->bssrateset, &pattrib->pktlen);
3033 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3034 pstat->bssratelen - 8,
3035 pstat->bssrateset + 8, &pattrib->pktlen);
3038 if (pstat->flags & WLAN_STA_HT && pmlmepriv->htpriv.ht_option) {
3039 /* FILL HT CAP INFO IE */
3040 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
3041 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ie,
3042 pnetwork->IELength);
3044 memcpy(pframe, p, p[1] + 2);
3045 pframe += (p[1] + 2);
3046 pattrib->pktlen += (p[1] + 2);
3049 /* FILL HT ADD INFO IE */
3050 /* p = hostapd_eid_ht_operation(hapd, p); */
3051 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, ie,
3052 pnetwork->IELength);
3053 if (p && p[1] > 0) {
3054 memcpy(pframe, p, p[1] + 2);
3055 pframe += (p[1] + 2);
3056 pattrib->pktlen += (p[1] + 2);
3061 if (pstat->flags & WLAN_STA_WME && pmlmepriv->qos_option) {
3062 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02,
3066 for (p = ie; ; p += (ie_len + 2)) {
3067 p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p,
3068 pnetwork->IELength - (ie_len + 2));
3073 if (p && !memcmp(p + 2, WMM_PARA_IE, 6)) {
3074 memcpy(pframe, p, ie_len + 2);
3075 pframe += (ie_len + 2);
3076 pattrib->pktlen += (ie_len + 2);
3081 if (!p || ie_len == 0)
3086 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) {
3087 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3088 REALTEK_96B_IE, &pattrib->pktlen);
3091 pattrib->last_txcmdsz = pattrib->pktlen;
3093 dump_mgntframe23a(padapter, pmgntframe);
3097 static void issue_assocreq(struct rtw_adapter *padapter)
3100 struct xmit_frame *pmgntframe;
3101 struct pkt_attrib *pattrib;
3102 unsigned char *pframe;
3104 struct ieee80211_mgmt *mgmt;
3105 unsigned int i, j, index = 0;
3106 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
3107 struct registry_priv *pregpriv = &padapter->registrypriv;
3108 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3109 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3110 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3111 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3112 int bssrate_len = 0, sta_bssrate_len = 0, pie_len;
3115 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3119 /* update attribute */
3120 pattrib = &pmgntframe->attrib;
3121 update_mgntframe_attrib23a(padapter, pattrib);
3123 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3125 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
3126 mgmt = (struct ieee80211_mgmt *)pframe;
3128 mgmt->frame_control =
3129 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ);
3131 ether_addr_copy(mgmt->da, get_my_bssid23a(&pmlmeinfo->network));
3132 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
3133 ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
3135 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3136 pmlmeext->mgnt_seq++;
3139 put_unaligned_le16(pmlmeinfo->network.capability,
3140 &mgmt->u.assoc_req.capab_info);
3141 /* todo: listen interval for power saving */
3142 put_unaligned_le16(3, &mgmt->u.assoc_req.listen_interval);
3144 pframe = mgmt->u.assoc_req.variable;
3145 pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
3148 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
3149 pmlmeinfo->network.Ssid.ssid_len,
3150 pmlmeinfo->network.Ssid.ssid, &pattrib->pktlen);
3152 /* supported rate & extended supported rate */
3154 get_rate_set23a(padapter, sta_bssrate, &sta_bssrate_len);
3155 /* DBG_8723A("sta_bssrate_len =%d\n", sta_bssrate_len); */
3157 /* for JAPAN, channel 14 can only uses B Mode(CCK) */
3158 if (pmlmeext->cur_channel == 14)
3159 sta_bssrate_len = 4;
3161 /* for (i = 0; i < sta_bssrate_len; i++) { */
3162 /* DBG_8723A("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
3165 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3166 if (pmlmeinfo->network.SupportedRates[i] == 0)
3168 DBG_8723A("network.SupportedRates[%d]=%02X\n", i,
3169 pmlmeinfo->network.SupportedRates[i]);
3172 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3173 if (pmlmeinfo->network.SupportedRates[i] == 0)
3176 /* Check if the AP's supported rates are also
3177 supported by STA. */
3178 for (j = 0; j < sta_bssrate_len; j++) {
3179 /* Avoid the proprietary data rate (22Mbps) of
3180 Handlink WSG-4000 AP */
3181 if ((pmlmeinfo->network.SupportedRates[i] |
3182 IEEE80211_BASIC_RATE_MASK) ==
3183 (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
3184 /* DBG_8723A("match i = %d, j =%d\n", i, j); */
3189 if (j == sta_bssrate_len) {
3190 /* the rate is not supported by STA */
3191 DBG_8723A("%s(): the rate[%d]=%02X is not supported by "
3192 "STA!\n", __func__, i,
3193 pmlmeinfo->network.SupportedRates[i]);
3195 /* the rate is supported by STA */
3196 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
3200 bssrate_len = index;
3201 DBG_8723A("bssrate_len = %d\n", bssrate_len);
3203 if (bssrate_len == 0) {
3204 rtw_free_xmitbuf23a(pxmitpriv, pmgntframe->pxmitbuf);
3205 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
3206 goto exit; /* don't connect to AP if no joint supported rate */
3209 if (bssrate_len > 8) {
3210 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3211 bssrate, &pattrib->pktlen);
3212 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3213 (bssrate_len - 8), (bssrate + 8),
3216 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3217 bssrate_len, bssrate, &pattrib->pktlen);
3221 pie = pmlmeinfo->network.IEs;
3222 pie_len = pmlmeinfo->network.IELength;
3224 p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
3226 pframe = rtw_set_ie23a(pframe, WLAN_EID_RSN, p[1], p + 2,
3230 if (padapter->mlmepriv.htpriv.ht_option) {
3231 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, pie_len);
3233 if (p && !is_ap_in_tkip23a(padapter)) {
3234 struct ieee80211_ht_cap *cap = &pmlmeinfo->ht_cap;
3236 memcpy(cap, p + 2, sizeof(struct ieee80211_ht_cap));
3238 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
3239 if (pregpriv->cbw40_enable == 0) {
3240 cap->cap_info &= ~cpu_to_le16(
3241 IEEE80211_HT_CAP_SGI_40 |
3242 IEEE80211_HT_CAP_SUP_WIDTH_20_40);
3244 cap->cap_info |= cpu_to_le16(
3245 IEEE80211_HT_CAP_SUP_WIDTH_20_40);
3248 /* todo: disable SM power save mode */
3249 cap->cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SM_PS);
3251 rf_type = rtl8723a_get_rf_type(padapter);
3252 /* switch (pregpriv->rf_config) */
3255 /* RX STBC One spatial stream */
3256 if (pregpriv->rx_stbc)
3257 cap->cap_info |= cpu_to_le16(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3259 memcpy(&cap->mcs, MCS_rate_1R23A, 16);
3265 /* enable for 2.4/5 GHz */
3266 if (pregpriv->rx_stbc == 0x3 ||
3267 (pmlmeext->cur_wireless_mode &
3269 /* enable for 2.4GHz */
3270 pregpriv->rx_stbc == 0x1) ||
3271 (pmlmeext->cur_wireless_mode &
3273 pregpriv->rx_stbc == 0x2) ||
3274 /* enable for 5GHz */
3275 pregpriv->wifi_spec == 1) {
3276 DBG_8723A("declare supporting RX "
3278 /* RX STBC two spatial stream */
3279 cap->cap_info |= cpu_to_le16(2 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3281 memcpy(&cap->mcs, MCS_rate_2R23A, 16);
3285 if (rtl8723a_BT_coexist(padapter) &&
3286 rtl8723a_BT_using_antenna_1(padapter)) {
3288 cap->ampdu_params_info &=
3289 ~IEEE80211_HT_AMPDU_PARM_FACTOR;
3290 /* cap->ampdu_params_info |= MAX_AMPDU_FACTOR_8K */
3293 pframe = rtw_set_ie23a(pframe, WLAN_EID_HT_CAPABILITY,
3294 p[1], (u8 *)&pmlmeinfo->ht_cap,
3299 /* vendor specific IE, such as WPA, WMM, WPS */
3300 for (i = 0; i < pmlmeinfo->network.IELength;) {
3301 p = pmlmeinfo->network.IEs + i;
3304 case WLAN_EID_VENDOR_SPECIFIC:
3305 if (!memcmp(p + 2, RTW_WPA_OUI23A_TYPE, 4) ||
3306 !memcmp(p + 2, WMM_OUI23A, 4) ||
3307 !memcmp(p + 2, WPS_OUI23A, 4)) {
3309 if (!padapter->registrypriv.wifi_spec) {
3310 /* Commented by Kurt 20110629 */
3311 /* In some older APs, WPS handshake */
3312 /* would be fail if we append vender
3313 extensions informations to AP */
3314 if (!memcmp(p + 2, WPS_OUI23A, 4))
3317 pframe = rtw_set_ie23a(pframe,
3318 WLAN_EID_VENDOR_SPECIFIC,
3331 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
3332 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3333 REALTEK_96B_IE, &pattrib->pktlen);
3335 pattrib->last_txcmdsz = pattrib->pktlen;
3336 dump_mgntframe23a(padapter, pmgntframe);
3341 pmlmepriv->assoc_req_len = 0;
3342 if (ret == _SUCCESS) {
3343 kfree(pmlmepriv->assoc_req);
3344 pmlmepriv->assoc_req = kmalloc(pattrib->pktlen, GFP_ATOMIC);
3345 if (pmlmepriv->assoc_req) {
3346 memcpy(pmlmepriv->assoc_req, mgmt, pattrib->pktlen);
3347 pmlmepriv->assoc_req_len = pattrib->pktlen;
3350 kfree(pmlmepriv->assoc_req);
3355 /* when wait_ack is ture, this function shoule be called at process context */
3356 static int _issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3357 unsigned int power_mode, int wait_ack)
3360 struct xmit_frame *pmgntframe;
3361 struct pkt_attrib *pattrib;
3362 unsigned char *pframe;
3363 struct ieee80211_hdr *pwlanhdr;
3364 struct xmit_priv *pxmitpriv;
3365 struct mlme_ext_priv *pmlmeext;
3366 struct mlme_ext_info *pmlmeinfo;
3368 /* DBG_8723A("%s:%d\n", __func__, power_mode); */
3373 pxmitpriv = &padapter->xmitpriv;
3374 pmlmeext = &padapter->mlmeextpriv;
3375 pmlmeinfo = &pmlmeext->mlmext_info;
3377 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3381 /* update attribute */
3382 pattrib = &pmgntframe->attrib;
3383 update_mgntframe_attrib23a(padapter, pattrib);
3384 pattrib->retry_ctrl = false;
3386 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3388 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3389 pwlanhdr = (struct ieee80211_hdr *)pframe;
3391 pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
3392 IEEE80211_STYPE_NULLFUNC);
3394 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3395 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
3396 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3397 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_TODS);
3400 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
3402 ether_addr_copy(pwlanhdr->addr1, da);
3403 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3404 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3406 pwlanhdr->seq_ctrl =
3407 cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3408 pmlmeext->mgnt_seq++;
3410 pframe += sizeof(struct ieee80211_hdr_3addr);
3411 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3413 pattrib->last_txcmdsz = pattrib->pktlen;
3416 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3418 dump_mgntframe23a(padapter, pmgntframe);
3426 /* when wait_ms >0 , this function shoule be called at process context */
3427 /* da == NULL for station mode */
3428 int issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3429 unsigned int power_mode, int try_cnt, int wait_ms)
3433 unsigned long start = jiffies;
3434 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3435 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3437 /* da == NULL, assum it's null data for sta to ap*/
3439 da = get_my_bssid23a(&pmlmeinfo->network);
3442 ret = _issue_nulldata23a(padapter, da, power_mode,
3443 wait_ms > 0 ? true : false);
3447 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3450 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3453 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3460 if (try_cnt && wait_ms) {
3462 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3463 "in %u ms\n", __func__,
3464 padapter->pnetdev->name,
3465 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3466 ret == _SUCCESS?", acked":"", i, try_cnt,
3467 jiffies_to_msecs(jiffies - start));
3469 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3470 __func__, padapter->pnetdev->name,
3471 rtw_get_oper_ch23a(padapter),
3472 ret == _SUCCESS?", acked":"", i, try_cnt,
3473 jiffies_to_msecs(jiffies - start));
3479 /* when wait_ack is ture, this function shoule be called at process context */
3480 static int _issue_qos_nulldata23a(struct rtw_adapter *padapter,
3481 unsigned char *da, u16 tid, int wait_ack)
3484 struct xmit_frame *pmgntframe;
3485 struct pkt_attrib *pattrib;
3486 unsigned char *pframe;
3487 struct ieee80211_qos_hdr *pwlanhdr;
3488 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3489 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3490 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3492 DBG_8723A("%s\n", __func__);
3494 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3498 /* update attribute */
3499 pattrib = &pmgntframe->attrib;
3500 update_mgntframe_attrib23a(padapter, pattrib);
3502 pattrib->hdrlen += 2;
3503 pattrib->qos_en = true;
3505 pattrib->ack_policy = 0;
3508 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3510 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3511 pwlanhdr = (struct ieee80211_qos_hdr *)pframe;
3513 pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
3514 IEEE80211_STYPE_QOS_NULLFUNC);
3516 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3517 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
3518 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3519 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_TODS);
3522 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
3524 pwlanhdr->qos_ctrl = cpu_to_le16(tid & IEEE80211_QOS_CTL_TID_MASK);
3525 pwlanhdr->qos_ctrl |= cpu_to_le16((pattrib->ack_policy << 5) &
3526 IEEE80211_QOS_CTL_ACK_POLICY_MASK);
3528 pwlanhdr->qos_ctrl |= cpu_to_le16(IEEE80211_QOS_CTL_EOSP);
3530 ether_addr_copy(pwlanhdr->addr1, da);
3531 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3532 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3534 pwlanhdr->seq_ctrl =
3535 cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3536 pmlmeext->mgnt_seq++;
3538 pframe += sizeof(struct ieee80211_qos_hdr);
3539 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
3541 pattrib->last_txcmdsz = pattrib->pktlen;
3544 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3546 dump_mgntframe23a(padapter, pmgntframe);
3554 /* when wait_ms >0 , this function shoule be called at process context */
3555 /* da == NULL for station mode */
3556 int issue_qos_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3557 u16 tid, int try_cnt, int wait_ms)
3561 unsigned long start = jiffies;
3562 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3563 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3565 /* da == NULL, assum it's null data for sta to ap*/
3567 da = get_my_bssid23a(&pmlmeinfo->network);
3570 ret = _issue_qos_nulldata23a(padapter, da, tid,
3571 wait_ms > 0 ? true : false);
3575 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3578 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3580 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3587 if (try_cnt && wait_ms) {
3589 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3590 "in %u ms\n", __func__,
3591 padapter->pnetdev->name,
3592 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3593 ret == _SUCCESS?", acked":"", i, try_cnt,
3594 jiffies_to_msecs(jiffies - start));
3596 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3597 __func__, padapter->pnetdev->name,
3598 rtw_get_oper_ch23a(padapter),
3599 ret == _SUCCESS?", acked":"", i, try_cnt,
3600 jiffies_to_msecs(jiffies - start));
3606 static int _issue_deauth(struct rtw_adapter *padapter, unsigned char *da,
3607 unsigned short reason, u8 wait_ack)
3609 struct xmit_frame *pmgntframe;
3610 struct pkt_attrib *pattrib;
3611 struct ieee80211_mgmt *mgmt;
3612 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3613 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3614 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3617 /* DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
3619 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3623 /* update attribute */
3624 pattrib = &pmgntframe->attrib;
3625 update_mgntframe_attrib23a(padapter, pattrib);
3626 pattrib->retry_ctrl = false;
3628 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3630 mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
3632 mgmt->frame_control =
3633 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH);
3635 ether_addr_copy(mgmt->da, da);
3636 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
3637 ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
3639 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3640 pmlmeext->mgnt_seq++;
3642 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr) + 2;
3644 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
3646 pattrib->last_txcmdsz = pattrib->pktlen;
3649 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3651 dump_mgntframe23a(padapter, pmgntframe);
3659 int issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
3660 unsigned short reason)
3662 DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
3663 return _issue_deauth(padapter, da, reason, false);
3666 static int issue_deauth_ex(struct rtw_adapter *padapter, u8 *da,
3667 unsigned short reason, int try_cnt, int wait_ms)
3671 unsigned long start = jiffies;
3674 ret = _issue_deauth(padapter, da, reason,
3675 wait_ms >0 ? true : false);
3679 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3682 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3685 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3692 if (try_cnt && wait_ms) {
3694 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3695 "in %u ms\n", __func__,
3696 padapter->pnetdev->name,
3697 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3698 ret == _SUCCESS?", acked":"", i, try_cnt,
3699 jiffies_to_msecs(jiffies - start));
3701 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3702 __func__, padapter->pnetdev->name,
3703 rtw_get_oper_ch23a(padapter),
3704 ret == _SUCCESS?", acked":"", i, try_cnt,
3705 jiffies_to_msecs(jiffies - start));
3711 void issue_action_spct_ch_switch23a(struct rtw_adapter *padapter,
3712 u8 *ra, u8 new_ch, u8 ch_offset)
3714 struct xmit_frame *pmgntframe;
3715 struct pkt_attrib *pattrib;
3716 unsigned char *pframe;
3717 struct ieee80211_mgmt *mgmt;
3718 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3719 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3721 DBG_8723A("%s(%s): ra ="MAC_FMT", ch:%u, offset:%u\n", __func__,
3722 padapter->pnetdev->name, MAC_ARG(ra), new_ch, ch_offset);
3724 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3728 /* update attribute */
3729 pattrib = &pmgntframe->attrib;
3730 update_mgntframe_attrib23a(padapter, pattrib);
3732 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3734 mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
3736 mgmt->frame_control =
3737 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
3739 ether_addr_copy(mgmt->da, ra); /* RA */
3740 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv)); /* TA */
3741 ether_addr_copy(mgmt->bssid, ra); /* DA = RA */
3743 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3744 pmlmeext->mgnt_seq++;
3746 mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
3747 mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH;
3749 pframe = mgmt->u.action.u.chan_switch.variable;
3750 pattrib->pktlen = offsetof(struct ieee80211_mgmt,
3751 u.action.u.chan_switch.variable);
3753 pframe = rtw_set_ie23a_ch_switch (pframe, &pattrib->pktlen, 0,
3755 pframe = rtw_set_ie23a_secondary_ch_offset(pframe, &pattrib->pktlen,
3756 hal_ch_offset_to_secondary_ch_offset23a(ch_offset));
3758 pattrib->last_txcmdsz = pattrib->pktlen;
3760 dump_mgntframe23a(padapter, pmgntframe);
3763 void issue_action_BA23a(struct rtw_adapter *padapter,
3764 const unsigned char *raddr,
3765 unsigned char action, unsigned short status)
3769 u16 BA_timeout_value;
3770 u16 BA_starting_seqctrl;
3772 int max_rx_ampdu_factor;
3773 struct xmit_frame *pmgntframe;
3774 struct pkt_attrib *pattrib;
3775 struct ieee80211_mgmt *mgmt;
3776 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3777 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3778 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3779 struct sta_info *psta;
3780 struct sta_priv *pstapriv = &padapter->stapriv;
3781 struct registry_priv *pregpriv = &padapter->registrypriv;
3782 u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
3784 DBG_8723A("%s, action =%d, status =%d\n", __func__, action, status);
3786 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3790 /* update attribute */
3791 pattrib = &pmgntframe->attrib;
3792 update_mgntframe_attrib23a(padapter, pattrib);
3794 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3796 mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
3798 mgmt->frame_control =
3799 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
3801 ether_addr_copy(mgmt->da, raddr);
3802 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
3803 ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
3805 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3806 pmlmeext->mgnt_seq++;
3808 mgmt->u.action.category = WLAN_CATEGORY_BACK;
3810 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr) + 1;
3812 status = cpu_to_le16(status);
3815 case WLAN_ACTION_ADDBA_REQ:
3816 pattrib->pktlen += sizeof(mgmt->u.action.u.addba_req);
3818 mgmt->u.action.u.addba_req.action_code = action;
3821 pmlmeinfo->dialogToken++;
3822 } while (pmlmeinfo->dialogToken == 0);
3824 mgmt->u.action.u.addba_req.dialog_token =
3825 pmlmeinfo->dialogToken;
3827 if (rtl8723a_BT_coexist(padapter) &&
3828 rtl8723a_BT_using_antenna_1(padapter) &&
3829 (pmlmeinfo->assoc_AP_vendor != broadcomAP ||
3830 memcmp(raddr, tendaAPMac, 3))) {
3831 /* A-MSDU NOT Supported */
3833 /* immediate Block Ack */
3834 BA_para_set |= (1 << 1) &
3835 IEEE80211_ADDBA_PARAM_POLICY_MASK;
3837 BA_para_set |= (status << 2) &
3838 IEEE80211_ADDBA_PARAM_TID_MASK;
3839 /* max buffer size is 8 MSDU */
3840 BA_para_set |= (8 << 6) &
3841 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3843 /* immediate ack & 64 buffer size */
3844 BA_para_set = (0x1002 | ((status & 0xf) << 2));
3847 put_unaligned_le16(BA_para_set,
3848 &mgmt->u.action.u.addba_req.capab);
3850 BA_timeout_value = 5000;/* 5ms */
3851 BA_timeout_value = cpu_to_le16(BA_timeout_value);
3852 put_unaligned_le16(BA_timeout_value,
3853 &mgmt->u.action.u.addba_req.timeout);
3855 psta = rtw_get_stainfo23a(pstapriv, raddr);
3859 idx = status & 0x07;
3861 (psta->sta_xmitpriv.txseq_tid[idx] & 0xfff) + 1;
3863 DBG_8723A("BA_starting_seqctrl = %d for TID =%d\n",
3866 psta->BA_starting_seqctrl[idx] = start_seq;
3868 BA_starting_seqctrl = start_seq << 4;
3870 BA_starting_seqctrl = 0;
3872 put_unaligned_le16(BA_starting_seqctrl,
3873 &mgmt->u.action.u.addba_req.start_seq_num);
3877 case WLAN_ACTION_ADDBA_RESP:
3878 pattrib->pktlen += sizeof(mgmt->u.action.u.addba_resp);
3880 mgmt->u.action.u.addba_resp.action_code = action;
3881 mgmt->u.action.u.addba_resp.dialog_token =
3882 pmlmeinfo->ADDBA_req.dialog_token;
3883 put_unaligned_le16(status,
3884 &mgmt->u.action.u.addba_resp.status);
3886 GetHalDefVar8192CUsb(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
3887 &max_rx_ampdu_factor);
3889 BA_para = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f;
3890 if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_64K)
3891 BA_para_set = BA_para | 0x1000; /* 64 buffer size */
3892 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_32K)
3893 BA_para_set = BA_para | 0x0800; /* 32 buffer size */
3894 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_16K)
3895 BA_para_set = BA_para | 0x0400; /* 16 buffer size */
3896 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_8K)
3897 BA_para_set = BA_para | 0x0200; /* 8 buffer size */
3899 BA_para_set = BA_para | 0x1000; /* 64 buffer size */
3901 if (rtl8723a_BT_coexist(padapter) &&
3902 rtl8723a_BT_using_antenna_1(padapter) &&
3903 (pmlmeinfo->assoc_AP_vendor != broadcomAP ||
3904 memcmp(raddr, tendaAPMac, 3))) {
3905 /* max buffer size is 8 MSDU */
3906 BA_para_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3907 BA_para_set |= (8 << 6) &
3908 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3911 if (pregpriv->ampdu_amsdu == 0)/* disabled */
3912 BA_para_set &= ~BIT(0);
3913 else if (pregpriv->ampdu_amsdu == 1)/* enabled */
3914 BA_para_set |= BIT(0);
3916 put_unaligned_le16(BA_para_set,
3917 &mgmt->u.action.u.addba_resp.capab);
3919 put_unaligned_le16(pmlmeinfo->ADDBA_req.BA_timeout_value,
3920 &mgmt->u.action.u.addba_resp.timeout);
3922 pattrib->pktlen += 8;
3924 case WLAN_ACTION_DELBA:
3925 pattrib->pktlen += sizeof(mgmt->u.action.u.delba);
3927 mgmt->u.action.u.delba.action_code = action;
3928 BA_para_set = (status & 0x1F) << 3;
3929 mgmt->u.action.u.delba.params = cpu_to_le16(BA_para_set);
3930 mgmt->u.action.u.delba.reason_code =
3931 cpu_to_le16(WLAN_REASON_QSTA_NOT_USE);
3933 pattrib->pktlen += 5;
3939 pattrib->last_txcmdsz = pattrib->pktlen;
3941 dump_mgntframe23a(padapter, pmgntframe);
3944 int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr)
3946 struct sta_priv *pstapriv = &padapter->stapriv;
3947 struct sta_info *psta = NULL;
3948 /* struct recv_reorder_ctrl *preorder_ctrl; */
3949 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3950 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3953 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
3954 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3957 psta = rtw_get_stainfo23a(pstapriv, addr);
3961 if (initiator == 0) { /* recipient */
3962 for (tid = 0; tid < MAXTID; tid++) {
3963 if (psta->recvreorder_ctrl[tid].enable == true) {
3964 DBG_8723A("rx agg disable tid(%d)\n", tid);
3965 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
3966 psta->recvreorder_ctrl[tid].enable = false;
3967 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
3970 } else if (initiator == 1) { /* originator */
3971 for (tid = 0; tid < MAXTID; tid++) {
3972 if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
3973 DBG_8723A("tx agg disable tid(%d)\n", tid);
3974 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
3975 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3976 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
3984 int send_beacon23a(struct rtw_adapter *padapter)
3989 unsigned long start = jiffies;
3990 unsigned int passing_time;
3992 rtl8723a_bcn_valid(padapter);
3994 issue_beacon23a(padapter, 100);
3998 bxmitok = rtl8723a_get_bcn_valid(padapter);
4000 } while ((poll % 10) != 0 && bxmitok == false &&
4001 !padapter->bSurpriseRemoved &&
4002 !padapter->bDriverStopped);
4004 } while (!bxmitok && issue<100 && !padapter->bSurpriseRemoved &&
4005 !padapter->bDriverStopped);
4007 if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
4010 passing_time = jiffies_to_msecs(jiffies - start);
4013 DBG_8723A("%s fail! %u ms\n", __func__, passing_time);
4017 if (passing_time > 100 || issue > 3)
4018 DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n",
4019 __func__, issue, poll, passing_time);
4024 /****************************************************************************
4026 Following are some utitity fuctions for WiFi MLME
4028 *****************************************************************************/
4030 bool IsLegal5GChannel(struct rtw_adapter *Adapter, u8 channel)
4034 u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
4035 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
4036 114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
4037 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
4039 for (i = 0; i < sizeof(Channel_5G); i++)
4040 if (channel == Channel_5G[i])
4045 static void rtw_site_survey(struct rtw_adapter *padapter)
4047 unsigned char survey_channel = 0;
4048 enum rt_scan_type ScanType = SCAN_PASSIVE;
4049 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4050 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4051 struct rtw_ieee80211_channel *ch;
4053 if (pmlmeext->sitesurvey_res.channel_idx <
4054 pmlmeext->sitesurvey_res.ch_num) {
4055 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
4056 survey_channel = ch->hw_value;
4057 ScanType = (ch->flags & IEEE80211_CHAN_NO_IR) ?
4058 SCAN_PASSIVE : SCAN_ACTIVE;
4061 if (survey_channel != 0) {
4062 /* PAUSE 4-AC Queue when site_survey */
4063 if (pmlmeext->sitesurvey_res.channel_idx == 0)
4064 set_channel_bwmode23a(padapter, survey_channel,
4065 HAL_PRIME_CHNL_OFFSET_DONT_CARE,
4066 HT_CHANNEL_WIDTH_20);
4068 SelectChannel23a(padapter, survey_channel);
4070 if (ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */
4073 for (i = 0;i<RTW_SSID_SCAN_AMOUNT;i++) {
4074 if (pmlmeext->sitesurvey_res.ssid[i].ssid_len) {
4075 /* todo: to issue two probe req??? */
4076 issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4077 /* msleep(SURVEY_TO>>1); */
4078 issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4082 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
4083 /* todo: to issue two probe req??? */
4084 issue_probereq(padapter, NULL, NULL);
4085 /* msleep(SURVEY_TO>>1); */
4086 issue_probereq(padapter, NULL, NULL);
4090 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
4092 /* channel number is 0 or this channel is not valid. */
4093 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
4095 /* switch back to the original channel */
4097 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
4098 pmlmeext->cur_ch_offset,
4099 pmlmeext->cur_bwmode);
4101 /* flush 4-AC Queue after rtw_site_survey */
4105 rtl8723a_set_media_status(padapter, pmlmeinfo->state & 0x3);
4107 /* restore RX GAIN */
4108 rtl8723a_set_initial_gain(padapter, 0xff);
4109 /* turn on dynamic functions */
4110 rtl8723a_odm_support_ability_restore(padapter);
4112 if (is_client_associated_to_ap23a(padapter) == true)
4113 issue_nulldata23a(padapter, NULL, 0, 3, 500);
4115 rtl8723a_mlme_sitesurvey(padapter, 0);
4117 report_surveydone_event23a(padapter);
4119 pmlmeext->chan_scan_time = SURVEY_TO;
4120 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
4126 /* collect bss info from Beacon and Probe request/response frames. */
4127 static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter,
4128 struct recv_frame *precv_frame)
4130 struct sk_buff *skb = precv_frame->pkt;
4131 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
4132 struct registry_priv *pregistrypriv = &padapter->registrypriv;
4133 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4134 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4135 struct wlan_bssid_ex *bssid;
4138 unsigned int length;
4143 bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
4147 if (ieee80211_is_beacon(mgmt->frame_control)) {
4148 length -= offsetof(struct ieee80211_mgmt, u.beacon.variable);
4149 pie = mgmt->u.beacon.variable;
4150 bssid->reserved = 1;
4152 get_unaligned_le16(&mgmt->u.beacon.capab_info);
4153 bssid->beacon_interval =
4154 get_unaligned_le16(&mgmt->u.beacon.beacon_int);
4155 bssid->tsf = get_unaligned_le64(&mgmt->u.beacon.timestamp);
4156 } else if (ieee80211_is_probe_req(mgmt->frame_control)) {
4157 length -= offsetof(struct ieee80211_mgmt, u.probe_req.variable);
4158 pie = mgmt->u.probe_req.variable;
4159 bssid->reserved = 2;
4160 bssid->capability = 0;
4161 bssid->beacon_interval =
4162 padapter->registrypriv.dev_network.beacon_interval;
4164 } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4166 offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
4167 pie = mgmt->u.probe_resp.variable;
4168 bssid->reserved = 3;
4170 get_unaligned_le16(&mgmt->u.probe_resp.capab_info);
4171 bssid->beacon_interval =
4172 get_unaligned_le16(&mgmt->u.probe_resp.beacon_int);
4173 bssid->tsf = get_unaligned_le64(&mgmt->u.probe_resp.timestamp);
4175 length -= offsetof(struct ieee80211_mgmt, u.beacon.variable);
4176 pie = mgmt->u.beacon.variable;
4177 bssid->reserved = 0;
4179 get_unaligned_le16(&mgmt->u.beacon.capab_info);
4180 bssid->beacon_interval =
4181 padapter->registrypriv.dev_network.beacon_interval;
4185 if (length > MAX_IE_SZ) {
4186 /* DBG_8723A("IE too long for survey event\n"); */
4191 bssid->Length = offsetof(struct wlan_bssid_ex, IEs) + length;
4193 /* below is to copy the information element */
4194 bssid->IELength = length;
4195 memcpy(bssid->IEs, pie, bssid->IELength);
4197 /* get the signal strength */
4198 /* in dBM.raw data */
4199 bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower;
4200 bssid->PhyInfo.SignalQuality =
4201 precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
4202 bssid->PhyInfo.SignalStrength =
4203 precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
4206 p = cfg80211_find_ie(WLAN_EID_SSID, bssid->IEs, bssid->IELength);
4209 DBG_8723A("marc: cannot find SSID for survey event\n");
4213 if (p[1] > IEEE80211_MAX_SSID_LEN) {
4214 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4215 "event\n", __func__, __LINE__, p[1]);
4218 memcpy(bssid->Ssid.ssid, p + 2, p[1]);
4219 bssid->Ssid.ssid_len = p[1];
4221 /* checking rate info... */
4223 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, bssid->IEs, bssid->IELength);
4225 if (p[1] > NDIS_802_11_LENGTH_RATES_EX) {
4226 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4227 "event\n", __func__, __LINE__, p[1]);
4230 memcpy(bssid->SupportedRates, p + 2, p[1]);
4234 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, bssid->IEs,
4237 if (p[1] > (NDIS_802_11_LENGTH_RATES_EX-i)) {
4238 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4239 "event\n", __func__, __LINE__, p[1]);
4242 memcpy(bssid->SupportedRates + i, p + 2, p[1]);
4245 /* Checking for DSConfig */
4246 p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bssid->IEs, bssid->IELength);
4248 bssid->DSConfig = 0;
4251 bssid->DSConfig = p[2];
4252 } else {/* In 5G, some ap do not have DSSET IE */
4253 /* checking HT info for channel */
4254 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, bssid->IEs,
4257 struct ieee80211_ht_operation *HT_info =
4258 (struct ieee80211_ht_operation *)(p + 2);
4259 bssid->DSConfig = HT_info->primary_chan;
4260 } else /* use current channel */
4261 bssid->DSConfig = rtw_get_oper_ch23a(padapter);
4264 if (ieee80211_is_probe_req(mgmt->frame_control)) {
4266 bssid->ifmode = NL80211_IFTYPE_STATION;
4267 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4272 if (bssid->capability & WLAN_CAPABILITY_ESS) {
4273 bssid->ifmode = NL80211_IFTYPE_STATION;
4274 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4276 bssid->ifmode = NL80211_IFTYPE_ADHOC;
4277 ether_addr_copy(bssid->MacAddress, mgmt->bssid);
4280 if (bssid->capability & WLAN_CAPABILITY_PRIVACY)
4285 bssid->ATIMWindow = 0;
4287 /* 20/40 BSS Coexistence check */
4288 if (pregistrypriv->wifi_spec == 1 &&
4289 pmlmeinfo->bwmode_updated == false) {
4290 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4292 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, bssid->IEs,
4294 if (p && p[1] > 0) {
4295 struct ieee80211_ht_cap *pHT_caps;
4296 pHT_caps = (struct ieee80211_ht_cap *)(p + 2);
4298 if (pHT_caps->cap_info &
4299 cpu_to_le16(IEEE80211_HT_CAP_40MHZ_INTOLERANT))
4300 pmlmepriv->num_FortyMHzIntolerant++;
4302 pmlmepriv->num_sta_no_ht++;
4306 /* mark bss info receving from nearby channel as SignalQuality 101 */
4307 if (bssid->DSConfig != rtw_get_oper_ch23a(padapter))
4308 bssid->PhyInfo.SignalQuality = 101;
4316 static void start_create_ibss(struct rtw_adapter* padapter)
4318 unsigned short caps;
4319 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4320 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4321 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4322 pmlmeext->cur_channel = (u8)pnetwork->DSConfig;
4323 pmlmeinfo->bcn_interval = pnetwork->beacon_interval;
4325 /* update wireless mode */
4326 update_wireless_mode23a(padapter);
4328 /* udpate capability */
4329 caps = pnetwork->capability;
4330 update_capinfo23a(padapter, caps);
4331 if (caps & WLAN_CAPABILITY_IBSS) { /* adhoc master */
4332 rtl8723a_set_sec_cfg(padapter, 0xcf);
4334 /* switch channel */
4335 /* SelectChannel23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
4336 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4338 rtl8723a_SetBeaconRelatedRegisters(padapter);
4340 /* set msr to WIFI_FW_ADHOC_STATE */
4341 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4342 rtl8723a_set_media_status(padapter, pmlmeinfo->state & 0x3);
4345 if (send_beacon23a(padapter) == _FAIL)
4347 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("issuing beacon frame fail....\n"));
4349 report_join_res23a(padapter, -1);
4350 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4354 hw_var_set_bssid(padapter, padapter->registrypriv.dev_network.MacAddress);
4355 hw_var_set_mlme_join(padapter, 0);
4357 report_join_res23a(padapter, 1);
4358 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
4363 DBG_8723A("%s: invalid cap:%x\n", __func__, caps);
4368 static void start_clnt_join(struct rtw_adapter* padapter)
4370 unsigned short caps;
4372 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4373 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4374 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4377 pmlmeext->cur_channel = (u8)pnetwork->DSConfig;
4378 pmlmeinfo->bcn_interval = pnetwork->beacon_interval;
4380 /* update wireless mode */
4381 update_wireless_mode23a(padapter);
4383 /* udpate capability */
4384 caps = pnetwork->capability;
4385 update_capinfo23a(padapter, caps);
4386 if (caps & WLAN_CAPABILITY_ESS) {
4387 /* switch channel */
4388 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4390 rtl8723a_set_media_status(padapter, WIFI_FW_STATION_STATE);
4392 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ?
4395 rtl8723a_set_sec_cfg(padapter, val8);
4397 /* switch channel */
4398 /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
4400 /* here wait for receiving the beacon to start auth */
4401 /* and enable a timer */
4402 beacon_timeout = decide_wait_for_beacon_timeout23a(pmlmeinfo->bcn_interval);
4403 set_link_timer(pmlmeext, beacon_timeout);
4404 mod_timer(&padapter->mlmepriv.assoc_timer, jiffies +
4405 msecs_to_jiffies((REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout));
4406 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
4407 } else if (caps & WLAN_CAPABILITY_IBSS) { /* adhoc client */
4408 rtl8723a_set_media_status(padapter, WIFI_FW_ADHOC_STATE);
4410 rtl8723a_set_sec_cfg(padapter, 0xcf);
4412 /* switch channel */
4413 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4415 rtl8723a_SetBeaconRelatedRegisters(padapter);
4417 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4419 report_join_res23a(padapter, 1);
4423 /* DBG_8723A("marc: invalid cap:%x\n", caps); */
4428 static void start_clnt_auth(struct rtw_adapter* padapter)
4430 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4431 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4433 del_timer_sync(&pmlmeext->link_timer);
4435 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
4436 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
4438 pmlmeinfo->auth_seq = 1;
4439 pmlmeinfo->reauth_count = 0;
4440 pmlmeinfo->reassoc_count = 0;
4441 pmlmeinfo->link_count = 0;
4442 pmlmeext->retry = 0;
4444 /* Because of AP's not receiving deauth before */
4445 /* AP may: 1)not response auth or 2)deauth us after link is complete */
4446 /* issue deauth before issuing auth to deal with the situation */
4447 /* Commented by Albert 2012/07/21 */
4448 /* For the Win8 P2P connection, it will be hard to have a
4449 successful connection if this Wi-Fi doesn't connect to it. */
4450 issue_deauth23a(padapter, (&pmlmeinfo->network)->MacAddress,
4451 WLAN_REASON_DEAUTH_LEAVING);
4453 DBG_8723A_LEVEL(_drv_always_, "start auth\n");
4454 issue_auth(padapter, NULL, 0);
4456 set_link_timer(pmlmeext, REAUTH_TO);
4459 static void start_clnt_assoc(struct rtw_adapter* padapter)
4461 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4462 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4464 del_timer_sync(&pmlmeext->link_timer);
4466 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
4467 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
4469 issue_assocreq(padapter);
4471 set_link_timer(pmlmeext, REASSOC_TO);
4474 int receive_disconnect23a(struct rtw_adapter *padapter,
4475 unsigned char *MacAddr, unsigned short reason)
4477 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4478 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4481 if (!ether_addr_equal(MacAddr, get_my_bssid23a(&pmlmeinfo->network)))
4484 DBG_8723A("%s\n", __func__);
4486 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
4488 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
4490 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4491 report_del_sta_event23a(padapter, MacAddr, reason);
4494 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
4496 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4497 report_join_res23a(padapter, -2);
4504 static void process_80211d(struct rtw_adapter *padapter,
4505 struct wlan_bssid_ex *bssid)
4507 struct registry_priv *pregistrypriv;
4508 struct mlme_ext_priv *pmlmeext;
4509 struct rt_channel_info *chplan_new;
4513 pregistrypriv = &padapter->registrypriv;
4514 pmlmeext = &padapter->mlmeextpriv;
4516 /* Adjust channel plan by AP Country IE */
4517 if (pregistrypriv->enable80211d &&
4518 !pmlmeext->update_channel_plan_by_ap_done) {
4520 struct rt_channel_plan chplan_ap;
4521 struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
4523 u8 fcn; /* first channel number */
4524 u8 noc; /* number of channel */
4527 ie = cfg80211_find_ie(WLAN_EID_COUNTRY, bssid->IEs,
4529 if (!ie || ie[1] < IEEE80211_COUNTRY_IE_MIN_LEN)
4536 memcpy(country, p, 3);
4540 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4541 ("%s: 802.11d country =%s\n", __func__, country));
4544 while ((ie - p) >= 3) {
4549 for (j = 0; j < noc; j++) {
4551 channel = fcn + j; /* 2.4 GHz */
4553 channel = fcn + j * 4; /* 5 GHz */
4555 chplan_ap.Channel[i++] = channel;
4560 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
4561 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
4562 chplan_new = pmlmeext->channel_set;
4565 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
4567 if (i == MAX_CHANNEL_NUM ||
4568 chplan_sta[i].ChannelNum == 0 ||
4569 chplan_sta[i].ChannelNum > 14)
4572 if (j == chplan_ap.Len ||
4573 chplan_ap.Channel[j] > 14)
4576 if (chplan_sta[i].ChannelNum ==
4577 chplan_ap.Channel[j]) {
4578 chplan_new[k].ChannelNum =
4579 chplan_ap.Channel[j];
4580 chplan_new[k].ScanType = SCAN_ACTIVE;
4584 } else if (chplan_sta[i].ChannelNum <
4585 chplan_ap.Channel[j]) {
4586 chplan_new[k].ChannelNum =
4587 chplan_sta[i].ChannelNum;
4588 chplan_new[k].ScanType =
4592 } else if (chplan_sta[i].ChannelNum >
4593 chplan_ap.Channel[j]) {
4594 chplan_new[k].ChannelNum =
4595 chplan_ap.Channel[j];
4596 chplan_new[k].ScanType =
4603 /* change AP not support channel to Passive scan */
4604 while (i < MAX_CHANNEL_NUM &&
4605 chplan_sta[i].ChannelNum != 0 &&
4606 chplan_sta[i].ChannelNum <= 14) {
4607 chplan_new[k].ChannelNum =
4608 chplan_sta[i].ChannelNum;
4609 chplan_new[k].ScanType = SCAN_PASSIVE;
4614 /* add channel AP supported */
4615 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14){
4616 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4617 chplan_new[k].ScanType = SCAN_ACTIVE;
4622 /* keep original STA 2.4G channel plan */
4623 while (i < MAX_CHANNEL_NUM &&
4624 chplan_sta[i].ChannelNum != 0 &&
4625 chplan_sta[i].ChannelNum <= 14) {
4626 chplan_new[k].ChannelNum =
4627 chplan_sta[i].ChannelNum;
4628 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4633 /* skip AP 2.4G channel plan */
4634 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14)
4638 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
4640 if (i == MAX_CHANNEL_NUM ||
4641 chplan_sta[i].ChannelNum == 0)
4644 if (j == chplan_ap.Len ||
4645 chplan_ap.Channel[j] == 0)
4648 if (chplan_sta[i].ChannelNum ==
4649 chplan_ap.Channel[j]) {
4650 chplan_new[k].ChannelNum =
4651 chplan_ap.Channel[j];
4652 chplan_new[k].ScanType = SCAN_ACTIVE;
4656 } else if (chplan_sta[i].ChannelNum <
4657 chplan_ap.Channel[j]) {
4658 chplan_new[k].ChannelNum =
4659 chplan_sta[i].ChannelNum;
4660 chplan_new[k].ScanType = SCAN_PASSIVE;
4663 } else if (chplan_sta[i].ChannelNum >
4664 chplan_ap.Channel[j]) {
4665 chplan_new[k].ChannelNum =
4666 chplan_ap.Channel[j];
4667 chplan_new[k].ScanType = SCAN_ACTIVE;
4673 /* change AP not support channel to Passive scan */
4674 while (i < MAX_CHANNEL_NUM &&
4675 chplan_sta[i].ChannelNum != 0) {
4676 chplan_new[k].ChannelNum =
4677 chplan_sta[i].ChannelNum;
4678 chplan_new[k].ScanType = SCAN_PASSIVE;
4683 /* add channel AP supported */
4684 while (j < chplan_ap.Len && chplan_ap.Channel[j] != 0) {
4685 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4686 chplan_new[k].ScanType = SCAN_ACTIVE;
4691 /* keep original STA 5G channel plan */
4692 while (i < MAX_CHANNEL_NUM &&
4693 chplan_sta[i].ChannelNum != 0) {
4694 chplan_new[k].ChannelNum =
4695 chplan_sta[i].ChannelNum;
4696 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4701 pmlmeext->update_channel_plan_by_ap_done = 1;
4704 /* If channel is used by AP, set channel scan type to active */
4705 channel = bssid->DSConfig;
4706 chplan_new = pmlmeext->channel_set;
4708 while (i < MAX_CHANNEL_NUM && chplan_new[i].ChannelNum != 0) {
4709 if (chplan_new[i].ChannelNum == channel) {
4710 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
4711 /* 5G Bnad 2, 3 (DFS) doesn't change
4713 if (channel >= 52 && channel <= 144)
4716 chplan_new[i].ScanType = SCAN_ACTIVE;
4717 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4718 ("%s: change channel %d scan type "
4719 "from passive to active\n",
4720 __func__, channel));
4728 /****************************************************************************
4730 Following are the functions to report events
4732 *****************************************************************************/
4734 void report_survey_event23a(struct rtw_adapter *padapter,
4735 struct recv_frame *precv_frame)
4737 struct cmd_obj *pcmd_obj;
4740 struct survey_event *psurvey_evt;
4741 struct C2HEvent_Header *pc2h_evt_hdr;
4742 struct mlme_ext_priv *pmlmeext;
4743 struct cmd_priv *pcmdpriv;
4748 pmlmeext = &padapter->mlmeextpriv;
4749 pcmdpriv = &padapter->cmdpriv;
4751 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4755 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
4756 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4762 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4763 pcmd_obj->cmdsz = cmdsz;
4764 pcmd_obj->parmbuf = pevtcmd;
4766 pcmd_obj->rsp = NULL;
4767 pcmd_obj->rspsz = 0;
4769 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
4770 pc2h_evt_hdr->len = sizeof(struct survey_event);
4771 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
4772 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4774 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4776 psurvey_evt->bss = collect_bss_info(padapter, precv_frame);
4777 if (!psurvey_evt->bss) {
4783 process_80211d(padapter, psurvey_evt->bss);
4785 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4787 pmlmeext->sitesurvey_res.bss_cnt++;
4792 void report_surveydone_event23a(struct rtw_adapter *padapter)
4794 struct cmd_obj *pcmd_obj;
4797 struct surveydone_event *psurveydone_evt;
4798 struct C2HEvent_Header *pc2h_evt_hdr;
4799 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4800 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4802 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4806 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
4807 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4813 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4814 pcmd_obj->cmdsz = cmdsz;
4815 pcmd_obj->parmbuf = pevtcmd;
4817 pcmd_obj->rsp = NULL;
4818 pcmd_obj->rspsz = 0;
4820 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
4821 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
4822 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
4823 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4825 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4826 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
4828 DBG_8723A("survey done event(%x)\n", psurveydone_evt->bss_cnt);
4830 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4835 void report_join_res23a(struct rtw_adapter *padapter, int res)
4837 struct cmd_obj *pcmd_obj;
4840 struct joinbss_event *pjoinbss_evt;
4841 struct C2HEvent_Header *pc2h_evt_hdr;
4842 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4843 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4844 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4846 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4850 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
4851 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4857 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4858 pcmd_obj->cmdsz = cmdsz;
4859 pcmd_obj->parmbuf = pevtcmd;
4861 pcmd_obj->rsp = NULL;
4862 pcmd_obj->rspsz = 0;
4864 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
4865 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
4866 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
4867 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4869 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4870 memcpy((unsigned char *)&pjoinbss_evt->network.network,
4871 &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
4872 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
4874 DBG_8723A("report_join_res23a(%d)\n", res);
4876 rtw_joinbss_event_prehandle23a(padapter, (u8 *)&pjoinbss_evt->network);
4878 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4883 void report_del_sta_event23a(struct rtw_adapter *padapter,
4884 unsigned char* MacAddr, unsigned short reason)
4886 struct cmd_obj *pcmd_obj;
4889 struct sta_info *psta;
4891 struct stadel_event *pdel_sta_evt;
4892 struct C2HEvent_Header *pc2h_evt_hdr;
4893 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4894 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4896 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4900 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
4901 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4907 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4908 pcmd_obj->cmdsz = cmdsz;
4909 pcmd_obj->parmbuf = pevtcmd;
4911 pcmd_obj->rsp = NULL;
4912 pcmd_obj->rspsz = 0;
4914 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
4915 pc2h_evt_hdr->len = sizeof(struct stadel_event);
4916 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
4917 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4919 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4920 ether_addr_copy((unsigned char *)&pdel_sta_evt->macaddr, MacAddr);
4921 memcpy((unsigned char *)pdel_sta_evt->rsvd, (unsigned char *)&reason,
4924 psta = rtw_get_stainfo23a(&padapter->stapriv, MacAddr);
4926 mac_id = (int)psta->mac_id;
4930 pdel_sta_evt->mac_id = mac_id;
4932 DBG_8723A("report_del_sta_event23a: delete STA, mac_id =%d\n", mac_id);
4934 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4939 void report_add_sta_event23a(struct rtw_adapter *padapter,
4940 unsigned char* MacAddr, int cam_idx)
4942 struct cmd_obj *pcmd_obj;
4945 struct stassoc_event *padd_sta_evt;
4946 struct C2HEvent_Header *pc2h_evt_hdr;
4947 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4948 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4950 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4954 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
4955 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4961 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4962 pcmd_obj->cmdsz = cmdsz;
4963 pcmd_obj->parmbuf = pevtcmd;
4965 pcmd_obj->rsp = NULL;
4966 pcmd_obj->rspsz = 0;
4968 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
4969 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
4970 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
4971 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4973 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4974 ether_addr_copy((unsigned char *)&padd_sta_evt->macaddr, MacAddr);
4975 padd_sta_evt->cam_id = cam_idx;
4977 DBG_8723A("report_add_sta_event23a: add STA\n");
4979 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4984 /****************************************************************************
4986 Following are the event callback functions
4988 *****************************************************************************/
4990 /* for sta/adhoc mode */
4991 void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta)
4993 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4994 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4995 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4998 VCS_update23a(padapter, psta);
5001 if (pmlmepriv->htpriv.ht_option)
5003 psta->htpriv.ht_option = true;
5005 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
5007 if (support_short_GI23a(padapter, &pmlmeinfo->ht_cap))
5008 psta->htpriv.sgi = true;
5010 psta->qos_option = true;
5015 psta->htpriv.ht_option = false;
5017 psta->htpriv.ampdu_enable = false;
5019 psta->htpriv.sgi = false;
5020 psta->qos_option = false;
5023 psta->htpriv.bwmode = pmlmeext->cur_bwmode;
5024 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
5026 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
5027 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
5030 if (pmlmepriv->qos_option)
5031 psta->qos_option = true;
5033 psta->state = _FW_LINKED;
5036 void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter,
5039 struct sta_info *psta, *psta_bmc;
5040 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5041 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5042 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
5043 struct sta_priv *pstapriv = &padapter->stapriv;
5046 hw_var_set_mlme_join(padapter, 1);
5047 hw_var_set_bssid(padapter, null_addr);
5049 /* restore to initial setting. */
5050 update_tx_basic_rate23a(padapter,
5051 padapter->registrypriv.wireless_mode);
5053 goto exit_mlmeext_joinbss_event_callback23a;
5056 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5059 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
5062 pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
5063 update_bmc_sta_support_rate23a(padapter, psta_bmc->mac_id);
5064 Update_RA_Entry23a(padapter, psta_bmc);
5068 /* turn on dynamic functions */
5069 rtl8723a_odm_support_ability_set(padapter, DYNAMIC_ALL_FUNC_ENABLE);
5071 /* update IOT-releated issue */
5072 update_IOT_info23a(padapter);
5074 HalSetBrateCfg23a(padapter, cur_network->SupportedRates);
5077 rtl8723a_set_beacon_interval(padapter, pmlmeinfo->bcn_interval);
5079 /* udpate capability */
5080 update_capinfo23a(padapter, pmlmeinfo->capability);
5082 /* WMM, Update EDCA param */
5083 WMMOnAssocRsp23a(padapter);
5086 HTOnAssocRsp23a(padapter);
5088 /* Set cur_channel&cur_bwmode&cur_ch_offset */
5089 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5091 psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
5092 if (psta) /* only for infra. mode */
5094 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5096 /* DBG_8723A("set_sta_rate23a\n"); */
5098 psta->wireless_mode = pmlmeext->cur_wireless_mode;
5100 /* set per sta rate after updating HT cap. */
5101 set_sta_rate23a(padapter, psta);
5104 hw_var_set_mlme_join(padapter, 2);
5106 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
5107 /* correcting TSF */
5108 rtw_correct_TSF(padapter);
5110 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5113 rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_CONNECT, 0);
5115 exit_mlmeext_joinbss_event_callback23a:
5116 DBG_8723A("=>%s\n", __func__);
5119 void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter,
5120 struct sta_info *psta)
5122 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5123 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5125 DBG_8723A("%s\n", __func__);
5127 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
5128 /* adhoc master or sta_count>1 */
5129 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
5132 } else { /* adhoc client */
5133 /* correcting TSF */
5134 rtw_correct_TSF(padapter);
5137 if (send_beacon23a(padapter) != _SUCCESS) {
5138 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
5140 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
5145 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
5147 hw_var_set_mlme_join(padapter, 2);
5150 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5152 /* rate radaptive */
5153 Update_RA_Entry23a(padapter, psta);
5155 /* update adhoc sta_info */
5156 update_sta_info23a(padapter, psta);
5159 void mlmeext_sta_del_event_callback23a(struct rtw_adapter *padapter)
5161 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5162 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5164 if (is_client_associated_to_ap23a(padapter) ||
5165 is_IBSS_empty23a(padapter)) {
5166 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5168 hw_var_set_mlme_disconnect(padapter);
5169 hw_var_set_bssid(padapter, null_addr);
5171 /* restore to initial setting. */
5172 update_tx_basic_rate23a(padapter,
5173 padapter->registrypriv.wireless_mode);
5175 /* switch to the 20M Hz mode after disconnect */
5176 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5177 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5179 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
5180 pmlmeext->cur_ch_offset,
5181 pmlmeext->cur_bwmode);
5183 flush_all_cam_entry23a(padapter);
5185 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5187 /* set MSR to no link state -> infra. mode */
5188 rtl8723a_set_media_status(padapter, _HW_STATE_STATION_);
5190 del_timer_sync(&pmlmeext->link_timer);
5194 static u8 chk_ap_is_alive(struct rtw_adapter *padapter, struct sta_info *psta)
5198 if (sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta) &&
5199 sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) &&
5200 sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
5205 sta_update_last_rx_pkts(psta);
5209 void linked_status_chk23a(struct rtw_adapter *padapter)
5212 struct sta_info *psta;
5213 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5214 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5215 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5216 struct sta_priv *pstapriv = &padapter->stapriv;
5218 if (is_client_associated_to_ap23a(padapter)) {
5219 /* linked infrastructure client mode */
5221 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
5226 psta = rtw_get_stainfo23a(pstapriv,
5227 pmlmeinfo->network.MacAddress);
5229 bool is_p2p_enable = false;
5231 if (chk_ap_is_alive(padapter, psta) == false)
5234 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
5237 if (pmlmeext->active_keep_alive_check &&
5238 (rx_chk == _FAIL || tx_chk == _FAIL)) {
5239 u8 backup_oper_channel = 0;
5241 /* switch to correct channel of current
5242 network before issue keep-alive frames */
5243 if (rtw_get_oper_ch23a(padapter) !=
5244 pmlmeext->cur_channel) {
5245 backup_oper_channel =
5246 rtw_get_oper_ch23a(padapter);
5247 SelectChannel23a(padapter,
5248 pmlmeext->cur_channel);
5251 if (rx_chk != _SUCCESS)
5252 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
5254 if ((tx_chk != _SUCCESS &&
5255 pmlmeinfo->link_count++ == 0xf) ||
5256 rx_chk != _SUCCESS) {
5257 tx_chk = issue_nulldata23a(padapter,
5260 /* if tx acked and p2p disabled,
5261 set rx_chk _SUCCESS to reset retry
5263 if (tx_chk == _SUCCESS &&
5268 /* back to the original operation channel */
5269 if (backup_oper_channel>0)
5270 SelectChannel23a(padapter,
5271 backup_oper_channel);
5273 if (rx_chk != _SUCCESS) {
5274 if (pmlmeext->retry == 0) {
5275 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5276 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5277 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5281 if (tx_chk != _SUCCESS &&
5282 pmlmeinfo->link_count++ == 0xf)
5283 tx_chk = issue_nulldata23a(padapter,
5288 if (rx_chk == _FAIL) {
5290 if (pmlmeext->retry > rx_chk_limit) {
5291 DBG_8723A_LEVEL(_drv_always_,
5292 "%s(%s): disconnect or "
5293 "roaming\n", __func__,
5294 padapter->pnetdev->name);
5295 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress,
5296 WLAN_REASON_EXPIRATION_CHK);
5300 pmlmeext->retry = 0;
5302 if (tx_chk == _FAIL)
5303 pmlmeinfo->link_count &= 0xf;
5305 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
5306 pmlmeinfo->link_count = 0;
5310 } else if (is_client_associated_to_ibss23a(padapter)) {
5311 /* linked IBSS mode */
5312 /* for each assoc list entry to check the rx pkt counter */
5313 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
5314 if (pmlmeinfo->FW_sta_info[i].status == 1) {
5315 psta = pmlmeinfo->FW_sta_info[i].psta;
5320 if (pmlmeinfo->FW_sta_info[i].rx_pkt ==
5321 sta_rx_pkts(psta)) {
5323 if (pmlmeinfo->FW_sta_info[i].retry<3) {
5324 pmlmeinfo->FW_sta_info[i].retry++;
5326 pmlmeinfo->FW_sta_info[i].retry = 0;
5327 pmlmeinfo->FW_sta_info[i].status = 0;
5328 report_del_sta_event23a(padapter, psta->hwaddr,
5329 65535/* indicate disconnect caused by no rx */
5333 pmlmeinfo->FW_sta_info[i].retry = 0;
5334 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
5338 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5342 static void survey_timer_hdl(unsigned long data)
5344 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5345 struct cmd_obj *ph2c;
5346 struct sitesurvey_parm *psurveyPara;
5347 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5348 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5350 /* issue rtw_sitesurvey_cmd23a */
5351 if (pmlmeext->sitesurvey_res.state > SCAN_START) {
5352 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
5353 pmlmeext->sitesurvey_res.channel_idx++;
5355 if (pmlmeext->scan_abort == true) {
5356 pmlmeext->sitesurvey_res.channel_idx =
5357 pmlmeext->sitesurvey_res.ch_num;
5358 DBG_8723A("%s idx:%d\n", __func__,
5359 pmlmeext->sitesurvey_res.channel_idx);
5361 pmlmeext->scan_abort = false;/* reset */
5364 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
5366 goto exit_survey_timer_hdl;
5368 psurveyPara = kzalloc(sizeof(struct sitesurvey_parm),
5372 goto exit_survey_timer_hdl;
5375 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara,
5376 GEN_CMD_CODE(_SiteSurvey));
5377 rtw_enqueue_cmd23a(pcmdpriv, ph2c);
5380 exit_survey_timer_hdl:
5384 static void link_timer_hdl(unsigned long data)
5386 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5387 /* static unsigned int rx_pkt = 0; */
5388 /* static u64 tx_cnt = 0; */
5389 /* struct xmit_priv *pxmitpriv = &padapter->xmitpriv; */
5390 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5391 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5392 /* struct sta_priv *pstapriv = &padapter->stapriv; */
5394 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
5395 DBG_8723A("link_timer_hdl:no beacon while connecting\n");
5396 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5397 report_join_res23a(padapter, -3);
5398 } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
5400 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
5401 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
5403 pmlmeinfo->state = 0;
5404 report_join_res23a(padapter, -1);
5409 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
5410 /* pmlmeinfo->reauth_count = 0; */
5414 DBG_8723A("link_timer_hdl: auth timeout and try again\n");
5415 pmlmeinfo->auth_seq = 1;
5416 issue_auth(padapter, NULL, 0);
5417 set_link_timer(pmlmeext, REAUTH_TO);
5418 } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
5419 /* re-assoc timer */
5420 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
5421 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5422 report_join_res23a(padapter, -2);
5426 DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
5427 issue_assocreq(padapter);
5428 set_link_timer(pmlmeext, REASSOC_TO);
5434 static void addba_timer_hdl(unsigned long data)
5436 struct sta_info *psta = (struct sta_info *)data;
5437 struct ht_priv *phtpriv;
5442 phtpriv = &psta->htpriv;
5444 if (phtpriv->ht_option && phtpriv->ampdu_enable) {
5445 if (phtpriv->candidate_tid_bitmap)
5446 phtpriv->candidate_tid_bitmap = 0x0;
5450 void init_addba_retry_timer23a(struct sta_info *psta)
5452 setup_timer(&psta->addba_retry_timer, addba_timer_hdl,
5453 (unsigned long)psta);
5456 void init_mlme_ext_timer23a(struct rtw_adapter *padapter)
5458 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5460 setup_timer(&pmlmeext->survey_timer, survey_timer_hdl,
5461 (unsigned long)padapter);
5463 setup_timer(&pmlmeext->link_timer, link_timer_hdl,
5464 (unsigned long)padapter);
5467 int NULL_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5472 int setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5474 enum nl80211_iftype type;
5475 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5476 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5477 const struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
5479 switch (psetop->mode) {
5480 case NL80211_IFTYPE_P2P_GO:
5481 case NL80211_IFTYPE_AP:
5482 pmlmeinfo->state = WIFI_FW_AP_STATE;
5483 type = _HW_STATE_AP_;
5485 case NL80211_IFTYPE_P2P_CLIENT:
5486 case NL80211_IFTYPE_STATION:
5488 pmlmeinfo->state &= ~(BIT(0)|BIT(1));
5489 /* set to STATION_STATE */
5490 pmlmeinfo->state |= WIFI_FW_STATION_STATE;
5491 type = _HW_STATE_STATION_;
5493 case NL80211_IFTYPE_ADHOC:
5494 type = _HW_STATE_ADHOC_;
5497 type = _HW_STATE_NOLINK_;
5501 hw_var_set_opmode(padapter, type);
5502 /* Set_NETYPE0_MSR(padapter, type); */
5507 int createbss_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5509 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5510 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5511 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5512 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5513 /* u32 initialgain; */
5515 if (pparm->ifmode == NL80211_IFTYPE_AP ||
5516 pparm->ifmode == NL80211_IFTYPE_P2P_GO) {
5517 #ifdef CONFIG_8723AU_AP_MODE
5518 if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
5525 /* below is for ad-hoc master */
5526 if (pparm->ifmode == NL80211_IFTYPE_ADHOC) {
5527 rtw_joinbss_reset23a(padapter);
5529 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5530 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5531 pmlmeinfo->ERP_enable = 0;
5532 pmlmeinfo->WMM_enable = 0;
5533 pmlmeinfo->HT_enable = 0;
5534 pmlmeinfo->HT_caps_enable = 0;
5535 pmlmeinfo->HT_info_enable = 0;
5537 /* disable dynamic functions, such as high power, DIG */
5538 rtl8723a_odm_support_ability_backup(padapter);
5540 rtl8723a_odm_support_ability_clr(padapter,
5541 DYNAMIC_FUNC_DISABLE);
5543 /* cancel link timer */
5544 del_timer_sync(&pmlmeext->link_timer);
5547 flush_all_cam_entry23a(padapter);
5549 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5550 return H2C_PARAMETERS_ERROR;
5552 memcpy(pnetwork, pparm, sizeof(struct wlan_bssid_ex));
5554 start_create_ibss(padapter);
5560 int join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5562 struct registry_priv *pregpriv = &padapter->registrypriv;
5563 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5564 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5565 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5566 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5567 struct ieee80211_ht_operation *pht_info;
5570 /* u32 initialgain; */
5573 /* check already connecting to AP or not */
5574 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
5575 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
5576 issue_deauth_ex(padapter, pnetwork->MacAddress,
5577 WLAN_REASON_DEAUTH_LEAVING, 5, 100);
5579 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5582 flush_all_cam_entry23a(padapter);
5584 del_timer_sync(&pmlmeext->link_timer);
5586 /* set MSR to nolink -> infra. mode */
5587 /* rtl8723a_set_media_status(padapter, _HW_STATE_NOLINK_); */
5588 rtl8723a_set_media_status(padapter, _HW_STATE_STATION_);
5590 hw_var_set_mlme_disconnect(padapter);
5593 rtw_joinbss_reset23a(padapter);
5595 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5596 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5597 pmlmeinfo->ERP_enable = 0;
5598 pmlmeinfo->WMM_enable = 0;
5599 pmlmeinfo->HT_enable = 0;
5600 pmlmeinfo->HT_caps_enable = 0;
5601 pmlmeinfo->HT_info_enable = 0;
5602 pmlmeinfo->bwmode_updated = false;
5603 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
5605 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5606 return H2C_PARAMETERS_ERROR;
5608 memcpy(pnetwork, pbuf, sizeof(struct wlan_bssid_ex));
5610 /* Check AP vendor to move rtw_joinbss_cmd23a() */
5611 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pnetwork->IEs,
5612 pnetwork->IELength); */
5614 for (i = 0; i < pnetwork->IELength;) {
5615 p = pnetwork->IEs + i;
5618 case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */
5619 if (!memcmp(p + 2, WMM_OUI23A, 4))
5620 pmlmeinfo->WMM_enable = 1;
5623 case WLAN_EID_HT_CAPABILITY: /* Get HT Cap IE. */
5624 pmlmeinfo->HT_caps_enable = 1;
5627 case WLAN_EID_HT_OPERATION: /* Get HT Info IE. */
5628 pmlmeinfo->HT_info_enable = 1;
5630 /* spec case only for cisco's ap because cisco's ap
5631 * issue assoc rsp using mcs rate @40MHz or @20MHz */
5632 pht_info = (struct ieee80211_ht_operation *)(p + 2);
5634 if (pregpriv->cbw40_enable &&
5635 (pht_info->ht_param &
5636 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
5637 /* switch to the 40M Hz mode according to AP */
5638 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
5639 switch (pht_info->ht_param &
5640 IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
5641 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
5642 pmlmeext->cur_ch_offset =
5643 HAL_PRIME_CHNL_OFFSET_LOWER;
5646 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
5647 pmlmeext->cur_ch_offset =
5648 HAL_PRIME_CHNL_OFFSET_UPPER;
5652 pmlmeext->cur_ch_offset =
5653 HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5657 DBG_8723A("set ch/bw before connected\n");
5668 hw_var_set_bssid(padapter, pmlmeinfo->network.MacAddress);
5669 hw_var_set_mlme_join(padapter, 0);
5671 /* cancel link timer */
5672 del_timer_sync(&pmlmeext->link_timer);
5674 start_clnt_join(padapter);
5679 int disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5681 const struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
5682 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5683 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5684 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5686 if (is_client_associated_to_ap23a(padapter)) {
5687 issue_deauth_ex(padapter, pnetwork->MacAddress,
5688 WLAN_REASON_DEAUTH_LEAVING,
5689 param->deauth_timeout_ms/100, 100);
5692 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5694 /* pmlmeinfo->state = WIFI_FW_NULL_STATE; */
5696 hw_var_set_mlme_disconnect(padapter);
5697 hw_var_set_bssid(padapter, null_addr);
5699 /* restore to initial setting. */
5700 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
5702 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE ||
5703 (pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
5704 rtl8723a_set_bcn_func(padapter, 0); /* Stop BCN */
5706 /* set MSR to no link state -> infra. mode */
5707 rtl8723a_set_media_status(padapter, _HW_STATE_STATION_);
5709 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5711 /* switch to the 20M Hz mode after disconnect */
5712 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5713 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5715 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
5716 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5718 flush_all_cam_entry23a(padapter);
5720 del_timer_sync(&pmlmeext->link_timer);
5722 rtw_free_uc_swdec_pending_queue23a(padapter);
5728 rtw_scan_ch_decision(struct rtw_adapter *padapter,
5729 struct rtw_ieee80211_channel *out, u32 out_num,
5730 const struct rtw_ieee80211_channel *in, u32 in_num)
5733 int scan_ch_num = 0;
5735 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5737 /* clear out first */
5738 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
5740 /* acquire channels from in */
5742 for (i = 0;i<in_num;i++) {
5743 if (in[i].hw_value &&
5744 !(in[i].flags & IEEE80211_CHAN_DISABLED) &&
5745 (set_idx = rtw_ch_set_search_ch23a(pmlmeext->channel_set,
5746 in[i].hw_value)) >= 0) {
5747 memcpy(&out[j], &in[i],
5748 sizeof(struct rtw_ieee80211_channel));
5750 if (pmlmeext->channel_set[set_idx].ScanType ==
5752 out[j].flags &= IEEE80211_CHAN_NO_IR;
5760 /* if out is empty, use channel_set as default */
5762 for (i = 0;i<pmlmeext->max_chan_nums;i++) {
5763 out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
5765 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
5766 out[i].flags &= IEEE80211_CHAN_NO_IR;
5772 if (padapter->setband == GHZ_24) { /* 2.4G */
5773 for (i = 0; i < j ; i++) {
5774 if (out[i].hw_value > 35)
5776 sizeof(struct rtw_ieee80211_channel));
5781 } else if (padapter->setband == GHZ_50) { /* 5G */
5782 for (i = 0; i < j ; i++) {
5783 if (out[i].hw_value > 35) {
5784 memcpy(&out[scan_ch_num++], &out[i],
5785 sizeof(struct rtw_ieee80211_channel));
5795 int sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5797 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5798 const struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
5799 u8 bdelayscan = false;
5803 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
5804 pmlmeext->sitesurvey_res.state = SCAN_START;
5805 pmlmeext->sitesurvey_res.bss_cnt = 0;
5806 pmlmeext->sitesurvey_res.channel_idx = 0;
5808 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
5809 if (pparm->ssid[i].ssid_len) {
5810 memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid,
5811 pparm->ssid[i].ssid,
5812 IEEE80211_MAX_SSID_LEN);
5813 pmlmeext->sitesurvey_res.ssid[i].ssid_len =
5814 pparm->ssid[i].ssid_len;
5816 pmlmeext->sitesurvey_res.ssid[i].ssid_len = 0;
5820 pmlmeext->sitesurvey_res.ch_num =
5821 rtw_scan_ch_decision(padapter,
5822 pmlmeext->sitesurvey_res.ch,
5823 RTW_CHANNEL_SCAN_AMOUNT,
5824 pparm->ch, pparm->ch_num);
5826 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
5828 /* issue null data if associating to the AP */
5829 if (is_client_associated_to_ap23a(padapter)) {
5830 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
5832 /* switch to correct channel of current network
5833 before issue keep-alive frames */
5834 if (rtw_get_oper_ch23a(padapter) !=
5835 pmlmeext->cur_channel)
5836 SelectChannel23a(padapter,
5837 pmlmeext->cur_channel);
5839 issue_nulldata23a(padapter, NULL, 1, 3, 500);
5845 /* delay 50ms to protect nulldata(1). */
5846 set_survey_timer(pmlmeext, 50);
5851 if (pmlmeext->sitesurvey_res.state == SCAN_START ||
5852 pmlmeext->sitesurvey_res.state == SCAN_TXNULL) {
5853 /* disable dynamic functions, such as high power, DIG */
5854 rtl8723a_odm_support_ability_backup(padapter);
5855 rtl8723a_odm_support_ability_clr(padapter,
5856 DYNAMIC_FUNC_DISABLE);
5858 /* config the initial gain under scaning, need to
5859 write the BB registers */
5860 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == true)
5865 rtl8723a_set_initial_gain(padapter, initialgain);
5867 /* set MSR to no link state */
5868 rtl8723a_set_media_status(padapter, _HW_STATE_NOLINK_);
5870 rtl8723a_mlme_sitesurvey(padapter, 1);
5872 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
5875 rtw_site_survey(padapter);
5880 int setauth_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5882 const struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
5883 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5884 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5886 if (pparm->mode < 4)
5887 pmlmeinfo->auth_algo = pparm->mode;
5892 int setkey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5894 unsigned short ctrl;
5895 const struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
5896 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5897 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5898 unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
5900 /* main tx key for wep. */
5902 pmlmeinfo->key_index = pparm->keyid;
5905 ctrl = BIT(15) | (pparm->algorithm) << 2 | pparm->keyid;
5907 DBG_8723A_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 "
5908 "WEP104-5 TKIP-2 AES-4) keyid:%d\n",
5909 pparm->algorithm, pparm->keyid);
5910 rtl8723a_cam_write(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
5912 /* allow multicast packets to driver */
5913 rtl8723a_on_rcr_am(padapter);
5918 int set_stakey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5921 u8 cam_id;/* cam_entry */
5922 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5923 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5924 const struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
5927 /* 0~3 for default key */
5929 /* for concurrent mode (ap+sta): */
5930 /* default key is disable, using sw encrypt/decrypt */
5931 /* cam_entry = 4 for sta mode (macid = 0) */
5932 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
5934 /* for concurrent mode (sta+sta): */
5935 /* default key is disable, using sw encrypt/decrypt */
5936 /* cam_entry = 4 mapping to macid = 0 */
5937 /* cam_entry = 5 mapping to macid = 2 */
5941 DBG_8723A_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 "
5942 "WEP104-5 TKIP-2 AES-4) camid:%d\n",
5943 pparm->algorithm, cam_id);
5944 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
5945 struct sta_info *psta;
5946 struct sta_priv *pstapriv = &padapter->stapriv;
5948 if (pparm->algorithm == 0) { /* clear cam entry */
5949 clear_cam_entry23a(padapter, pparm->id);
5950 return H2C_SUCCESS_RSP;
5953 psta = rtw_get_stainfo23a(pstapriv, pparm->addr);
5955 ctrl = BIT(15) | (pparm->algorithm << 2);
5957 DBG_8723A("r871x_set_stakey_hdl23a(): enc_algorithm "
5958 "=%d\n", pparm->algorithm);
5960 if (psta->mac_id < 1 || psta->mac_id > (NUM_STA - 4)) {
5961 DBG_8723A("r871x_set_stakey_hdl23a():set_stakey"
5962 " failed, mac_id(aid) =%d\n",
5964 return H2C_REJECTED;
5967 /* 0~3 for default key, cmd_id = macid + 3,
5969 cam_id = (psta->mac_id + 3);
5971 DBG_8723A("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, "
5972 "cam_entry =%d\n", pparm->addr[0],
5973 pparm->addr[1], pparm->addr[2],
5974 pparm->addr[3], pparm->addr[4],
5975 pparm->addr[5], cam_id);
5977 rtl8723a_cam_write(padapter, cam_id, ctrl,
5978 pparm->addr, pparm->key);
5980 return H2C_SUCCESS_RSP;
5982 DBG_8723A("r871x_set_stakey_hdl23a(): sta has been "
5984 return H2C_REJECTED;
5988 /* below for sta mode */
5990 if (pparm->algorithm == 0) { /* clear cam entry */
5991 clear_cam_entry23a(padapter, pparm->id);
5995 ctrl = BIT(15) | (pparm->algorithm << 2);
5997 rtl8723a_cam_write(padapter, cam_id, ctrl, pparm->addr, pparm->key);
5999 pmlmeinfo->enc_algo = pparm->algorithm;
6004 int add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6006 const struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
6007 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6008 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6009 struct sta_info *psta;
6011 psta = rtw_get_stainfo23a(&padapter->stapriv, pparm->addr);
6016 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
6017 pmlmeinfo->HT_enable) ||
6018 (pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6019 issue_action_BA23a(padapter, pparm->addr,
6020 WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
6021 mod_timer(&psta->addba_retry_timer,
6022 jiffies + msecs_to_jiffies(ADDBA_TO));
6024 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
6029 int set_tx_beacon_cmd23a(struct rtw_adapter* padapter)
6031 struct cmd_obj *ph2c;
6032 struct Tx_Beacon_param *ptxBeacon_parm;
6033 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
6034 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6035 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6039 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
6045 ptxBeacon_parm = kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC);
6046 if (!ptxBeacon_parm) {
6052 memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network,
6053 sizeof(struct wlan_bssid_ex));
6055 len_diff = update_hidden_ssid(ptxBeacon_parm->network.IEs,
6056 ptxBeacon_parm->network.IELength,
6057 pmlmeinfo->hidden_ssid_mode);
6058 ptxBeacon_parm->network.IELength += len_diff;
6060 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm,
6061 GEN_CMD_CODE(_TX_Beacon));
6063 res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
6069 int mlme_evt_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6071 u8 evt_code, evt_seq;
6073 const struct C2HEvent_Header *c2h;
6074 void (*event_callback)(struct rtw_adapter *dev, const u8 *pbuf);
6076 c2h = (struct C2HEvent_Header *)pbuf;
6081 /* checking if event code is valid */
6082 if (evt_code >= MAX_C2HEVT) {
6083 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
6084 ("\nEvent Code(%d) mismatch!\n", evt_code));
6088 /* checking if event size match the event parm size */
6089 if (wlanevents[evt_code].parmsize != 0 &&
6090 wlanevents[evt_code].parmsize != evt_sz) {
6091 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
6092 ("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
6093 evt_code, wlanevents[evt_code].parmsize, evt_sz));
6097 event_callback = wlanevents[evt_code].event_callback;
6098 event_callback(padapter, pbuf + sizeof(struct C2HEvent_Header));
6105 int h2c_msg_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6108 return H2C_PARAMETERS_ERROR;
6113 int tx_beacon_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6115 if (send_beacon23a(padapter) == _FAIL) {
6116 DBG_8723A("issue_beacon23a, fail!\n");
6117 return H2C_PARAMETERS_ERROR;
6119 #ifdef CONFIG_8723AU_AP_MODE
6120 else { /* tx bc/mc frames after update TIM */
6121 struct sta_info *psta_bmc;
6122 struct list_head *plist, *phead, *ptmp;
6123 struct xmit_frame *pxmitframe;
6124 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6125 struct sta_priv *pstapriv = &padapter->stapriv;
6127 /* for BC/MC Frames */
6128 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
6132 if (pstapriv->tim_bitmap & BIT(0) && psta_bmc->sleepq_len > 0) {
6133 msleep(10);/* 10ms, ATIM(HIQ) Windows */
6134 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
6135 spin_lock_bh(&pxmitpriv->lock);
6137 phead = get_list_head(&psta_bmc->sleep_q);
6139 list_for_each_safe(plist, ptmp, phead) {
6140 pxmitframe = container_of(plist,
6144 list_del_init(&pxmitframe->list);
6146 psta_bmc->sleepq_len--;
6147 if (psta_bmc->sleepq_len>0)
6148 pxmitframe->attrib.mdata = 1;
6150 pxmitframe->attrib.mdata = 0;
6152 pxmitframe->attrib.triggered = 1;
6154 pxmitframe->attrib.qsel = 0x11;/* HIQ */
6156 rtl8723au_hal_xmitframe_enqueue(padapter,
6160 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
6161 spin_unlock_bh(&pxmitpriv->lock);
6169 int set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6171 const struct set_ch_parm *set_ch_parm;
6172 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6175 return H2C_PARAMETERS_ERROR;
6177 set_ch_parm = (struct set_ch_parm *)pbuf;
6179 DBG_8723A("%s(%s): ch:%u, bw:%u, ch_offset:%u\n", __func__,
6180 padapter->pnetdev->name, set_ch_parm->ch,
6181 set_ch_parm->bw, set_ch_parm->ch_offset);
6183 pmlmeext->cur_channel = set_ch_parm->ch;
6184 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
6185 pmlmeext->cur_bwmode = set_ch_parm->bw;
6187 set_channel_bwmode23a(padapter, set_ch_parm->ch,
6188 set_ch_parm->ch_offset, set_ch_parm->bw);
6193 int set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6195 const struct SetChannelPlan_param *setChannelPlan_param;
6196 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6199 return H2C_PARAMETERS_ERROR;
6201 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
6203 pmlmeext->max_chan_nums =
6204 init_channel_set(padapter, setChannelPlan_param->channel_plan,
6205 pmlmeext->channel_set);
6206 init_channel_list(padapter, pmlmeext->channel_set,
6207 pmlmeext->max_chan_nums, &pmlmeext->channel_list);
6212 int led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6214 struct LedBlink_param *ledBlink_param;
6217 return H2C_PARAMETERS_ERROR;
6219 ledBlink_param = (struct LedBlink_param *)pbuf;
6224 int set_csa_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6226 return H2C_REJECTED;
6229 /* TDLS_WRCR : write RCR DATA BIT */
6230 /* TDLS_SD_PTI : issue peer traffic indication */
6231 /* TDLS_CS_OFF : go back to the channel linked with AP,
6232 terminating channel switch procedure */
6233 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and
6235 /* TDLS_DONE_CH_SEN : channel sensing and report candidate channel */
6236 /* TDLS_OFF_CH : first time set channel to off channel */
6237 /* TDLS_BASE_CH : go back tp the channel linked with AP when set
6238 base channel as target channel */
6239 /* TDLS_P_OFF_CH : periodically go to off channel */
6240 /* TDLS_P_BASE_CH : periodically go back to base channel */
6241 /* TDLS_RS_RCR : restore RCR */
6242 /* TDLS_CKALV_PH1 : check alive timer phase1 */
6243 /* TDLS_CKALV_PH2 : check alive timer phase2 */
6244 /* TDLS_FREE_STA : free tdls sta */
6245 int tdls_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6247 return H2C_REJECTED;