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 static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
56 unsigned short status);
57 static int issue_deauth_ex(struct rtw_adapter *padapter, u8 *da,
58 unsigned short reason, int try_cnt, int wait_ms);
59 static void start_clnt_assoc(struct rtw_adapter *padapter);
60 static void start_clnt_auth(struct rtw_adapter *padapter);
61 static void start_clnt_join(struct rtw_adapter *padapter);
62 static void start_create_ibss(struct rtw_adapter *padapter);
63 static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter,
64 struct recv_frame *precv_frame);
66 #ifdef CONFIG_8723AU_AP_MODE
67 static int OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
68 static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
69 struct sta_info *pstat, u16 pkt_type);
72 static struct mlme_handler mlme_sta_tbl[]={
73 {"OnAssocReq23a", &OnAssocReq23a},
74 {"OnAssocRsp23a", &OnAssocRsp23a},
75 {"OnReAssocReq", &OnAssocReq23a},
76 {"OnReAssocRsp", &OnAssocRsp23a},
77 {"OnProbeReq23a", &OnProbeReq23a},
78 {"OnProbeRsp23a", &OnProbeRsp23a},
80 /*----------------------------------------------------------
82 -----------------------------------------------------------*/
83 {"DoReserved23a", &DoReserved23a},
84 {"DoReserved23a", &DoReserved23a},
85 {"OnBeacon23a", &OnBeacon23a},
86 {"OnATIM", &OnAtim23a},
87 {"OnDisassoc23a", &OnDisassoc23a},
88 {"OnAuth23a", &OnAuth23aClient23a},
89 {"OnDeAuth23a", &OnDeAuth23a},
90 {"OnAction23a", &OnAction23a},
93 static struct action_handler OnAction23a_tbl[]={
94 {WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct23a},
95 {WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction23a_qos},
96 {WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction23a_dls},
97 {WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction23a_back23a},
98 {WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public23a},
99 {WLAN_CATEGORY_HT, "ACTION_HT", &OnAction23a_ht},
100 {WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved23a},
101 {WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction23a_wmm},
102 {WLAN_CATEGORY_VENDOR_SPECIFIC, "ACTION_P2P", &OnAction23a_p2p},
105 static u8 null_addr[ETH_ALEN]= {0, 0, 0, 0, 0, 0};
107 /**************************************************
108 OUI definitions for the vendor specific IE
109 ***************************************************/
110 unsigned char WMM_OUI23A[] = {0x00, 0x50, 0xf2, 0x02};
111 unsigned char WPS_OUI23A[] = {0x00, 0x50, 0xf2, 0x04};
112 unsigned char P2P_OUI23A[] = {0x50, 0x6F, 0x9A, 0x09};
113 unsigned char WFD_OUI23A[] = {0x50, 0x6F, 0x9A, 0x0A};
115 unsigned char WMM_INFO_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
116 unsigned char WMM_PARA_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
118 static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
120 /********************************************************
122 *********************************************************/
123 unsigned char MCS_rate_2R23A[16] = {
124 0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0,
125 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
126 unsigned char MCS_rate_1R23A[16] = {
127 0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0,
128 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
130 /********************************************************
131 ChannelPlan definitions
132 *********************************************************/
134 static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
135 /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
136 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
137 /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
138 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
139 /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
140 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
141 /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
142 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
143 /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
144 {{10, 11, 12, 13}, 4},
145 /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
149 static struct rt_channel_plan_5g RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
150 /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
152 /* 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 */
153 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
154 116, 120, 124, 128, 132, 136, 140}, 19},
155 /* 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 */
156 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
157 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
158 /* 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 */
159 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
160 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22},
161 /* 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */
162 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
163 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
164 /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
165 {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},
166 /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
167 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},
168 /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
169 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12},
170 /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
171 {{149, 153, 157, 161, 165}, 5},
172 /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
173 {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
174 /* 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 */
175 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
176 116, 136, 140, 149, 153, 157, 161, 165}, 20},
177 /* 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 */
178 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
179 116, 120, 124, 149, 153, 157, 161, 165}, 20},
180 /* 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 */
181 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
182 116, 120, 124, 128, 132, 136, 140}, 19},
183 /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
184 {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
185 /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
186 {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},
187 /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
188 {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149,
189 153, 157, 161, 165}, 15},
190 /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
191 {{56, 60, 64, 149, 153, 157, 161, 165}, 8},
193 /* Driver self defined for old channel plan Compatible,
194 Remember to modify if have new channel plan definition ===== */
195 /* 0x11, RT_CHANNEL_DOMAIN_5G_FCC */
196 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
197 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},
198 /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
199 {{36, 40, 44, 48}, 4},
200 /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
201 {{36, 40, 44, 48, 149, 153, 157, 161}, 8},
204 static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
205 /* 0x00 ~ 0x1F , Old Define ===== */
206 {0x02, 0x11}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
207 {0x02, 0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
208 {0x01, 0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
209 {0x01, 0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
210 {0x01, 0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
211 {0x03, 0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
212 {0x03, 0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
213 {0x01, 0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
214 {0x03, 0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
215 {0x03, 0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
216 {0x00, 0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
217 {0x02, 0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
218 {0x01, 0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
219 {0x02, 0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
220 {0x02, 0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
221 {0x02, 0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
222 {0x01, 0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
223 {0x02, 0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
224 {0x01, 0x12}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
225 {0x00, 0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
226 {0x02, 0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
227 {0x00, 0x12}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
228 {0x00, 0x13}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
229 {0x03, 0x12}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
230 {0x05, 0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
231 {0x02, 0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
232 {0x00, 0x00}, /* 0x1A, */
233 {0x00, 0x00}, /* 0x1B, */
234 {0x00, 0x00}, /* 0x1C, */
235 {0x00, 0x00}, /* 0x1D, */
236 {0x00, 0x00}, /* 0x1E, */
237 {0x05, 0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
238 /* 0x20 ~ 0x7F , New Define ===== */
239 {0x00, 0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
240 {0x01, 0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
241 {0x02, 0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
242 {0x03, 0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
243 {0x04, 0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
244 {0x02, 0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
245 {0x00, 0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
246 {0x03, 0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
247 {0x00, 0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
248 {0x00, 0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
249 {0x00, 0x00}, /* 0x2A, */
250 {0x00, 0x00}, /* 0x2B, */
251 {0x00, 0x00}, /* 0x2C, */
252 {0x00, 0x00}, /* 0x2D, */
253 {0x00, 0x00}, /* 0x2E, */
254 {0x00, 0x00}, /* 0x2F, */
255 {0x00, 0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
256 {0x00, 0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
257 {0x00, 0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
258 {0x00, 0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
259 {0x02, 0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
260 {0x00, 0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
261 {0x00, 0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
262 {0x03, 0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
263 {0x03, 0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
264 {0x02, 0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
265 {0x00, 0x00}, /* 0x3A, */
266 {0x00, 0x00}, /* 0x3B, */
267 {0x00, 0x00}, /* 0x3C, */
268 {0x00, 0x00}, /* 0x3D, */
269 {0x00, 0x00}, /* 0x3E, */
270 {0x00, 0x00}, /* 0x3F, */
271 {0x02, 0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
272 {0x03, 0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
275 static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE =
276 {0x03, 0x02}; /* use the conbination for max channel numbers */
278 static void dummy_event_callback(struct rtw_adapter *adapter, const u8 *pbuf)
282 static struct fwevent wlanevents[] =
284 {0, &dummy_event_callback}, /*0*/
292 {0, &rtw_survey_event_cb23a}, /*8*/
293 {sizeof (struct surveydone_event), &rtw_surveydone_event_callback23a},
294 {0, &rtw23a_joinbss_event_cb}, /*10*/
295 {sizeof(struct stassoc_event), &rtw_stassoc_event_callback23a},
296 {sizeof(struct stadel_event), &rtw_stadel_event_callback23a},
297 {0, &dummy_event_callback},
298 {0, &dummy_event_callback},
303 {0, &dummy_event_callback},
307 {0, &dummy_event_callback},
312 static void rtw_correct_TSF(struct rtw_adapter *padapter)
314 hw_var_set_correct_tsf(padapter);
318 rtw_update_TSF(struct mlme_ext_priv *pmlmeext, struct ieee80211_mgmt *mgmt)
320 pmlmeext->TSFValue = get_unaligned_le64(&mgmt->u.beacon.timestamp);
324 * Search the @param channel_num in given @param channel_set
325 * @ch_set: the given channel set
326 * @ch: the given channel number
328 * return the index of channel_num in channel_set, -1 if not found
330 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 = MSR_NOLINK;
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)
569 struct registry_priv *pregistrypriv = &padapter->registrypriv;
570 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
571 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
572 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
574 pmlmeext->padapter = padapter;
576 init_mlme_ext_priv23a_value(padapter);
577 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
579 init_mlme_ext_timer23a(padapter);
581 #ifdef CONFIG_8723AU_AP_MODE
582 init_mlme_ap_info23a(padapter);
585 pmlmeext->max_chan_nums = init_channel_set(padapter,
586 pmlmepriv->ChannelPlan,
587 pmlmeext->channel_set);
588 init_channel_list(padapter, pmlmeext->channel_set,
589 pmlmeext->max_chan_nums, &pmlmeext->channel_list);
591 pmlmeext->chan_scan_time = SURVEY_TO;
592 pmlmeext->mlmeext_init = true;
594 pmlmeext->active_keep_alive_check = true;
598 void free_mlme_ext_priv23a (struct mlme_ext_priv *pmlmeext)
600 struct rtw_adapter *padapter = pmlmeext->padapter;
605 if (padapter->bDriverStopped == true) {
606 del_timer_sync(&pmlmeext->survey_timer);
607 del_timer_sync(&pmlmeext->link_timer);
608 /* del_timer_sync(&pmlmeext->ADDBA_timer); */
613 _mgt_dispatcher23a(struct rtw_adapter *padapter, struct mlme_handler *ptable,
614 struct recv_frame *precv_frame)
616 struct sk_buff *skb = precv_frame->pkt;
617 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
620 /* receive the frames that ra(a1) is my address
621 or ra(a1) is bc address. */
622 if (!ether_addr_equal(hdr->addr1, myid(&padapter->eeprompriv))&&
623 !is_broadcast_ether_addr(hdr->addr1))
626 ptable->func(padapter, precv_frame);
630 void mgt_dispatcher23a(struct rtw_adapter *padapter,
631 struct recv_frame *precv_frame)
633 struct mlme_handler *ptable;
634 #ifdef CONFIG_8723AU_AP_MODE
635 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
636 #endif /* CONFIG_8723AU_AP_MODE */
637 struct sk_buff *skb = precv_frame->pkt;
638 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
639 struct sta_info *psta;
643 if (!ieee80211_is_mgmt(mgmt->frame_control))
646 /* receive the frames that ra(a1) is my address or ra(a1) is
648 if (!ether_addr_equal(mgmt->da, myid(&padapter->eeprompriv)) &&
649 !is_broadcast_ether_addr(mgmt->da))
652 ptable = mlme_sta_tbl;
654 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
658 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
659 "Currently we do not support reserved sub-fr-type =%d\n",
665 psta = rtw_get_stainfo23a(&padapter->stapriv, mgmt->sa);
668 if (ieee80211_has_retry(mgmt->frame_control)) {
669 if (precv_frame->attrib.seq_num ==
670 psta->RxMgmtFrameSeqNum) {
671 /* drop the duplicate management frame */
672 DBG_8723A("Drop duplicate management frame "
673 "with seq_num = %d.\n",
674 precv_frame->attrib.seq_num);
678 psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num;
681 #ifdef CONFIG_8723AU_AP_MODE
683 case IEEE80211_STYPE_AUTH:
684 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
685 ptable->func = &OnAuth23a;
687 ptable->func = &OnAuth23aClient23a;
689 case IEEE80211_STYPE_ASSOC_REQ:
690 case IEEE80211_STYPE_REASSOC_REQ:
691 _mgt_dispatcher23a(padapter, ptable, precv_frame);
693 case IEEE80211_STYPE_PROBE_REQ:
694 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
695 _mgt_dispatcher23a(padapter, ptable, precv_frame);
697 _mgt_dispatcher23a(padapter, ptable, precv_frame);
699 case IEEE80211_STYPE_BEACON:
700 _mgt_dispatcher23a(padapter, ptable, precv_frame);
702 case IEEE80211_STYPE_ACTION:
703 /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) */
704 _mgt_dispatcher23a(padapter, ptable, precv_frame);
707 _mgt_dispatcher23a(padapter, ptable, precv_frame);
711 _mgt_dispatcher23a(padapter, ptable, precv_frame);
715 /****************************************************************************
717 Following are the callback functions for each subtype of the management frames
719 *****************************************************************************/
722 OnProbeReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
725 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
726 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
727 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
728 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
729 struct sk_buff *skb = precv_frame->pkt;
730 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
733 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
736 if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
737 !check_fwstate(pmlmepriv,
738 WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
741 if (unlikely(!ieee80211_is_probe_req(mgmt->frame_control))) {
742 printk(KERN_WARNING "%s: Received non probe request frame\n",
747 len -= offsetof(struct ieee80211_mgmt, u.probe_req.variable);
749 ie = cfg80211_find_ie(WLAN_EID_SSID, mgmt->u.probe_req.variable, len);
751 /* check (wildcard) SSID */
755 if ((ie[1] && memcmp(ie + 2, cur->Ssid.ssid, cur->Ssid.ssid_len)) ||
756 (ie[1] == 0 && pmlmeinfo->hidden_ssid_mode)) {
760 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
761 pmlmepriv->cur_network.join_res)
762 issue_probersp(padapter, mgmt->sa);
769 OnProbeRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
771 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
773 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
774 report_survey_event23a(padapter, precv_frame);
782 OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
785 struct sta_info *psta;
786 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
787 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
788 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
789 struct sta_priv *pstapriv = &padapter->stapriv;
790 struct sk_buff *skb = precv_frame->pkt;
791 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
792 int pkt_len = skb->len;
793 struct wlan_bssid_ex *pbss;
799 pie = mgmt->u.beacon.variable;
800 pie_len = pkt_len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
801 p = rtw_get_ie23a(pie, WLAN_EID_EXT_SUPP_RATES, &ielen, pie_len);
802 if (p && ielen > 0) {
803 if (p[1 + ielen] == 0x2D && p[2 + ielen] != 0x2D) {
804 /* Invalid value 0x2D is detected in Extended Supported
805 * Rates (ESR) IE. Try to fix the IE length to avoid
806 * failed Beacon parsing.
808 DBG_8723A("[WIFIDBG] Error in ESR IE is detected in "
809 "Beacon of BSSID: %pM. Fix the length of "
810 "ESR IE to avoid failed Beacon parsing.\n",
816 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
817 report_survey_event23a(padapter, precv_frame);
821 if (!ether_addr_equal(mgmt->bssid,
822 get_my_bssid23a(&pmlmeinfo->network)))
825 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
826 /* we should update current network before auth,
827 or some IE is wrong */
828 pbss = collect_bss_info(padapter, precv_frame);
830 update_network23a(&pmlmepriv->cur_network.network, pbss,
832 rtw_get_bcn_info23a(&pmlmepriv->cur_network);
836 /* check the vendor of the assoc AP */
837 pmlmeinfo->assoc_AP_vendor =
838 check_assoc_AP23a((u8 *)&mgmt->u.beacon, pkt_len -
839 offsetof(struct ieee80211_mgmt, u));
841 /* update TSF Value */
842 rtw_update_TSF(pmlmeext, mgmt);
845 start_clnt_auth(padapter);
850 if (((pmlmeinfo->state & 0x03) == MSR_AP) &&
851 (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
852 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
854 ret = rtw_check_bcn_info23a(padapter, mgmt, pkt_len);
855 if (ret != _SUCCESS) {
856 DBG_8723A_LEVEL(_drv_always_, "ap has changed, "
858 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress, 65535);
861 /* update WMM, ERP in the beacon */
862 /* todo: the timer is used instead of
863 the number of the beacon received */
864 if ((sta_rx_pkts(psta) & 0xf) == 0) {
865 /* DBG_8723A("update_bcn_info\n"); */
866 update_beacon23a_info(padapter, mgmt,
870 } else if ((pmlmeinfo->state&0x03) == MSR_ADHOC) {
871 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
873 /* update WMM, ERP in the beacon */
874 /* todo: the timer is used instead of the
875 number of the beacon received */
876 if ((sta_rx_pkts(psta) & 0xf) == 0) {
877 /* DBG_8723A("update_bcn_info\n"); */
878 update_beacon23a_info(padapter, mgmt,
882 /* allocate a new CAM entry for IBSS station */
883 cam_idx = allocate_fw_sta_entry23a(padapter);
884 if (cam_idx == NUM_STA)
887 /* get supported rate */
888 if (update_sta_support_rate23a(padapter, pie, pie_len,
890 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
894 /* update TSF Value */
895 rtw_update_TSF(pmlmeext, mgmt);
897 /* report sta add event */
898 report_add_sta_event23a(padapter, mgmt->sa,
908 #ifdef CONFIG_8723AU_AP_MODE
910 OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
912 static struct sta_info stat;
913 struct sta_info *pstat = NULL;
914 struct sta_priv *pstapriv = &padapter->stapriv;
915 struct security_priv *psecuritypriv = &padapter->securitypriv;
916 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
917 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
918 struct sk_buff *skb = precv_frame->pkt;
919 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
923 u16 auth_mode, seq, algorithm;
924 int status, len = skb->len;
926 if ((pmlmeinfo->state & 0x03) != MSR_AP)
929 DBG_8723A("+OnAuth23a\n");
933 auth_mode = psecuritypriv->dot11AuthAlgrthm;
935 pframe = mgmt->u.auth.variable;
936 len = skb->len - offsetof(struct ieee80211_mgmt, u.auth.variable);
938 seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
939 algorithm = le16_to_cpu(mgmt->u.auth.auth_alg);
941 DBG_8723A("auth alg =%x, seq =%X\n", algorithm, seq);
943 if (auth_mode == 2 &&
944 psecuritypriv->dot11PrivacyAlgrthm != WLAN_CIPHER_SUITE_WEP40 &&
945 psecuritypriv->dot11PrivacyAlgrthm != WLAN_CIPHER_SUITE_WEP104)
948 /* rx a shared-key auth but shared not enabled, or */
949 /* rx a open-system auth but shared-key is enabled */
950 if ((algorithm != WLAN_AUTH_OPEN && auth_mode == 0) ||
951 (algorithm == WLAN_AUTH_OPEN && auth_mode == 1)) {
952 DBG_8723A("auth rejected due to bad alg [alg =%d, auth_mib "
953 "=%d] %02X%02X%02X%02X%02X%02X\n",
954 algorithm, auth_mode,
955 sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
957 status = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
962 if (rtw_access_ctrl23a(padapter, sa) == false) {
963 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
967 pstat = rtw_get_stainfo23a(pstapriv, sa);
969 /* allocate a new one */
970 DBG_8723A("going to alloc stainfo for sa =%pM\n", sa);
971 pstat = rtw_alloc_stainfo23a(pstapriv, sa, GFP_ATOMIC);
973 DBG_8723A(" Exceed the upper limit of supported "
975 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
979 pstat->state = WIFI_FW_AUTH_NULL;
982 /* pstat->flags = 0; */
983 /* pstat->capability = 0; */
985 spin_lock_bh(&pstapriv->asoc_list_lock);
986 if (!list_empty(&pstat->asoc_list)) {
987 list_del_init(&pstat->asoc_list);
988 pstapriv->asoc_list_cnt--;
989 if (pstat->expire_to > 0) {
990 /* TODO: STA re_auth within expire_to */
993 spin_unlock_bh(&pstapriv->asoc_list_lock);
996 /* TODO: STA re_auth and auth timeout */
1000 spin_lock_bh(&pstapriv->auth_list_lock);
1001 if (list_empty(&pstat->auth_list)) {
1002 list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
1003 pstapriv->auth_list_cnt++;
1005 spin_unlock_bh(&pstapriv->auth_list_lock);
1007 if (pstat->auth_seq == 0)
1008 pstat->expire_to = pstapriv->auth_to;
1010 if ((pstat->auth_seq + 1) != seq) {
1011 DBG_8723A("(1)auth rejected because out of seq [rx_seq =%d, "
1012 "exp_seq =%d]!\n", seq, pstat->auth_seq+1);
1013 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1017 if (algorithm == WLAN_AUTH_OPEN && (auth_mode == 0 || auth_mode == 2)) {
1019 pstat->state &= ~WIFI_FW_AUTH_NULL;
1020 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1021 pstat->expire_to = pstapriv->assoc_to;
1022 pstat->authalg = algorithm;
1024 DBG_8723A("(2)auth rejected because out of seq "
1025 "[rx_seq =%d, exp_seq =%d]!\n",
1026 seq, pstat->auth_seq+1);
1027 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1030 } else { /* shared system or auto authentication */
1032 /* prepare for the challenging txt... */
1033 pstat->state &= ~WIFI_FW_AUTH_NULL;
1034 pstat->state |= WIFI_FW_AUTH_STATE;
1035 pstat->authalg = algorithm;
1036 pstat->auth_seq = 2;
1037 } else if (seq == 3) {
1038 /* checking for challenging txt... */
1039 DBG_8723A("checking for challenging txt...\n");
1041 p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pframe, len);
1042 if (!p || p[1] <= 0) {
1043 DBG_8723A("auth rejected because challenge "
1045 status = WLAN_STATUS_CHALLENGE_FAIL;
1049 if (!memcmp(p + 2, pstat->chg_txt, 128)) {
1050 pstat->state &= ~WIFI_FW_AUTH_STATE;
1051 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1052 /* challenging txt is correct... */
1053 pstat->expire_to = pstapriv->assoc_to;
1055 DBG_8723A("auth rejected because challenge "
1057 status = WLAN_STATUS_CHALLENGE_FAIL;
1061 DBG_8723A("(3)auth rejected because out of seq "
1062 "[rx_seq =%d, exp_seq =%d]!\n",
1063 seq, pstat->auth_seq+1);
1064 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1069 /* Now, we are going to issue_auth... */
1070 pstat->auth_seq = seq + 1;
1072 issue_auth(padapter, pstat, WLAN_STATUS_SUCCESS);
1074 if (pstat->state & WIFI_FW_AUTH_SUCCESS)
1075 pstat->auth_seq = 0;
1082 rtw_free_stainfo23a(padapter, pstat);
1085 memset((char *)pstat, '\0', sizeof(stat));
1086 pstat->auth_seq = 2;
1087 ether_addr_copy(pstat->hwaddr, sa);
1089 issue_auth(padapter, pstat, (unsigned short)status);
1096 OnAuth23aClient23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1098 unsigned int seq, status, algthm;
1099 unsigned int go2asoc = 0;
1100 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1101 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1102 struct sk_buff *skb = precv_frame->pkt;
1103 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1106 int plen = skb->len;
1108 DBG_8723A("%s\n", __func__);
1110 /* check A1 matches or not */
1111 if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
1114 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
1117 pie = mgmt->u.auth.variable;
1118 plen -= offsetof(struct ieee80211_mgmt, u.auth.variable);
1120 algthm = le16_to_cpu(mgmt->u.auth.auth_alg);
1121 seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
1122 status = le16_to_cpu(mgmt->u.auth.status_code);
1125 DBG_8723A("clnt auth fail, status: %d\n", status);
1126 /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
1127 if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
1128 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1129 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1131 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
1132 /* pmlmeinfo->reauth_count = 0; */
1135 set_link_timer(pmlmeext, 1);
1140 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
1141 /* legendary shared system */
1142 p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pie, plen);
1145 /* DBG_8723A("marc: no challenge text?\n"); */
1149 memcpy((void *)(pmlmeinfo->chg_txt), p + 2, p[1]);
1150 pmlmeinfo->auth_seq = 3;
1151 issue_auth(padapter, NULL, 0);
1152 set_link_timer(pmlmeext, REAUTH_TO);
1159 } else if (seq == 4) {
1160 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1165 /* this is also illegal */
1166 /* DBG_8723A("marc: clnt auth failed due to illegal seq =%x\n",
1172 DBG_8723A_LEVEL(_drv_always_, "auth success, start assoc\n");
1173 start_clnt_assoc(padapter);
1179 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
1184 #ifdef CONFIG_8723AU_AP_MODE
1185 static int rtw_validate_vendor_specific_ies(const u8 *pos, int elen)
1189 /* first 3 bytes in vendor specific information element are the IEEE
1190 * OUI of the vendor. The following byte is used a vendor specific
1193 DBG_8723A("short vendor specific information element "
1194 "ignored (len =%i)\n", elen);
1198 oui = RTW_GET_BE24(pos);
1200 case WLAN_OUI_MICROSOFT:
1201 /* Microsoft/Wi-Fi information elements are further typed and
1204 case WLAN_OUI_TYPE_MICROSOFT_WPA:
1205 /* Microsoft OUI (00:50:F2) with OUI Type 1:
1206 * real WPA information element */
1208 case WLAN_OUI_TYPE_MICROSOFT_WMM:
1210 DBG_8723A("short WME information element "
1211 "ignored (len =%i)\n", elen);
1215 case WME_OUI_SUBTYPE_INFORMATION_ELEMENT:
1216 case WME_OUI_SUBTYPE_PARAMETER_ELEMENT:
1218 case WME_OUI_SUBTYPE_TSPEC_ELEMENT:
1221 DBG_8723A("unknown WME information element "
1222 "ignored (subtype =%d len =%i)\n",
1227 case WLAN_OUI_TYPE_MICROSOFT_WPS:
1228 /* Wi-Fi Protected Setup (WPS) IE */
1231 DBG_8723A("Unknown Microsoft information element "
1232 "ignored (type =%d len =%i)\n",
1240 case VENDOR_HT_CAPAB_OUI_TYPE:
1243 DBG_8723A("Unknown Broadcom information element "
1244 "ignored (type =%d len =%i)\n", pos[3], elen);
1250 DBG_8723A("unknown vendor specific information element "
1251 "ignored (vendor OUI %02x:%02x:%02x len =%i)\n",
1252 pos[0], pos[1], pos[2], elen);
1259 static int rtw_validate_frame_ies(const u8 *start, uint len)
1261 const u8 *pos = start;
1273 DBG_8723A("%s: IEEE 802.11 failed (id =%d elen =%d "
1274 "left =%i)\n", __func__, id, elen, left);
1280 case WLAN_EID_SUPP_RATES:
1281 case WLAN_EID_FH_PARAMS:
1282 case WLAN_EID_DS_PARAMS:
1283 case WLAN_EID_CF_PARAMS:
1285 case WLAN_EID_IBSS_PARAMS:
1286 case WLAN_EID_CHALLENGE:
1287 case WLAN_EID_ERP_INFO:
1288 case WLAN_EID_EXT_SUPP_RATES:
1290 case WLAN_EID_VENDOR_SPECIFIC:
1291 if (rtw_validate_vendor_specific_ies(pos, elen))
1295 case WLAN_EID_PWR_CAPABILITY:
1296 case WLAN_EID_SUPPORTED_CHANNELS:
1297 case WLAN_EID_MOBILITY_DOMAIN:
1298 case WLAN_EID_FAST_BSS_TRANSITION:
1299 case WLAN_EID_TIMEOUT_INTERVAL:
1300 case WLAN_EID_HT_CAPABILITY:
1301 case WLAN_EID_HT_OPERATION:
1304 DBG_8723A("%s IEEE 802.11 ignored unknown element "
1305 "(id =%d elen =%d)\n", __func__, id, elen);
1321 OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1323 #ifdef CONFIG_8723AU_AP_MODE
1324 u16 capab_info, listen_interval;
1325 struct sta_info *pstat;
1326 unsigned char reassoc;
1327 int i, wpa_ie_len, left;
1328 unsigned char supportRate[16];
1330 unsigned short status = WLAN_STATUS_SUCCESS;
1331 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1332 struct security_priv *psecuritypriv = &padapter->securitypriv;
1333 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1334 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1335 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
1336 struct sta_priv *pstapriv = &padapter->stapriv;
1337 struct sk_buff *skb = precv_frame->pkt;
1338 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1339 const u8 *pos, *p, *wpa_ie, *wps_ie;
1340 u8 *pframe = skb->data;
1341 uint pkt_len = skb->len;
1344 if ((pmlmeinfo->state & 0x03) != MSR_AP)
1347 left = pkt_len - sizeof(struct ieee80211_hdr_3addr);
1348 if (ieee80211_is_assoc_req(mgmt->frame_control)) {
1350 pos = mgmt->u.assoc_req.variable;
1351 left -= offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
1352 } else { /* WIFI_REASSOCREQ */
1354 pos = mgmt->u.reassoc_req.variable;
1355 left -= offsetof(struct ieee80211_mgmt, u.reassoc_req.variable);
1359 DBG_8723A("handle_assoc(reassoc =%d) - too short payload "
1360 "(len =%lu)\n", reassoc, (unsigned long)pkt_len);
1364 pstat = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1366 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1367 goto asoc_class2_error;
1370 /* These two are located at the same offsets whether it's an
1371 * assoc_req or a reassoc_req */
1372 capab_info = get_unaligned_le16(&mgmt->u.assoc_req.capab_info);
1374 get_unaligned_le16(&mgmt->u.assoc_req.listen_interval);
1376 DBG_8723A("%s\n", __func__);
1378 /* check if this stat has been successfully authenticated/assocated */
1379 if (!(pstat->state & WIFI_FW_AUTH_SUCCESS)) {
1380 if (!(pstat->state & WIFI_FW_ASSOC_SUCCESS)) {
1381 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1382 goto asoc_class2_error;
1384 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
1385 pstat->state |= WIFI_FW_ASSOC_STATE;
1388 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1389 pstat->state |= WIFI_FW_ASSOC_STATE;
1392 pstat->capability = capab_info;
1394 /* now parse all ieee802_11 ie to point to elems */
1396 if (rtw_validate_frame_ies(pos, left)) {
1397 DBG_8723A("STA %pM sent invalid association request\n",
1399 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1400 goto OnAssocReq23aFail;
1403 /* now we should check all the fields... */
1405 p = cfg80211_find_ie(WLAN_EID_SSID, pos, left);
1406 if (!p || p[1] == 0) {
1407 /* broadcast ssid, however it is not allowed in assocreq */
1408 DBG_8723A("STA %pM sent invalid association request lacking an SSID\n",
1410 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1411 goto OnAssocReq23aFail;
1413 /* check if ssid match */
1414 if (memcmp(p + 2, cur->Ssid.ssid, cur->Ssid.ssid_len))
1415 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1417 if (p[1] != cur->Ssid.ssid_len)
1418 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1421 if (status != WLAN_STATUS_SUCCESS)
1422 goto OnAssocReq23aFail;
1424 /* check if the supported rate is ok */
1425 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, pos, left);
1427 DBG_8723A("Rx a sta assoc-req which supported rate is "
1429 /* use our own rate set as statoin used */
1430 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
1431 /* supportRateNum = AP_BSSRATE_LEN; */
1433 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1434 goto OnAssocReq23aFail;
1436 memcpy(supportRate, p + 2, p[1]);
1437 supportRateNum = p[1];
1439 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, pos, left);
1441 if (supportRateNum <= sizeof(supportRate)) {
1442 memcpy(supportRate+supportRateNum, p + 2, p[1]);
1443 supportRateNum += p[1];
1448 /* todo: mask supportRate between AP & STA -> move to update raid */
1449 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
1451 /* update station supportRate */
1452 pstat->bssratelen = supportRateNum;
1453 memcpy(pstat->bssrateset, supportRate, supportRateNum);
1454 Update23aTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
1456 /* check RSN/WPA/WPS */
1457 pstat->dot8021xalg = 0;
1459 pstat->wpa_group_cipher = 0;
1460 pstat->wpa2_group_cipher = 0;
1461 pstat->wpa_pairwise_cipher = 0;
1462 pstat->wpa2_pairwise_cipher = 0;
1463 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
1465 wpa_ie = cfg80211_find_ie(WLAN_EID_RSN, pos, left);
1467 wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1468 WLAN_OUI_TYPE_MICROSOFT_WPA,
1471 int group_cipher = 0, pairwise_cipher = 0;
1473 wpa_ie_len = wpa_ie[1];
1474 if (psecuritypriv->wpa_psk & BIT(1)) {
1475 r = rtw_parse_wpa2_ie23a(wpa_ie, wpa_ie_len + 2,
1477 &pairwise_cipher, NULL);
1478 if (r == _SUCCESS) {
1479 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1480 pstat->wpa_psk |= BIT(1);
1482 pstat->wpa2_group_cipher = group_cipher &
1483 psecuritypriv->wpa2_group_cipher;
1484 pstat->wpa2_pairwise_cipher = pairwise_cipher &
1485 psecuritypriv->wpa2_pairwise_cipher;
1487 status = WLAN_STATUS_INVALID_IE;
1488 } else if (psecuritypriv->wpa_psk & BIT(0)) {
1489 r = rtw_parse_wpa_ie23a(wpa_ie, wpa_ie_len + 2,
1490 &group_cipher, &pairwise_cipher,
1492 if (r == _SUCCESS) {
1493 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1494 pstat->wpa_psk |= BIT(0);
1496 pstat->wpa_group_cipher = group_cipher &
1497 psecuritypriv->wpa_group_cipher;
1498 pstat->wpa_pairwise_cipher = pairwise_cipher &
1499 psecuritypriv->wpa_pairwise_cipher;
1501 status = WLAN_STATUS_INVALID_IE;
1506 if (wpa_ie && status == WLAN_STATUS_SUCCESS) {
1507 if (!pstat->wpa_group_cipher)
1508 status = WLAN_STATUS_INVALID_GROUP_CIPHER;
1510 if (!pstat->wpa_pairwise_cipher)
1511 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
1515 if (status != WLAN_STATUS_SUCCESS)
1516 goto OnAssocReq23aFail;
1518 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
1520 wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1521 WLAN_OUI_TYPE_MICROSOFT_WPS,
1526 DBG_8723A("STA included WPS IE in (Re)Association "
1527 "Request - assume WPS is used\n");
1528 pstat->flags |= WLAN_STA_WPS;
1530 DBG_8723A("STA did not include WPA/RSN IE in (Re)"
1531 "Association Request - possible WPS use\n");
1532 pstat->flags |= WLAN_STA_MAYBE_WPS;
1537 if (psecuritypriv->wpa_psk == 0) {
1538 DBG_8723A("STA %pM: WPA/RSN IE in association request, but AP don't support WPA/RSN\n",
1541 status = WLAN_STATUS_INVALID_IE;
1543 goto OnAssocReq23aFail;
1547 DBG_8723A("STA included WPS IE in (Re)Association "
1548 "Request - WPS is used\n");
1549 pstat->flags |= WLAN_STA_WPS;
1552 copy_len = ((wpa_ie_len + 2) > sizeof(pstat->wpa_ie)) ?
1553 sizeof(pstat->wpa_ie) : (wpa_ie_len + 2);
1557 memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len);
1560 /* check if there is WMM IE & support WWM-PS */
1561 pstat->flags &= ~WLAN_STA_WME;
1562 pstat->qos_option = 0;
1563 pstat->qos_info = 0;
1564 pstat->has_legacy_ac = true;
1565 pstat->uapsd_vo = 0;
1566 pstat->uapsd_vi = 0;
1567 pstat->uapsd_be = 0;
1568 pstat->uapsd_bk = 0;
1569 if (pmlmepriv->qos_option) {
1570 const u8 *end = pos + left;
1576 p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1577 WLAN_OUI_TYPE_MICROSOFT_WMM,
1580 pstat->flags |= WLAN_STA_WME;
1582 pstat->qos_option = 1;
1583 pstat->qos_info = *(p + 8);
1586 (pstat->qos_info >> 5) & 0x3;
1588 if ((pstat->qos_info & 0xf) != 0xf)
1589 pstat->has_legacy_ac = true;
1591 pstat->has_legacy_ac = false;
1593 if (pstat->qos_info & 0xf) {
1594 if (pstat->qos_info & BIT(0))
1595 pstat->uapsd_vo = BIT(0)|BIT(1);
1597 pstat->uapsd_vo = 0;
1599 if (pstat->qos_info & BIT(1))
1600 pstat->uapsd_vi = BIT(0)|BIT(1);
1602 pstat->uapsd_vi = 0;
1604 if (pstat->qos_info & BIT(2))
1605 pstat->uapsd_bk = BIT(0)|BIT(1);
1607 pstat->uapsd_bk = 0;
1609 if (pstat->qos_info & BIT(3))
1610 pstat->uapsd_be = BIT(0)|BIT(1);
1612 pstat->uapsd_be = 0;
1623 /* save HT capabilities in the sta object */
1624 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
1625 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pos, left);
1627 if (p && p[1] >= sizeof(struct ieee80211_ht_cap)) {
1628 pstat->flags |= WLAN_STA_HT;
1630 pstat->flags |= WLAN_STA_WME;
1632 memcpy(&pstat->htpriv.ht_cap, p + 2,
1633 sizeof(struct ieee80211_ht_cap));
1635 pstat->flags &= ~WLAN_STA_HT;
1637 if (!pmlmepriv->htpriv.ht_option && pstat->flags & WLAN_STA_HT){
1638 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1639 goto OnAssocReq23aFail;
1642 if (pstat->flags & WLAN_STA_HT &&
1643 (pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP ||
1644 pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) {
1645 DBG_8723A("HT: %pM tried to use TKIP with HT association\n",
1648 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
1649 /* goto OnAssocReq23aFail; */
1652 pstat->flags |= WLAN_STA_NONERP;
1653 for (i = 0; i < pstat->bssratelen; i++) {
1654 if ((pstat->bssrateset[i] & 0x7f) > 22) {
1655 pstat->flags &= ~WLAN_STA_NONERP;
1660 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1661 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
1663 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1665 if (status != WLAN_STATUS_SUCCESS)
1666 goto OnAssocReq23aFail;
1668 /* TODO: identify_proprietary_vendor_ie(); */
1669 /* Realtek proprietary IE */
1670 /* identify if this is Broadcom sta */
1671 /* identify if this is ralink sta */
1672 /* Customer proprietary IE */
1674 /* get a unique AID */
1675 if (pstat->aid > 0) {
1676 DBG_8723A(" old AID %d\n", pstat->aid);
1678 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
1679 if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
1682 if (pstat->aid > NUM_STA)
1683 pstat->aid = NUM_STA;
1684 if (pstat->aid > pstapriv->max_num_sta) {
1688 DBG_8723A(" no room for more AIDs\n");
1690 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1692 goto OnAssocReq23aFail;
1694 pstapriv->sta_aid[pstat->aid - 1] = pstat;
1695 DBG_8723A("allocate new AID = (%d)\n", pstat->aid);
1699 pstat->state &= ~WIFI_FW_ASSOC_STATE;
1700 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
1702 spin_lock_bh(&pstapriv->auth_list_lock);
1703 if (!list_empty(&pstat->auth_list)) {
1704 list_del_init(&pstat->auth_list);
1705 pstapriv->auth_list_cnt--;
1707 spin_unlock_bh(&pstapriv->auth_list_lock);
1709 spin_lock_bh(&pstapriv->asoc_list_lock);
1710 if (list_empty(&pstat->asoc_list)) {
1711 pstat->expire_to = pstapriv->expire_to;
1712 list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
1713 pstapriv->asoc_list_cnt++;
1715 spin_unlock_bh(&pstapriv->asoc_list_lock);
1717 /* now the station is qualified to join our BSS... */
1718 if (pstat->state & WIFI_FW_ASSOC_SUCCESS &&
1719 status == WLAN_STATUS_SUCCESS) {
1720 /* 1 bss_cap_update & sta_info_update23a */
1721 bss_cap_update_on_sta_join23a(padapter, pstat);
1722 sta_info_update23a(padapter, pstat);
1724 /* issue assoc rsp before notify station join event. */
1725 if (ieee80211_is_assoc_req(mgmt->frame_control))
1726 issue_assocrsp(padapter, status, pstat,
1727 IEEE80211_STYPE_ASSOC_RESP);
1729 issue_assocrsp(padapter, status, pstat,
1730 IEEE80211_STYPE_REASSOC_RESP);
1732 /* 2 - report to upper layer */
1733 DBG_8723A("indicate_sta_join_event to upper layer - hostapd\n");
1734 rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
1736 /* 3-(1) report sta add event */
1737 report_add_sta_event23a(padapter, pstat->hwaddr, pstat->aid);
1744 issue_deauth23a(padapter, mgmt->sa, status);
1750 if (ieee80211_is_assoc_req(mgmt->frame_control))
1751 issue_assocrsp(padapter, status, pstat,
1752 IEEE80211_STYPE_ASSOC_RESP);
1754 issue_assocrsp(padapter, status, pstat,
1755 IEEE80211_STYPE_REASSOC_RESP);
1757 #endif /* CONFIG_8723AU_AP_MODE */
1763 OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1765 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1766 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1767 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1768 struct sk_buff *skb = precv_frame->pkt;
1769 struct ieee80211_mgmt *pmgmt = (struct ieee80211_mgmt *) skb->data;
1771 unsigned short status;
1773 u8 *pframe = skb->data;
1774 int pkt_len = skb->len;
1777 DBG_8723A("%s\n", __func__);
1779 /* check A1 matches or not */
1780 if (!ether_addr_equal(myid(&padapter->eeprompriv), pmgmt->da))
1783 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
1786 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1789 del_timer_sync(&pmlmeext->link_timer);
1792 status = le16_to_cpu(pmgmt->u.assoc_resp.status_code);
1794 DBG_8723A("assoc reject, status code: %d\n", status);
1795 pmlmeinfo->state = MSR_NOLINK;
1797 goto report_assoc_result;
1800 /* get capabilities */
1801 pmlmeinfo->capability = le16_to_cpu(pmgmt->u.assoc_resp.capab_info);
1804 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
1807 res = pmlmeinfo->aid = le16_to_cpu(pmgmt->u.assoc_resp.aid) & 0x3fff;
1809 pie = pframe + offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
1811 offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
1813 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
1814 pmgmt->u.assoc_resp.variable, pielen);
1816 HT_caps_handler23a(padapter, p);
1818 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
1819 pmgmt->u.assoc_resp.variable, pielen);
1821 HT_info_handler23a(padapter, p);
1823 p = cfg80211_find_ie(WLAN_EID_ERP_INFO,
1824 pmgmt->u.assoc_resp.variable, pielen);
1826 ERP_IE_handler23a(padapter, p);
1828 pie = pframe + offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
1830 p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1831 WLAN_OUI_TYPE_MICROSOFT_WMM,
1832 pie, pframe + pkt_len - pie);
1837 /* if this IE is too short, try the next */
1840 /* if this IE is WMM params, we found what we wanted */
1846 WMM_param_handler23a(padapter, p);
1848 pmlmeinfo->state &= ~WIFI_FW_ASSOC_STATE;
1849 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
1851 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
1852 UpdateBrateTbl23a(padapter, pmlmeinfo->network.SupportedRates);
1854 report_assoc_result:
1855 pmlmepriv->assoc_rsp_len = 0;
1857 kfree(pmlmepriv->assoc_rsp);
1858 pmlmepriv->assoc_rsp = kmalloc(pkt_len, GFP_ATOMIC);
1859 if (pmlmepriv->assoc_rsp) {
1860 memcpy(pmlmepriv->assoc_rsp, pframe, pkt_len);
1861 pmlmepriv->assoc_rsp_len = pkt_len;
1864 kfree(pmlmepriv->assoc_rsp);
1866 report_join_res23a(padapter, res);
1872 OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1874 unsigned short reason;
1875 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1876 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1877 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1878 struct sk_buff *skb = precv_frame->pkt;
1879 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1881 if (!ether_addr_equal(mgmt->bssid,
1882 get_my_bssid23a(&pmlmeinfo->network)))
1885 reason = le16_to_cpu(mgmt->u.deauth.reason_code);
1887 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1889 #ifdef CONFIG_8723AU_AP_MODE
1890 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1891 struct sta_info *psta;
1892 struct sta_priv *pstapriv = &padapter->stapriv;
1894 DBG_8723A_LEVEL(_drv_always_, "ap recv deauth reason code(%d) "
1895 "sta:%pM\n", reason, mgmt->sa);
1897 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1901 spin_lock_bh(&pstapriv->asoc_list_lock);
1902 if (!list_empty(&psta->asoc_list)) {
1903 list_del_init(&psta->asoc_list);
1904 pstapriv->asoc_list_cnt--;
1905 updated = ap_free_sta23a(padapter, psta,
1908 spin_unlock_bh(&pstapriv->asoc_list_lock);
1910 associated_clients_update23a(padapter, updated);
1917 DBG_8723A_LEVEL(_drv_always_, "sta recv deauth reason code(%d) "
1918 "sta:%pM\n", reason, mgmt->bssid);
1920 receive_disconnect23a(padapter, mgmt->bssid, reason);
1922 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1928 OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1930 unsigned short reason;
1931 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1932 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1933 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1934 struct sk_buff *skb = precv_frame->pkt;
1935 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1937 if (!ether_addr_equal(mgmt->bssid,
1938 get_my_bssid23a(&pmlmeinfo->network)))
1941 reason = le16_to_cpu(mgmt->u.disassoc.reason_code);
1943 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1945 #ifdef CONFIG_8723AU_AP_MODE
1946 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1947 struct sta_info *psta;
1948 struct sta_priv *pstapriv = &padapter->stapriv;
1950 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason code(%d)"
1951 " sta:%pM\n", reason, mgmt->sa);
1953 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1957 spin_lock_bh(&pstapriv->asoc_list_lock);
1958 if (!list_empty(&psta->asoc_list)) {
1959 list_del_init(&psta->asoc_list);
1960 pstapriv->asoc_list_cnt--;
1961 updated = ap_free_sta23a(padapter, psta,
1964 spin_unlock_bh(&pstapriv->asoc_list_lock);
1966 associated_clients_update23a(padapter, updated);
1973 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason "
1974 "code(%d) sta:%pM\n", reason, mgmt->bssid);
1976 receive_disconnect23a(padapter, mgmt->bssid, reason);
1978 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1983 OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1985 DBG_8723A("%s\n", __func__);
1990 on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1996 OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2002 OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2007 static int OnAction23a_back23a(struct rtw_adapter *padapter,
2008 struct recv_frame *precv_frame)
2011 struct sta_info *psta = NULL;
2012 struct recv_reorder_ctrl *preorder_ctrl;
2013 unsigned char category, action;
2014 unsigned short tid, status, capab, params, reason_code = 0;
2015 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2016 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2017 struct sk_buff *skb = precv_frame->pkt;
2018 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
2019 struct sta_priv *pstapriv = &padapter->stapriv;
2021 /* check RA matches or not */
2022 if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
2025 DBG_8723A("%s\n", __func__);
2027 if ((pmlmeinfo->state&0x03) != MSR_AP)
2028 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
2032 psta = rtw_get_stainfo23a(pstapriv, addr);
2037 category = mgmt->u.action.category;
2038 if (category == WLAN_CATEGORY_BACK) { /* representing Block Ack */
2039 if (!pmlmeinfo->HT_enable)
2041 /* action_code is located in the same place for all
2042 action events, so pick any */
2043 action = mgmt->u.action.u.wme_action.action_code;
2044 DBG_8723A("%s, action =%d\n", __func__, action);
2046 case WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
2047 memcpy(&pmlmeinfo->ADDBA_req,
2048 &mgmt->u.action.u.addba_req.dialog_token,
2049 sizeof(struct ADDBA_request));
2050 process_addba_req23a(padapter,
2051 (u8 *)&pmlmeinfo->ADDBA_req, addr);
2052 if (pmlmeinfo->bAcceptAddbaReq == true)
2053 issue_action_BA23a(padapter, addr,
2054 WLAN_ACTION_ADDBA_RESP, 0);
2056 /* reject ADDBA Req */
2057 issue_action_BA23a(padapter, addr,
2058 WLAN_ACTION_ADDBA_RESP, 37);
2061 case WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
2062 status = get_unaligned_le16(
2063 &mgmt->u.action.u.addba_resp.status);
2064 capab = get_unaligned_le16(
2065 &mgmt->u.action.u.addba_resp.capab);
2066 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
2067 if (status == 0) { /* successful */
2068 DBG_8723A("agg_enable for TID =%d\n", tid);
2069 psta->htpriv.agg_enable_bitmap |= BIT(tid);
2070 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
2072 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
2075 case WLAN_ACTION_DELBA: /* DELBA */
2076 params = get_unaligned_le16(
2077 &mgmt->u.action.u.delba.params);
2080 if (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) {
2081 preorder_ctrl = &psta->recvreorder_ctrl[tid];
2082 preorder_ctrl->enable = false;
2083 preorder_ctrl->indicate_seq = 0xffff;
2085 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
2086 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
2088 reason_code = get_unaligned_le16(
2089 &mgmt->u.action.u.delba.reason_code);
2090 /* todo: how to notify the host while receiving
2100 static int on_action_public23a(struct rtw_adapter *padapter,
2101 struct recv_frame *precv_frame)
2103 struct sk_buff *skb = precv_frame->pkt;
2104 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2105 u8 *pframe = skb->data;
2108 /* check RA matches or not */
2109 if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
2112 channel = rtw_get_oper_ch23a(padapter);
2114 if (channel <= RTW_CH_MAX_2G_CHANNEL)
2115 freq = ieee80211_channel_to_frequency(channel,
2116 IEEE80211_BAND_2GHZ);
2118 freq = ieee80211_channel_to_frequency(channel,
2119 IEEE80211_BAND_5GHZ);
2121 if (cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, pframe,
2129 OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2135 OnAction23a_wmm(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2141 OnAction23a_p2p(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2147 OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2151 struct action_handler *ptable;
2152 struct sk_buff *skb = precv_frame->pkt;
2153 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
2155 category = mgmt->u.action.category;
2157 for (i = 0; i < ARRAY_SIZE(OnAction23a_tbl); i++) {
2158 ptable = &OnAction23a_tbl[i];
2160 if (category == ptable->num)
2161 ptable->func(padapter, precv_frame);
2167 static int DoReserved23a(struct rtw_adapter *padapter,
2168 struct recv_frame *precv_frame)
2173 struct xmit_frame *alloc_mgtxmitframe23a(struct xmit_priv *pxmitpriv)
2175 struct xmit_frame *pmgntframe;
2176 struct xmit_buf *pxmitbuf;
2178 pmgntframe = rtw_alloc_xmitframe23a_ext(pxmitpriv);
2181 DBG_8723A("%s(%s): alloc xmitframe fail\n", __func__,
2182 pxmitpriv->adapter->pnetdev->name);
2186 pxmitbuf = rtw_alloc_xmitbuf23a_ext(pxmitpriv);
2188 DBG_8723A("%s(%s): alloc xmitbuf fail\n", __func__,
2189 pxmitpriv->adapter->pnetdev->name);
2190 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
2195 pmgntframe->frame_tag = MGNT_FRAMETAG;
2196 pmgntframe->pxmitbuf = pxmitbuf;
2197 pmgntframe->buf_addr = pxmitbuf->pbuf;
2198 pxmitbuf->priv_data = pmgntframe;
2204 /****************************************************************************
2206 Following are some TX functions for WiFi MLME
2208 *****************************************************************************/
2210 void update_mgnt_tx_rate23a(struct rtw_adapter *padapter, u8 rate)
2212 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2214 pmlmeext->tx_rate = rate;
2215 DBG_8723A("%s(): rate = %x\n", __func__, rate);
2218 void update_mgntframe_attrib23a(struct rtw_adapter *padapter,
2219 struct pkt_attrib *pattrib)
2221 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2223 memset((u8 *)pattrib, 0, sizeof(struct pkt_attrib));
2225 pattrib->hdrlen = 24;
2226 pattrib->nr_frags = 1;
2227 pattrib->priority = 7;
2228 pattrib->mac_id = 0;
2229 pattrib->qsel = 0x12;
2231 pattrib->pktlen = 0;
2233 if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
2234 pattrib->raid = 6;/* b mode */
2236 pattrib->raid = 5;/* a/g mode */
2238 pattrib->encrypt = 0;
2239 pattrib->bswenc = false;
2241 pattrib->qos_en = false;
2242 pattrib->ht_en = false;
2243 pattrib->bwmode = HT_CHANNEL_WIDTH_20;
2244 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2245 pattrib->sgi = false;
2247 pattrib->seqnum = pmlmeext->mgnt_seq;
2249 pattrib->retry_ctrl = true;
2252 void dump_mgntframe23a(struct rtw_adapter *padapter,
2253 struct xmit_frame *pmgntframe)
2255 if (padapter->bSurpriseRemoved == true ||
2256 padapter->bDriverStopped == true)
2259 rtl8723au_mgnt_xmit(padapter, pmgntframe);
2262 int dump_mgntframe23a_and_wait(struct rtw_adapter *padapter,
2263 struct xmit_frame *pmgntframe, int timeout_ms)
2267 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2268 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
2269 struct submit_ctx sctx;
2271 if (padapter->bSurpriseRemoved == true ||
2272 padapter->bDriverStopped == true)
2275 rtw_sctx_init23a(&sctx, timeout_ms);
2276 pxmitbuf->sctx = &sctx;
2278 ret = rtl8723au_mgnt_xmit(padapter, pmgntframe);
2280 if (ret == _SUCCESS)
2281 ret = rtw_sctx_wait23a(&sctx);
2283 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
2284 pxmitbuf->sctx = NULL;
2285 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
2290 int dump_mgntframe23a_and_wait_ack23a(struct rtw_adapter *padapter,
2291 struct xmit_frame *pmgntframe)
2294 u32 timeout_ms = 500;/* 500ms */
2295 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2297 if (padapter->bSurpriseRemoved == true ||
2298 padapter->bDriverStopped == true)
2301 mutex_lock(&pxmitpriv->ack_tx_mutex);
2302 pxmitpriv->ack_tx = true;
2304 pmgntframe->ack_report = 1;
2305 if (rtl8723au_mgnt_xmit(padapter, pmgntframe) == _SUCCESS)
2306 ret = rtw_ack_tx_wait23a(pxmitpriv, timeout_ms);
2308 pxmitpriv->ack_tx = false;
2309 mutex_unlock(&pxmitpriv->ack_tx_mutex);
2314 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
2322 ssid_ie = rtw_get_ie23a(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
2324 /* DBG_8723A("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n",
2325 __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
2327 if (ssid_ie && ssid_len_ori > 0) {
2328 switch (hidden_ssid_mode) {
2330 next_ie = ssid_ie + 2 + ssid_len_ori;
2331 remain_len = ies_len -(next_ie-ies);
2334 memcpy(ssid_ie+2, next_ie, remain_len);
2335 len_diff -= ssid_len_ori;
2339 memset(&ssid_ie[2], 0, ssid_len_ori);
2349 void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
2351 struct xmit_frame *pmgntframe;
2352 struct pkt_attrib *pattrib;
2353 unsigned char *pframe;
2354 struct ieee80211_mgmt *mgmt;
2355 unsigned int rate_len;
2356 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2357 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2358 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2359 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2360 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2361 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2366 /* DBG_8723A("%s\n", __func__); */
2368 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2370 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2373 #ifdef CONFIG_8723AU_AP_MODE
2374 spin_lock_bh(&pmlmepriv->bcn_update_lock);
2377 /* update attribute */
2378 pattrib = &pmgntframe->attrib;
2379 update_mgntframe_attrib23a(padapter, pattrib);
2380 pattrib->qsel = 0x10;
2382 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2384 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2385 mgmt = (struct ieee80211_mgmt *)pframe;
2387 mgmt->frame_control =
2388 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
2391 ether_addr_copy(mgmt->da, bc_addr);
2392 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
2393 ether_addr_copy(mgmt->bssid, get_my_bssid23a(cur_network));
2395 /* timestamp will be inserted by hardware */
2397 put_unaligned_le16(cur_network->beacon_interval,
2398 &mgmt->u.beacon.beacon_int);
2400 put_unaligned_le16(cur_network->capability,
2401 &mgmt->u.beacon.capab_info);
2403 pframe = mgmt->u.beacon.variable;
2404 pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
2406 if ((pmlmeinfo->state & 0x03) == MSR_AP) {
2409 /* DBG_8723A("ie len =%d\n", cur_network->IELength); */
2410 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2411 len_diff = update_hidden_ssid(pframe, cur_network->IELength,
2412 pmlmeinfo->hidden_ssid_mode);
2413 pframe += (cur_network->IELength+len_diff);
2414 pattrib->pktlen += (cur_network->IELength+len_diff);
2416 iebuf = mgmt->u.beacon.variable;
2417 buflen = pattrib->pktlen -
2418 offsetof(struct ieee80211_mgmt, u.beacon.variable);
2419 wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
2420 WLAN_OUI_TYPE_MICROSOFT_WPS,
2423 if (wps_ie && wps_ie[1] > 0) {
2424 rtw_get_wps_attr_content23a(wps_ie, wps_ie[1],
2425 WPS_ATTR_SELECTED_REGISTRAR,
2429 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
2431 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
2437 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2438 cur_network->Ssid.ssid_len,
2439 cur_network->Ssid.ssid, &pattrib->pktlen);
2441 /* supported rates... */
2442 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2443 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2444 ((rate_len > 8)? 8: rate_len),
2445 cur_network->SupportedRates, &pattrib->pktlen);
2447 /* DS parameter set */
2448 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)
2449 &cur_network->DSConfig, &pattrib->pktlen);
2451 /* if ((pmlmeinfo->state&0x03) == MSR_ADHOC) */
2455 /* IBSS Parameter Set... */
2456 /* ATIMWindow = cur->ATIMWindow; */
2458 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2459 (unsigned char *)&ATIMWindow,
2463 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2464 &erpinfo, &pattrib->pktlen);
2467 /* EXTERNDED SUPPORTED RATE */
2469 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2471 cur_network->SupportedRates + 8,
2474 /* todo:HT for adhoc */
2478 #ifdef CONFIG_8723AU_AP_MODE
2479 pmlmepriv->update_bcn = false;
2481 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
2484 if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
2485 DBG_8723A("beacon frame too large\n");
2489 pattrib->last_txcmdsz = pattrib->pktlen;
2491 /* DBG_8723A("issue bcn_sz =%d\n", pattrib->last_txcmdsz); */
2493 dump_mgntframe23a_and_wait(padapter, pmgntframe, timeout_ms);
2495 dump_mgntframe23a(padapter, pmgntframe);
2498 static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da)
2500 struct xmit_frame *pmgntframe;
2501 struct pkt_attrib *pattrib;
2502 unsigned char *pframe;
2503 struct ieee80211_mgmt *mgmt;
2504 unsigned char *mac, *bssid;
2505 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2506 #ifdef CONFIG_8723AU_AP_MODE
2510 int ssid_ielen_diff;
2513 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2514 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2515 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2516 unsigned int rate_len;
2518 /* DBG_8723A("%s\n", __func__); */
2520 if (cur_network->IELength > MAX_IE_SZ)
2523 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2525 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2529 /* update attribute */
2530 pattrib = &pmgntframe->attrib;
2531 update_mgntframe_attrib23a(padapter, pattrib);
2533 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2535 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
2536 mgmt = (struct ieee80211_mgmt *)pframe;
2538 mac = myid(&padapter->eeprompriv);
2539 bssid = cur_network->MacAddress;
2541 mgmt->frame_control =
2542 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
2544 ether_addr_copy(mgmt->da, da);
2545 ether_addr_copy(mgmt->sa, mac);
2546 ether_addr_copy(mgmt->bssid, bssid);
2548 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
2549 pmlmeext->mgnt_seq++;
2551 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2553 /* timestamp will be inserted by hardware */
2554 put_unaligned_le16(cur_network->beacon_interval,
2555 &mgmt->u.probe_resp.beacon_int);
2557 put_unaligned_le16(cur_network->capability,
2558 &mgmt->u.probe_resp.capab_info);
2560 pframe = mgmt->u.probe_resp.variable;
2562 offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
2564 /* below for ad-hoc mode */
2566 #ifdef CONFIG_8723AU_AP_MODE
2567 if ((pmlmeinfo->state & 0x03) == MSR_AP) {
2568 pwps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
2569 WLAN_OUI_TYPE_MICROSOFT_WPS,
2571 cur_network->IELength);
2573 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2574 pframe += cur_network->IELength;
2575 pattrib->pktlen += cur_network->IELength;
2577 /* retrieve SSID IE from cur_network->Ssid */
2579 ssid_ie = rtw_get_ie23a(mgmt->u.probe_resp.variable,
2580 WLAN_EID_SSID, &ssid_ielen,
2581 pframe - mgmt->u.probe_resp.variable);
2583 ssid_ielen_diff = cur_network->Ssid.ssid_len - ssid_ielen;
2585 if (ssid_ie && cur_network->Ssid.ssid_len) {
2586 uint remainder_ielen;
2589 remainder_ie = ssid_ie + 2;
2591 remainder_ielen = pframe - remainder_ie;
2593 DBG_8723A_LEVEL(_drv_warning_, "%s(%s): "
2594 "remainder_ielen > MAX_IE_SZ\n",
2595 __func__, padapter->pnetdev->name);
2596 if (remainder_ielen > MAX_IE_SZ)
2597 remainder_ielen = MAX_IE_SZ;
2599 memcpy(buf, remainder_ie, remainder_ielen);
2600 memcpy(remainder_ie + ssid_ielen_diff, buf,
2602 *(ssid_ie + 1) = cur_network->Ssid.ssid_len;
2603 memcpy(ssid_ie + 2, cur_network->Ssid.ssid,
2604 cur_network->Ssid.ssid_len);
2606 pframe += ssid_ielen_diff;
2607 pattrib->pktlen += ssid_ielen_diff;
2613 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2614 cur_network->Ssid.ssid_len,
2615 cur_network->Ssid.ssid,
2618 /* supported rates... */
2619 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2620 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2621 ((rate_len > 8)? 8: rate_len),
2622 cur_network->SupportedRates,
2625 /* DS parameter set */
2626 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1,
2627 (unsigned char *)&cur_network->DSConfig,
2630 if ((pmlmeinfo->state & 0x03) == MSR_ADHOC) {
2633 /* IBSS Parameter Set... */
2634 /* ATIMWindow = cur->ATIMWindow; */
2636 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2637 (unsigned char *)&ATIMWindow,
2641 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2642 &erpinfo, &pattrib->pktlen);
2645 /* EXTERNDED SUPPORTED RATE */
2647 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2649 cur_network->SupportedRates + 8,
2652 /* todo:HT for adhoc */
2655 pattrib->last_txcmdsz = pattrib->pktlen;
2657 dump_mgntframe23a(padapter, pmgntframe);
2660 static int _issue_probereq(struct rtw_adapter *padapter,
2661 struct cfg80211_ssid *pssid, u8 *da, int wait_ack)
2664 struct xmit_frame *pmgntframe;
2665 struct pkt_attrib *pattrib;
2666 unsigned char *pframe;
2667 struct ieee80211_hdr *pwlanhdr;
2669 unsigned char bssrate[NumRates];
2670 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2671 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2672 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2673 int bssrate_len = 0;
2674 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2676 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2679 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2683 /* update attribute */
2684 pattrib = &pmgntframe->attrib;
2685 update_mgntframe_attrib23a(padapter, pattrib);
2687 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2689 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2690 pwlanhdr = (struct ieee80211_hdr *)pframe;
2692 mac = myid(&padapter->eeprompriv);
2694 pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2695 IEEE80211_STYPE_PROBE_REQ);
2698 /* unicast probe request frame */
2699 ether_addr_copy(pwlanhdr->addr1, da);
2700 ether_addr_copy(pwlanhdr->addr3, da);
2702 /* broadcast probe request frame */
2703 ether_addr_copy(pwlanhdr->addr1, bc_addr);
2704 ether_addr_copy(pwlanhdr->addr3, bc_addr);
2707 ether_addr_copy(pwlanhdr->addr2, mac);
2709 pwlanhdr->seq_ctrl =
2710 cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
2712 pmlmeext->mgnt_seq++;
2714 pframe += sizeof (struct ieee80211_hdr_3addr);
2715 pattrib->pktlen = sizeof (struct ieee80211_hdr_3addr);
2718 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, pssid->ssid_len,
2719 pssid->ssid, &pattrib->pktlen);
2721 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, 0, NULL,
2724 get_rate_set23a(padapter, bssrate, &bssrate_len);
2726 if (bssrate_len > 8) {
2727 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
2728 bssrate, &pattrib->pktlen);
2729 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2730 (bssrate_len - 8), (bssrate + 8),
2733 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2734 bssrate_len, bssrate, &pattrib->pktlen);
2737 /* add wps_ie for wps2.0 */
2738 if (pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie) {
2739 memcpy(pframe, pmlmepriv->wps_probe_req_ie,
2740 pmlmepriv->wps_probe_req_ie_len);
2741 pframe += pmlmepriv->wps_probe_req_ie_len;
2742 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
2745 pattrib->last_txcmdsz = pattrib->pktlen;
2747 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2748 "issuing probe_req, tx_len =%d\n", pattrib->last_txcmdsz);
2751 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
2753 dump_mgntframe23a(padapter, pmgntframe);
2761 static inline void issue_probereq(struct rtw_adapter *padapter,
2762 struct cfg80211_ssid *pssid, u8 *da)
2764 _issue_probereq(padapter, pssid, da, false);
2767 static int issue_probereq_ex(struct rtw_adapter *padapter,
2768 struct cfg80211_ssid *pssid, u8 *da,
2769 int try_cnt, int wait_ms)
2773 unsigned long start = jiffies;
2776 ret = _issue_probereq(padapter, pssid, da,
2777 wait_ms > 0 ? true : false);
2781 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
2784 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
2787 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
2794 if (try_cnt && wait_ms) {
2796 DBG_8723A("%s(%s): to %pM, ch:%u%s, %d/%d in %u ms\n",
2797 __func__, padapter->pnetdev->name,
2798 da, rtw_get_oper_ch23a(padapter),
2799 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
2800 jiffies_to_msecs(jiffies - start));
2802 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
2803 __func__, padapter->pnetdev->name,
2804 rtw_get_oper_ch23a(padapter),
2805 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
2806 jiffies_to_msecs(jiffies - start));
2812 /* if psta == NULL, indiate we are station(client) now... */
2813 static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
2814 unsigned short status)
2816 struct xmit_frame *pmgntframe;
2817 struct pkt_attrib *pattrib;
2818 unsigned char *pframe;
2819 struct ieee80211_mgmt *mgmt;
2822 int use_shared_key = 0;
2823 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2824 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2825 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2827 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2831 /* update attribute */
2832 pattrib = &pmgntframe->attrib;
2833 update_mgntframe_attrib23a(padapter, pattrib);
2835 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2837 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2838 mgmt = (struct ieee80211_mgmt *)pframe;
2840 mgmt->frame_control =
2841 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2842 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
2843 pmlmeext->mgnt_seq++;
2845 pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.auth.variable);
2847 if (psta) { /* for AP mode */
2848 #ifdef CONFIG_8723AU_AP_MODE
2849 unsigned short val16;
2851 ether_addr_copy(mgmt->da, psta->hwaddr);
2852 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
2853 ether_addr_copy(mgmt->bssid, myid(&padapter->eeprompriv));
2855 /* setting auth algo number */
2856 val16 = (u16)psta->authalg;
2858 if (status != WLAN_STATUS_SUCCESS)
2864 mgmt->u.auth.auth_alg = cpu_to_le16(val16);
2866 /* setting auth seq number */
2867 mgmt->u.auth.auth_transaction =
2868 cpu_to_le16((u16)psta->auth_seq);
2870 /* setting status code... */
2871 mgmt->u.auth.status_code = cpu_to_le16(status);
2873 pframe = mgmt->u.auth.variable;
2874 /* added challenging text... */
2875 if ((psta->auth_seq == 2) &&
2876 (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
2877 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
2878 psta->chg_txt, &pattrib->pktlen);
2881 struct ieee80211_mgmt *iv_mgmt;
2883 ether_addr_copy(mgmt->da, get_my_bssid23a(&pmlmeinfo->network));
2884 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
2885 ether_addr_copy(mgmt->bssid,
2886 get_my_bssid23a(&pmlmeinfo->network));
2888 /* setting auth algo number */
2889 /* 0:OPEN System, 1:Shared key */
2890 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
2892 auth_algo = WLAN_AUTH_SHARED_KEY;
2894 auth_algo = WLAN_AUTH_OPEN;
2896 /* DBG_8723A("%s auth_algo = %s auth_seq =%d\n", __func__,
2897 (pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED",
2898 pmlmeinfo->auth_seq); */
2900 /* setting IV for auth seq #3 */
2901 if ((pmlmeinfo->auth_seq == 3) &&
2902 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
2903 (use_shared_key == 1)) {
2904 u32 *piv = (u32 *)&mgmt->u.auth;
2906 iv_mgmt = (struct ieee80211_mgmt *)(pframe + 4);
2907 /* DBG_8723A("==> iv(%d), key_index(%d)\n",
2908 pmlmeinfo->iv, pmlmeinfo->key_index); */
2909 val32 = (pmlmeinfo->iv & 0x3fffffff) |
2910 (pmlmeinfo->key_index << 30);
2912 put_unaligned_le32(val32, piv);
2914 pattrib->pktlen += 4;
2916 pattrib->iv_len = IEEE80211_WEP_IV_LEN;
2920 iv_mgmt->u.auth.auth_alg = cpu_to_le16(auth_algo);
2922 /* setting auth seq number */
2923 iv_mgmt->u.auth.auth_transaction =
2924 cpu_to_le16(pmlmeinfo->auth_seq);
2926 /* setting status code... */
2927 iv_mgmt->u.auth.status_code = cpu_to_le16(status);
2929 pframe = iv_mgmt->u.auth.variable;
2931 /* then checking to see if sending challenging text... */
2932 if ((pmlmeinfo->auth_seq == 3) &&
2933 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
2934 (use_shared_key == 1)) {
2935 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
2939 mgmt->frame_control |=
2940 cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2942 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2944 pattrib->encrypt = WLAN_CIPHER_SUITE_WEP40;
2946 pattrib->icv_len = IEEE80211_WEP_ICV_LEN;
2948 pattrib->pktlen += pattrib->icv_len;
2952 pattrib->last_txcmdsz = pattrib->pktlen;
2954 rtw_wep_encrypt23a(padapter, pmgntframe);
2955 DBG_8723A("%s\n", __func__);
2956 dump_mgntframe23a(padapter, pmgntframe);
2959 #ifdef CONFIG_8723AU_AP_MODE
2960 static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
2961 struct sta_info *pstat, u16 pkt_type)
2963 struct xmit_frame *pmgntframe;
2964 struct ieee80211_mgmt *mgmt;
2965 struct pkt_attrib *pattrib;
2966 unsigned char *pframe;
2967 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2968 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2969 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2970 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2971 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
2973 u8 *ie = pnetwork->IEs;
2975 DBG_8723A("%s\n", __func__);
2977 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2981 /* update attribute */
2982 pattrib = &pmgntframe->attrib;
2983 update_mgntframe_attrib23a(padapter, pattrib);
2985 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2987 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2988 mgmt = (struct ieee80211_mgmt *)pframe;
2990 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | pkt_type);
2992 ether_addr_copy(mgmt->da, pstat->hwaddr);
2993 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
2994 ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
2996 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
2998 pmlmeext->mgnt_seq++;
3000 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3002 offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
3004 mgmt->u.assoc_resp.capab_info = cpu_to_le16(pnetwork->capability);
3005 mgmt->u.assoc_resp.status_code = cpu_to_le16(status);
3006 mgmt->u.assoc_resp.aid = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
3008 pframe = mgmt->u.assoc_resp.variable;
3010 if (pstat->bssratelen <= 8) {
3011 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3012 pstat->bssratelen, pstat->bssrateset,
3015 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3016 pstat->bssrateset, &pattrib->pktlen);
3017 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3018 pstat->bssratelen - 8,
3019 pstat->bssrateset + 8, &pattrib->pktlen);
3022 if (pstat->flags & WLAN_STA_HT && pmlmepriv->htpriv.ht_option) {
3023 /* FILL HT CAP INFO IE */
3024 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
3025 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ie,
3026 pnetwork->IELength);
3028 memcpy(pframe, p, p[1] + 2);
3029 pframe += (p[1] + 2);
3030 pattrib->pktlen += (p[1] + 2);
3033 /* FILL HT ADD INFO IE */
3034 /* p = hostapd_eid_ht_operation(hapd, p); */
3035 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, ie,
3036 pnetwork->IELength);
3037 if (p && p[1] > 0) {
3038 memcpy(pframe, p, p[1] + 2);
3039 pframe += (p[1] + 2);
3040 pattrib->pktlen += (p[1] + 2);
3045 if (pstat->flags & WLAN_STA_WME && pmlmepriv->qos_option) {
3046 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02,
3050 for (p = ie; ; p += (ie_len + 2)) {
3051 p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p,
3052 pnetwork->IELength - (ie_len + 2));
3057 if (p && !memcmp(p + 2, WMM_PARA_IE, 6)) {
3058 memcpy(pframe, p, ie_len + 2);
3059 pframe += (ie_len + 2);
3060 pattrib->pktlen += (ie_len + 2);
3065 if (!p || ie_len == 0)
3070 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) {
3071 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3072 REALTEK_96B_IE, &pattrib->pktlen);
3075 pattrib->last_txcmdsz = pattrib->pktlen;
3077 dump_mgntframe23a(padapter, pmgntframe);
3081 static void issue_assocreq(struct rtw_adapter *padapter)
3084 struct xmit_frame *pmgntframe;
3085 struct pkt_attrib *pattrib;
3086 unsigned char *pframe;
3088 struct ieee80211_mgmt *mgmt;
3089 unsigned int i, j, index = 0;
3090 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
3091 struct registry_priv *pregpriv = &padapter->registrypriv;
3092 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3093 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3094 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3095 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3096 int bssrate_len = 0, sta_bssrate_len = 0, pie_len;
3099 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3103 /* update attribute */
3104 pattrib = &pmgntframe->attrib;
3105 update_mgntframe_attrib23a(padapter, pattrib);
3107 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3109 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
3110 mgmt = (struct ieee80211_mgmt *)pframe;
3112 mgmt->frame_control =
3113 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ);
3115 ether_addr_copy(mgmt->da, get_my_bssid23a(&pmlmeinfo->network));
3116 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
3117 ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
3119 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3120 pmlmeext->mgnt_seq++;
3123 put_unaligned_le16(pmlmeinfo->network.capability,
3124 &mgmt->u.assoc_req.capab_info);
3125 /* todo: listen interval for power saving */
3126 put_unaligned_le16(3, &mgmt->u.assoc_req.listen_interval);
3128 pframe = mgmt->u.assoc_req.variable;
3129 pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
3132 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
3133 pmlmeinfo->network.Ssid.ssid_len,
3134 pmlmeinfo->network.Ssid.ssid, &pattrib->pktlen);
3136 /* supported rate & extended supported rate */
3138 get_rate_set23a(padapter, sta_bssrate, &sta_bssrate_len);
3139 /* DBG_8723A("sta_bssrate_len =%d\n", sta_bssrate_len); */
3141 /* for JAPAN, channel 14 can only uses B Mode(CCK) */
3142 if (pmlmeext->cur_channel == 14)
3143 sta_bssrate_len = 4;
3145 /* for (i = 0; i < sta_bssrate_len; i++) { */
3146 /* DBG_8723A("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
3149 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3150 if (pmlmeinfo->network.SupportedRates[i] == 0)
3152 DBG_8723A("network.SupportedRates[%d]=%02X\n", i,
3153 pmlmeinfo->network.SupportedRates[i]);
3156 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3157 if (pmlmeinfo->network.SupportedRates[i] == 0)
3160 /* Check if the AP's supported rates are also
3161 supported by STA. */
3162 for (j = 0; j < sta_bssrate_len; j++) {
3163 /* Avoid the proprietary data rate (22Mbps) of
3164 Handlink WSG-4000 AP */
3165 if ((pmlmeinfo->network.SupportedRates[i] |
3166 IEEE80211_BASIC_RATE_MASK) ==
3167 (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
3168 /* DBG_8723A("match i = %d, j =%d\n", i, j); */
3173 if (j == sta_bssrate_len) {
3174 /* the rate is not supported by STA */
3175 DBG_8723A("%s(): the rate[%d]=%02X is not supported by "
3176 "STA!\n", __func__, i,
3177 pmlmeinfo->network.SupportedRates[i]);
3179 /* the rate is supported by STA */
3180 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
3184 bssrate_len = index;
3185 DBG_8723A("bssrate_len = %d\n", bssrate_len);
3187 if (bssrate_len == 0) {
3188 rtw_free_xmitbuf23a(pxmitpriv, pmgntframe->pxmitbuf);
3189 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
3190 goto exit; /* don't connect to AP if no joint supported rate */
3193 if (bssrate_len > 8) {
3194 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3195 bssrate, &pattrib->pktlen);
3196 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3197 (bssrate_len - 8), (bssrate + 8),
3200 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3201 bssrate_len, bssrate, &pattrib->pktlen);
3205 pie = pmlmeinfo->network.IEs;
3206 pie_len = pmlmeinfo->network.IELength;
3208 p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
3210 pframe = rtw_set_ie23a(pframe, WLAN_EID_RSN, p[1], p + 2,
3214 if (padapter->mlmepriv.htpriv.ht_option) {
3215 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, pie_len);
3217 if (p && !is_ap_in_tkip23a(padapter)) {
3218 struct ieee80211_ht_cap *cap = &pmlmeinfo->ht_cap;
3220 memcpy(cap, p + 2, sizeof(struct ieee80211_ht_cap));
3222 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
3223 if (pregpriv->cbw40_enable == 0) {
3224 cap->cap_info &= ~cpu_to_le16(
3225 IEEE80211_HT_CAP_SGI_40 |
3226 IEEE80211_HT_CAP_SUP_WIDTH_20_40);
3228 cap->cap_info |= cpu_to_le16(
3229 IEEE80211_HT_CAP_SUP_WIDTH_20_40);
3232 /* todo: disable SM power save mode */
3233 cap->cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SM_PS);
3235 rf_type = rtl8723a_get_rf_type(padapter);
3236 /* switch (pregpriv->rf_config) */
3239 /* RX STBC One spatial stream */
3240 if (pregpriv->rx_stbc)
3241 cap->cap_info |= cpu_to_le16(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3243 memcpy(&cap->mcs, MCS_rate_1R23A, 16);
3249 /* enable for 2.4/5 GHz */
3250 if (pregpriv->rx_stbc == 0x3 ||
3251 (pmlmeext->cur_wireless_mode &
3253 /* enable for 2.4GHz */
3254 pregpriv->rx_stbc == 0x1) ||
3255 (pmlmeext->cur_wireless_mode &
3257 pregpriv->rx_stbc == 0x2) ||
3258 /* enable for 5GHz */
3259 pregpriv->wifi_spec == 1) {
3260 DBG_8723A("declare supporting RX "
3262 /* RX STBC two spatial stream */
3263 cap->cap_info |= cpu_to_le16(2 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3265 memcpy(&cap->mcs, MCS_rate_2R23A, 16);
3269 if (rtl8723a_BT_coexist(padapter) &&
3270 rtl8723a_BT_using_antenna_1(padapter)) {
3272 cap->ampdu_params_info &=
3273 ~IEEE80211_HT_AMPDU_PARM_FACTOR;
3274 /* cap->ampdu_params_info |= MAX_AMPDU_FACTOR_8K */
3277 pframe = rtw_set_ie23a(pframe, WLAN_EID_HT_CAPABILITY,
3278 p[1], (u8 *)&pmlmeinfo->ht_cap,
3283 /* vendor specific IE, such as WPA, WMM, WPS */
3284 for (i = 0; i < pmlmeinfo->network.IELength;) {
3285 p = pmlmeinfo->network.IEs + i;
3288 case WLAN_EID_VENDOR_SPECIFIC:
3289 if (!memcmp(p + 2, RTW_WPA_OUI23A_TYPE, 4) ||
3290 !memcmp(p + 2, WMM_OUI23A, 4) ||
3291 !memcmp(p + 2, WPS_OUI23A, 4)) {
3294 if (!padapter->registrypriv.wifi_spec) {
3295 /* Commented by Kurt 20110629 */
3296 /* In some older APs, WPS handshake */
3297 /* would be fail if we append vender
3298 extensions informations to AP */
3299 if (!memcmp(p + 2, WPS_OUI23A, 4))
3302 pframe = rtw_set_ie23a(pframe,
3303 WLAN_EID_VENDOR_SPECIFIC,
3316 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
3317 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3318 REALTEK_96B_IE, &pattrib->pktlen);
3320 pattrib->last_txcmdsz = pattrib->pktlen;
3321 dump_mgntframe23a(padapter, pmgntframe);
3326 pmlmepriv->assoc_req_len = 0;
3327 if (ret == _SUCCESS) {
3328 kfree(pmlmepriv->assoc_req);
3329 pmlmepriv->assoc_req = kmalloc(pattrib->pktlen, GFP_ATOMIC);
3330 if (pmlmepriv->assoc_req) {
3331 memcpy(pmlmepriv->assoc_req, mgmt, pattrib->pktlen);
3332 pmlmepriv->assoc_req_len = pattrib->pktlen;
3335 kfree(pmlmepriv->assoc_req);
3338 /* when wait_ack is true, this function should be called at process context */
3339 static int _issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3340 unsigned int power_mode, int wait_ack)
3343 struct xmit_frame *pmgntframe;
3344 struct pkt_attrib *pattrib;
3345 unsigned char *pframe;
3346 struct ieee80211_hdr *pwlanhdr;
3347 struct xmit_priv *pxmitpriv;
3348 struct mlme_ext_priv *pmlmeext;
3349 struct mlme_ext_info *pmlmeinfo;
3351 /* DBG_8723A("%s:%d\n", __func__, power_mode); */
3356 pxmitpriv = &padapter->xmitpriv;
3357 pmlmeext = &padapter->mlmeextpriv;
3358 pmlmeinfo = &pmlmeext->mlmext_info;
3360 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3364 /* update attribute */
3365 pattrib = &pmgntframe->attrib;
3366 update_mgntframe_attrib23a(padapter, pattrib);
3367 pattrib->retry_ctrl = false;
3369 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3371 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3372 pwlanhdr = (struct ieee80211_hdr *)pframe;
3374 pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
3375 IEEE80211_STYPE_NULLFUNC);
3377 if ((pmlmeinfo->state&0x03) == MSR_AP)
3378 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
3379 else if ((pmlmeinfo->state&0x03) == MSR_INFRA)
3380 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_TODS);
3383 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
3385 ether_addr_copy(pwlanhdr->addr1, da);
3386 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3387 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3389 pwlanhdr->seq_ctrl =
3390 cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3391 pmlmeext->mgnt_seq++;
3393 pframe += sizeof(struct ieee80211_hdr_3addr);
3394 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3396 pattrib->last_txcmdsz = pattrib->pktlen;
3399 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3401 dump_mgntframe23a(padapter, pmgntframe);
3409 /* when wait_ms >0 , this function should be called at process context */
3410 /* da == NULL for station mode */
3411 int issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3412 unsigned int power_mode, int try_cnt, int wait_ms)
3416 unsigned long start = jiffies;
3417 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3418 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3420 /* da == NULL, assume it's null data for sta to ap*/
3422 da = get_my_bssid23a(&pmlmeinfo->network);
3425 ret = _issue_nulldata23a(padapter, da, power_mode,
3426 wait_ms > 0 ? true : false);
3430 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3433 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3436 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3443 if (try_cnt && wait_ms) {
3445 DBG_8723A("%s(%s): to %pM, ch:%u%s, %d/%d in %u ms\n",
3446 __func__, padapter->pnetdev->name,
3447 da, rtw_get_oper_ch23a(padapter),
3448 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
3449 jiffies_to_msecs(jiffies - start));
3451 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3452 __func__, padapter->pnetdev->name,
3453 rtw_get_oper_ch23a(padapter),
3454 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
3455 jiffies_to_msecs(jiffies - start));
3461 /* when wait_ack is true, this function should be called at process context */
3462 static int _issue_qos_nulldata23a(struct rtw_adapter *padapter,
3463 unsigned char *da, u16 tid, int wait_ack)
3466 struct xmit_frame *pmgntframe;
3467 struct pkt_attrib *pattrib;
3468 unsigned char *pframe;
3469 struct ieee80211_qos_hdr *pwlanhdr;
3470 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3471 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3472 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3474 DBG_8723A("%s\n", __func__);
3476 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3480 /* update attribute */
3481 pattrib = &pmgntframe->attrib;
3482 update_mgntframe_attrib23a(padapter, pattrib);
3484 pattrib->hdrlen += 2;
3485 pattrib->qos_en = true;
3487 pattrib->ack_policy = 0;
3490 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3492 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3493 pwlanhdr = (struct ieee80211_qos_hdr *)pframe;
3495 pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
3496 IEEE80211_STYPE_QOS_NULLFUNC);
3498 if ((pmlmeinfo->state&0x03) == MSR_AP)
3499 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
3500 else if ((pmlmeinfo->state&0x03) == MSR_INFRA)
3501 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_TODS);
3504 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
3506 pwlanhdr->qos_ctrl = cpu_to_le16(tid & IEEE80211_QOS_CTL_TID_MASK);
3507 pwlanhdr->qos_ctrl |= cpu_to_le16((pattrib->ack_policy << 5) &
3508 IEEE80211_QOS_CTL_ACK_POLICY_MASK);
3510 pwlanhdr->qos_ctrl |= cpu_to_le16(IEEE80211_QOS_CTL_EOSP);
3512 ether_addr_copy(pwlanhdr->addr1, da);
3513 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3514 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3516 pwlanhdr->seq_ctrl =
3517 cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3518 pmlmeext->mgnt_seq++;
3520 pframe += sizeof(struct ieee80211_qos_hdr);
3521 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
3523 pattrib->last_txcmdsz = pattrib->pktlen;
3526 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3528 dump_mgntframe23a(padapter, pmgntframe);
3536 /* when wait_ms >0 , this function should be called at process context */
3537 /* da == NULL for station mode */
3538 int issue_qos_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3539 u16 tid, int try_cnt, int wait_ms)
3543 unsigned long start = jiffies;
3544 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3545 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3547 /* da == NULL, assume it's null data for sta to ap*/
3549 da = get_my_bssid23a(&pmlmeinfo->network);
3552 ret = _issue_qos_nulldata23a(padapter, da, tid,
3553 wait_ms > 0 ? true : false);
3557 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3560 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3562 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3569 if (try_cnt && wait_ms) {
3571 DBG_8723A("%s(%s): to %pM, ch:%u%s, %d/%d in %u ms\n",
3572 __func__, padapter->pnetdev->name,
3573 da, rtw_get_oper_ch23a(padapter),
3574 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
3575 jiffies_to_msecs(jiffies - start));
3577 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3578 __func__, padapter->pnetdev->name,
3579 rtw_get_oper_ch23a(padapter),
3580 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
3581 jiffies_to_msecs(jiffies - start));
3587 static int _issue_deauth(struct rtw_adapter *padapter, unsigned char *da,
3588 unsigned short reason, u8 wait_ack)
3590 struct xmit_frame *pmgntframe;
3591 struct pkt_attrib *pattrib;
3592 struct ieee80211_mgmt *mgmt;
3593 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3594 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3595 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3598 /* DBG_8723A("%s to %pM\n", __func__, da); */
3600 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3604 /* update attribute */
3605 pattrib = &pmgntframe->attrib;
3606 update_mgntframe_attrib23a(padapter, pattrib);
3607 pattrib->retry_ctrl = false;
3609 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3611 mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
3613 mgmt->frame_control =
3614 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH);
3616 ether_addr_copy(mgmt->da, da);
3617 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
3618 ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
3620 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3621 pmlmeext->mgnt_seq++;
3623 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr) + 2;
3625 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
3627 pattrib->last_txcmdsz = pattrib->pktlen;
3630 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3632 dump_mgntframe23a(padapter, pmgntframe);
3640 int issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
3641 unsigned short reason)
3643 DBG_8723A("%s to %pM\n", __func__, da);
3644 return _issue_deauth(padapter, da, reason, false);
3647 static int issue_deauth_ex(struct rtw_adapter *padapter, u8 *da,
3648 unsigned short reason, int try_cnt, int wait_ms)
3652 unsigned long start = jiffies;
3655 ret = _issue_deauth(padapter, da, reason,
3656 wait_ms >0 ? true : false);
3660 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3663 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3666 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3673 if (try_cnt && wait_ms) {
3675 DBG_8723A("%s(%s): to %pM, ch:%u%s, %d/%d in %u ms\n",
3676 __func__, padapter->pnetdev->name,
3677 da, rtw_get_oper_ch23a(padapter),
3678 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
3679 jiffies_to_msecs(jiffies - start));
3681 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3682 __func__, padapter->pnetdev->name,
3683 rtw_get_oper_ch23a(padapter),
3684 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
3685 jiffies_to_msecs(jiffies - start));
3691 void issue_action_spct_ch_switch23a(struct rtw_adapter *padapter,
3692 u8 *ra, u8 new_ch, u8 ch_offset)
3694 struct xmit_frame *pmgntframe;
3695 struct pkt_attrib *pattrib;
3696 unsigned char *pframe;
3697 struct ieee80211_mgmt *mgmt;
3698 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3699 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3701 DBG_8723A("%s(%s): ra=%pM, ch:%u, offset:%u\n",
3702 __func__, padapter->pnetdev->name, ra, new_ch, ch_offset);
3704 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3708 /* update attribute */
3709 pattrib = &pmgntframe->attrib;
3710 update_mgntframe_attrib23a(padapter, pattrib);
3712 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3714 mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
3716 mgmt->frame_control =
3717 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
3719 ether_addr_copy(mgmt->da, ra); /* RA */
3720 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv)); /* TA */
3721 ether_addr_copy(mgmt->bssid, ra); /* DA = RA */
3723 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3724 pmlmeext->mgnt_seq++;
3726 mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
3727 mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH;
3729 pframe = mgmt->u.action.u.chan_switch.variable;
3730 pattrib->pktlen = offsetof(struct ieee80211_mgmt,
3731 u.action.u.chan_switch.variable);
3733 pframe = rtw_set_ie23a_ch_switch (pframe, &pattrib->pktlen, 0,
3735 pframe = rtw_set_ie23a_secondary_ch_offset(pframe, &pattrib->pktlen,
3736 hal_ch_offset_to_secondary_ch_offset23a(ch_offset));
3738 pattrib->last_txcmdsz = pattrib->pktlen;
3740 dump_mgntframe23a(padapter, pmgntframe);
3743 void issue_action_BA23a(struct rtw_adapter *padapter,
3744 const unsigned char *raddr,
3745 unsigned char action, unsigned short status)
3749 u16 BA_starting_seqctrl;
3751 int max_rx_ampdu_factor;
3752 struct xmit_frame *pmgntframe;
3753 struct pkt_attrib *pattrib;
3754 struct ieee80211_mgmt *mgmt;
3755 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3756 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3757 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3758 struct sta_info *psta;
3759 struct sta_priv *pstapriv = &padapter->stapriv;
3760 struct registry_priv *pregpriv = &padapter->registrypriv;
3761 u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
3763 DBG_8723A("%s, action =%d, status =%d\n", __func__, action, status);
3765 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3769 /* update attribute */
3770 pattrib = &pmgntframe->attrib;
3771 update_mgntframe_attrib23a(padapter, pattrib);
3773 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3775 mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
3777 mgmt->frame_control =
3778 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
3780 ether_addr_copy(mgmt->da, raddr);
3781 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
3782 ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
3784 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3785 pmlmeext->mgnt_seq++;
3787 mgmt->u.action.category = WLAN_CATEGORY_BACK;
3789 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr) + 1;
3792 case WLAN_ACTION_ADDBA_REQ:
3793 pattrib->pktlen += sizeof(mgmt->u.action.u.addba_req);
3795 mgmt->u.action.u.addba_req.action_code = action;
3798 pmlmeinfo->dialogToken++;
3799 } while (pmlmeinfo->dialogToken == 0);
3801 mgmt->u.action.u.addba_req.dialog_token =
3802 pmlmeinfo->dialogToken;
3804 if (rtl8723a_BT_coexist(padapter) &&
3805 rtl8723a_BT_using_antenna_1(padapter) &&
3806 (pmlmeinfo->assoc_AP_vendor != broadcomAP ||
3807 memcmp(raddr, tendaAPMac, 3))) {
3808 /* A-MSDU NOT Supported */
3810 /* immediate Block Ack */
3811 BA_para_set |= (1 << 1) &
3812 IEEE80211_ADDBA_PARAM_POLICY_MASK;
3814 BA_para_set |= (status << 2) &
3815 IEEE80211_ADDBA_PARAM_TID_MASK;
3816 /* max buffer size is 8 MSDU */
3817 BA_para_set |= (8 << 6) &
3818 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3820 /* immediate ack & 64 buffer size */
3821 BA_para_set = 0x1002 | ((status & 0xf) << 2);
3824 put_unaligned_le16(BA_para_set,
3825 &mgmt->u.action.u.addba_req.capab);
3828 put_unaligned_le16(5000, &mgmt->u.action.u.addba_req.timeout);
3830 psta = rtw_get_stainfo23a(pstapriv, raddr);
3834 idx = status & 0x07;
3836 (psta->sta_xmitpriv.txseq_tid[idx] & 0xfff) + 1;
3838 DBG_8723A("BA_starting_seqctrl = %d for TID =%d\n",
3841 psta->BA_starting_seqctrl[idx] = start_seq;
3843 BA_starting_seqctrl = start_seq << 4;
3845 BA_starting_seqctrl = 0;
3847 put_unaligned_le16(BA_starting_seqctrl,
3848 &mgmt->u.action.u.addba_req.start_seq_num);
3852 case WLAN_ACTION_ADDBA_RESP:
3853 pattrib->pktlen += sizeof(mgmt->u.action.u.addba_resp);
3855 mgmt->u.action.u.addba_resp.action_code = action;
3856 mgmt->u.action.u.addba_resp.dialog_token =
3857 pmlmeinfo->ADDBA_req.dialog_token;
3858 put_unaligned_le16(status,
3859 &mgmt->u.action.u.addba_resp.status);
3861 GetHalDefVar8192CUsb(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
3862 &max_rx_ampdu_factor);
3864 BA_para = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f;
3865 if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_64K)
3866 BA_para_set = BA_para | 0x1000; /* 64 buffer size */
3867 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_32K)
3868 BA_para_set = BA_para | 0x0800; /* 32 buffer size */
3869 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_16K)
3870 BA_para_set = BA_para | 0x0400; /* 16 buffer size */
3871 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_8K)
3872 BA_para_set = BA_para | 0x0200; /* 8 buffer size */
3874 BA_para_set = BA_para | 0x1000; /* 64 buffer size */
3876 if (rtl8723a_BT_coexist(padapter) &&
3877 rtl8723a_BT_using_antenna_1(padapter) &&
3878 (pmlmeinfo->assoc_AP_vendor != broadcomAP ||
3879 memcmp(raddr, tendaAPMac, 3))) {
3880 /* max buffer size is 8 MSDU */
3881 BA_para_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3882 BA_para_set |= (8 << 6) &
3883 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3886 if (pregpriv->ampdu_amsdu == 0)/* disabled */
3887 BA_para_set &= ~BIT(0);
3888 else if (pregpriv->ampdu_amsdu == 1)/* enabled */
3889 BA_para_set |= BIT(0);
3891 put_unaligned_le16(BA_para_set,
3892 &mgmt->u.action.u.addba_resp.capab);
3894 mgmt->u.action.u.addba_resp.timeout
3895 = pmlmeinfo->ADDBA_req.BA_timeout_value;
3897 pattrib->pktlen += 8;
3899 case WLAN_ACTION_DELBA:
3900 pattrib->pktlen += sizeof(mgmt->u.action.u.delba);
3902 mgmt->u.action.u.delba.action_code = action;
3903 BA_para_set = (status & 0x1F) << 3;
3904 mgmt->u.action.u.delba.params = cpu_to_le16(BA_para_set);
3905 mgmt->u.action.u.delba.reason_code =
3906 cpu_to_le16(WLAN_REASON_QSTA_NOT_USE);
3908 pattrib->pktlen += 5;
3914 pattrib->last_txcmdsz = pattrib->pktlen;
3916 dump_mgntframe23a(padapter, pmgntframe);
3919 int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr)
3921 struct sta_priv *pstapriv = &padapter->stapriv;
3922 struct sta_info *psta = NULL;
3923 /* struct recv_reorder_ctrl *preorder_ctrl; */
3924 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3925 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3928 if ((pmlmeinfo->state&0x03) != MSR_AP)
3929 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3932 psta = rtw_get_stainfo23a(pstapriv, addr);
3936 if (initiator == 0) { /* recipient */
3937 for (tid = 0; tid < MAXTID; tid++) {
3938 if (psta->recvreorder_ctrl[tid].enable == true) {
3939 DBG_8723A("rx agg disable tid(%d)\n", tid);
3940 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
3941 psta->recvreorder_ctrl[tid].enable = false;
3942 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
3945 } else if (initiator == 1) { /* originator */
3946 for (tid = 0; tid < MAXTID; tid++) {
3947 if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
3948 DBG_8723A("tx agg disable tid(%d)\n", tid);
3949 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
3950 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3951 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
3959 int send_beacon23a(struct rtw_adapter *padapter)
3964 unsigned long start = jiffies;
3965 unsigned int passing_time;
3967 rtl8723a_bcn_valid(padapter);
3969 issue_beacon23a(padapter, 100);
3973 bxmitok = rtl8723a_get_bcn_valid(padapter);
3975 } while ((poll % 10) != 0 && !bxmitok &&
3976 !padapter->bSurpriseRemoved &&
3977 !padapter->bDriverStopped);
3979 } while (!bxmitok && issue<100 && !padapter->bSurpriseRemoved &&
3980 !padapter->bDriverStopped);
3982 if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
3985 passing_time = jiffies_to_msecs(jiffies - start);
3988 DBG_8723A("%s fail! %u ms\n", __func__, passing_time);
3992 if (passing_time > 100 || issue > 3)
3993 DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n",
3994 __func__, issue, poll, passing_time);
3999 /****************************************************************************
4001 Following are some utitity functions for WiFi MLME
4003 *****************************************************************************/
4005 bool IsLegal5GChannel(struct rtw_adapter *Adapter, u8 channel)
4009 u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
4010 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
4011 114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
4012 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
4014 for (i = 0; i < sizeof(Channel_5G); i++)
4015 if (channel == Channel_5G[i])
4020 static void rtw_site_survey(struct rtw_adapter *padapter)
4022 unsigned char survey_channel = 0;
4023 enum rt_scan_type ScanType = SCAN_PASSIVE;
4024 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4025 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4026 struct rtw_ieee80211_channel *ch;
4028 if (pmlmeext->sitesurvey_res.channel_idx <
4029 pmlmeext->sitesurvey_res.ch_num) {
4030 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
4031 survey_channel = ch->hw_value;
4032 ScanType = (ch->flags & IEEE80211_CHAN_NO_IR) ?
4033 SCAN_PASSIVE : SCAN_ACTIVE;
4036 if (survey_channel != 0) {
4037 /* PAUSE 4-AC Queue when site_survey */
4038 if (pmlmeext->sitesurvey_res.channel_idx == 0)
4039 set_channel_bwmode23a(padapter, survey_channel,
4040 HAL_PRIME_CHNL_OFFSET_DONT_CARE,
4041 HT_CHANNEL_WIDTH_20);
4043 SelectChannel23a(padapter, survey_channel);
4045 if (ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */
4049 for (i = 0;i<RTW_SSID_SCAN_AMOUNT;i++) {
4050 if (pmlmeext->sitesurvey_res.ssid[i].ssid_len) {
4051 /* todo: to issue two probe req??? */
4052 issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4053 /* msleep(SURVEY_TO>>1); */
4054 issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4058 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
4059 /* todo: to issue two probe req??? */
4060 issue_probereq(padapter, NULL, NULL);
4061 /* msleep(SURVEY_TO>>1); */
4062 issue_probereq(padapter, NULL, NULL);
4066 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
4068 /* channel number is 0 or this channel is not valid. */
4069 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
4071 /* switch back to the original channel */
4073 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
4074 pmlmeext->cur_ch_offset,
4075 pmlmeext->cur_bwmode);
4077 /* flush 4-AC Queue after rtw_site_survey */
4081 rtl8723a_set_media_status(padapter, pmlmeinfo->state & 0x3);
4083 /* restore RX GAIN */
4084 rtl8723a_set_initial_gain(padapter, 0xff);
4085 /* turn on dynamic functions */
4086 rtl8723a_odm_support_ability_restore(padapter);
4088 if (is_client_associated_to_ap23a(padapter) == true)
4089 issue_nulldata23a(padapter, NULL, 0, 3, 500);
4091 rtl8723a_mlme_sitesurvey(padapter, 0);
4093 report_surveydone_event23a(padapter);
4095 pmlmeext->chan_scan_time = SURVEY_TO;
4096 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
4100 /* collect bss info from Beacon and Probe request/response frames. */
4101 static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter,
4102 struct recv_frame *precv_frame)
4104 struct sk_buff *skb = precv_frame->pkt;
4105 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
4106 struct registry_priv *pregistrypriv = &padapter->registrypriv;
4107 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4108 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4109 struct wlan_bssid_ex *bssid;
4112 unsigned int length;
4117 bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
4121 if (ieee80211_is_beacon(mgmt->frame_control)) {
4122 length -= offsetof(struct ieee80211_mgmt, u.beacon.variable);
4123 pie = mgmt->u.beacon.variable;
4124 bssid->reserved = 1;
4126 get_unaligned_le16(&mgmt->u.beacon.capab_info);
4127 bssid->beacon_interval =
4128 get_unaligned_le16(&mgmt->u.beacon.beacon_int);
4129 bssid->tsf = get_unaligned_le64(&mgmt->u.beacon.timestamp);
4130 } else if (ieee80211_is_probe_req(mgmt->frame_control)) {
4131 length -= offsetof(struct ieee80211_mgmt, u.probe_req.variable);
4132 pie = mgmt->u.probe_req.variable;
4133 bssid->reserved = 2;
4134 bssid->capability = 0;
4135 bssid->beacon_interval =
4136 padapter->registrypriv.dev_network.beacon_interval;
4138 } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4140 offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
4141 pie = mgmt->u.probe_resp.variable;
4142 bssid->reserved = 3;
4144 get_unaligned_le16(&mgmt->u.probe_resp.capab_info);
4145 bssid->beacon_interval =
4146 get_unaligned_le16(&mgmt->u.probe_resp.beacon_int);
4147 bssid->tsf = get_unaligned_le64(&mgmt->u.probe_resp.timestamp);
4149 length -= offsetof(struct ieee80211_mgmt, u.beacon.variable);
4150 pie = mgmt->u.beacon.variable;
4151 bssid->reserved = 0;
4153 get_unaligned_le16(&mgmt->u.beacon.capab_info);
4154 bssid->beacon_interval =
4155 padapter->registrypriv.dev_network.beacon_interval;
4159 if (length > MAX_IE_SZ) {
4160 /* DBG_8723A("IE too long for survey event\n"); */
4165 bssid->Length = offsetof(struct wlan_bssid_ex, IEs) + length;
4167 /* below is to copy the information element */
4168 bssid->IELength = length;
4169 memcpy(bssid->IEs, pie, bssid->IELength);
4171 /* get the signal strength */
4172 /* in dBM.raw data */
4173 bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower;
4174 bssid->SignalQuality =
4175 precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
4176 bssid->SignalStrength =
4177 precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
4180 p = cfg80211_find_ie(WLAN_EID_SSID, bssid->IEs, bssid->IELength);
4183 DBG_8723A("marc: cannot find SSID for survey event\n");
4187 if (p[1] > IEEE80211_MAX_SSID_LEN) {
4188 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4189 "event\n", __func__, __LINE__, p[1]);
4192 memcpy(bssid->Ssid.ssid, p + 2, p[1]);
4193 bssid->Ssid.ssid_len = p[1];
4195 /* checking rate info... */
4197 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, bssid->IEs, bssid->IELength);
4199 if (p[1] > NDIS_802_11_LENGTH_RATES_EX) {
4200 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4201 "event\n", __func__, __LINE__, p[1]);
4204 memcpy(bssid->SupportedRates, p + 2, p[1]);
4208 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, bssid->IEs,
4211 if (p[1] > (NDIS_802_11_LENGTH_RATES_EX-i)) {
4212 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4213 "event\n", __func__, __LINE__, p[1]);
4216 memcpy(bssid->SupportedRates + i, p + 2, p[1]);
4219 /* Checking for DSConfig */
4220 p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bssid->IEs, bssid->IELength);
4222 bssid->DSConfig = 0;
4225 bssid->DSConfig = p[2];
4226 } else {/* In 5G, some ap do not have DSSET IE */
4227 /* checking HT info for channel */
4228 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, bssid->IEs,
4231 struct ieee80211_ht_operation *HT_info =
4232 (struct ieee80211_ht_operation *)(p + 2);
4233 bssid->DSConfig = HT_info->primary_chan;
4234 } else /* use current channel */
4235 bssid->DSConfig = rtw_get_oper_ch23a(padapter);
4238 if (ieee80211_is_probe_req(mgmt->frame_control)) {
4240 bssid->ifmode = NL80211_IFTYPE_STATION;
4241 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4246 if (bssid->capability & WLAN_CAPABILITY_ESS) {
4247 bssid->ifmode = NL80211_IFTYPE_STATION;
4248 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4250 bssid->ifmode = NL80211_IFTYPE_ADHOC;
4251 ether_addr_copy(bssid->MacAddress, mgmt->bssid);
4254 if (bssid->capability & WLAN_CAPABILITY_PRIVACY)
4259 bssid->ATIMWindow = 0;
4261 /* 20/40 BSS Coexistence check */
4262 if (pregistrypriv->wifi_spec == 1 &&
4263 pmlmeinfo->bwmode_updated == false) {
4264 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4266 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, bssid->IEs,
4268 if (p && p[1] > 0) {
4269 struct ieee80211_ht_cap *pHT_caps;
4271 pHT_caps = (struct ieee80211_ht_cap *)(p + 2);
4273 if (pHT_caps->cap_info &
4274 cpu_to_le16(IEEE80211_HT_CAP_40MHZ_INTOLERANT))
4275 pmlmepriv->num_FortyMHzIntolerant++;
4277 pmlmepriv->num_sta_no_ht++;
4281 /* mark bss info receiving from nearby channel as SignalQuality 101 */
4282 if (bssid->DSConfig != rtw_get_oper_ch23a(padapter))
4283 bssid->SignalQuality = 101;
4291 static void start_create_ibss(struct rtw_adapter *padapter)
4293 unsigned short caps;
4294 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4295 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4296 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4298 pmlmeext->cur_channel = (u8)pnetwork->DSConfig;
4299 pmlmeinfo->bcn_interval = pnetwork->beacon_interval;
4301 /* update wireless mode */
4302 update_wireless_mode23a(padapter);
4304 /* update capability */
4305 caps = pnetwork->capability;
4306 update_capinfo23a(padapter, caps);
4307 if (caps & WLAN_CAPABILITY_IBSS) { /* adhoc master */
4308 rtl8723a_set_sec_cfg(padapter, 0xcf);
4310 /* switch channel */
4311 /* SelectChannel23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
4312 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4314 rtl8723a_SetBeaconRelatedRegisters(padapter);
4316 /* set msr to MSR_ADHOC */
4317 pmlmeinfo->state = MSR_ADHOC;
4318 rtl8723a_set_media_status(padapter, pmlmeinfo->state & 0x3);
4321 if (send_beacon23a(padapter) == _FAIL) {
4322 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
4323 "issuing beacon frame fail....\n");
4325 report_join_res23a(padapter, -1);
4326 pmlmeinfo->state = MSR_NOLINK;
4328 hw_var_set_bssid(padapter, padapter->registrypriv.dev_network.MacAddress);
4329 hw_var_set_mlme_join(padapter, 0);
4331 report_join_res23a(padapter, 1);
4332 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
4335 DBG_8723A("%s: invalid cap:%x\n", __func__, caps);
4340 static void start_clnt_join(struct rtw_adapter *padapter)
4342 unsigned short caps;
4344 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4345 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4346 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4349 pmlmeext->cur_channel = (u8)pnetwork->DSConfig;
4350 pmlmeinfo->bcn_interval = pnetwork->beacon_interval;
4352 /* update wireless mode */
4353 update_wireless_mode23a(padapter);
4355 /* update capability */
4356 caps = pnetwork->capability;
4357 update_capinfo23a(padapter, caps);
4358 if (caps & WLAN_CAPABILITY_ESS) {
4359 /* switch channel */
4360 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4362 rtl8723a_set_media_status(padapter, MSR_INFRA);
4364 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ?
4367 rtl8723a_set_sec_cfg(padapter, val8);
4369 /* switch channel */
4370 /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
4372 /* here wait for receiving the beacon to start auth */
4373 /* and enable a timer */
4374 beacon_timeout = decide_wait_for_beacon_timeout23a(pmlmeinfo->bcn_interval);
4375 set_link_timer(pmlmeext, beacon_timeout);
4376 mod_timer(&padapter->mlmepriv.assoc_timer, jiffies +
4377 msecs_to_jiffies((REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout));
4378 pmlmeinfo->state = WIFI_FW_AUTH_NULL | MSR_INFRA;
4379 } else if (caps & WLAN_CAPABILITY_IBSS) { /* adhoc client */
4380 rtl8723a_set_media_status(padapter, MSR_ADHOC);
4382 rtl8723a_set_sec_cfg(padapter, 0xcf);
4384 /* switch channel */
4385 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4387 rtl8723a_SetBeaconRelatedRegisters(padapter);
4389 pmlmeinfo->state = MSR_ADHOC;
4391 report_join_res23a(padapter, 1);
4393 /* DBG_8723A("marc: invalid cap:%x\n", caps); */
4398 static void start_clnt_auth(struct rtw_adapter *padapter)
4400 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4401 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4403 del_timer_sync(&pmlmeext->link_timer);
4405 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
4406 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
4408 pmlmeinfo->auth_seq = 1;
4409 pmlmeinfo->reauth_count = 0;
4410 pmlmeinfo->reassoc_count = 0;
4411 pmlmeinfo->link_count = 0;
4412 pmlmeext->retry = 0;
4414 /* Because of AP's not receiving deauth before */
4415 /* AP may: 1)not response auth or 2)deauth us after link is complete */
4416 /* issue deauth before issuing auth to deal with the situation */
4417 /* Commented by Albert 2012/07/21 */
4418 /* For the Win8 P2P connection, it will be hard to have a
4419 successful connection if this Wi-Fi doesn't connect to it. */
4420 issue_deauth23a(padapter, (&pmlmeinfo->network)->MacAddress,
4421 WLAN_REASON_DEAUTH_LEAVING);
4423 DBG_8723A_LEVEL(_drv_always_, "start auth\n");
4424 issue_auth(padapter, NULL, 0);
4426 set_link_timer(pmlmeext, REAUTH_TO);
4429 static void start_clnt_assoc(struct rtw_adapter *padapter)
4431 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4432 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4434 del_timer_sync(&pmlmeext->link_timer);
4436 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
4437 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
4439 issue_assocreq(padapter);
4441 set_link_timer(pmlmeext, REASSOC_TO);
4444 int receive_disconnect23a(struct rtw_adapter *padapter,
4445 unsigned char *MacAddr, unsigned short reason)
4447 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4448 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4451 if (!ether_addr_equal(MacAddr, get_my_bssid23a(&pmlmeinfo->network)))
4454 DBG_8723A("%s\n", __func__);
4456 if ((pmlmeinfo->state&0x03) == MSR_INFRA) {
4457 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
4458 pmlmeinfo->state = MSR_NOLINK;
4459 report_del_sta_event23a(padapter, MacAddr, reason);
4461 } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) {
4462 pmlmeinfo->state = MSR_NOLINK;
4463 report_join_res23a(padapter, -2);
4470 static void process_80211d(struct rtw_adapter *padapter,
4471 struct wlan_bssid_ex *bssid)
4473 struct registry_priv *pregistrypriv;
4474 struct mlme_ext_priv *pmlmeext;
4475 struct rt_channel_info *chplan_new;
4479 pregistrypriv = &padapter->registrypriv;
4480 pmlmeext = &padapter->mlmeextpriv;
4482 /* Adjust channel plan by AP Country IE */
4483 if (pregistrypriv->enable80211d &&
4484 !pmlmeext->update_channel_plan_by_ap_done) {
4486 struct rt_channel_plan chplan_ap;
4487 struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
4489 u8 fcn; /* first channel number */
4490 u8 noc; /* number of channel */
4493 ie = cfg80211_find_ie(WLAN_EID_COUNTRY, bssid->IEs,
4495 if (!ie || ie[1] < IEEE80211_COUNTRY_IE_MIN_LEN)
4502 memcpy(country, p, 3);
4506 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4507 "%s: 802.11d country =%s\n", __func__, country);
4510 while ((ie - p) >= 3) {
4515 for (j = 0; j < noc; j++) {
4517 channel = fcn + j; /* 2.4 GHz */
4519 channel = fcn + j * 4; /* 5 GHz */
4521 chplan_ap.Channel[i++] = channel;
4526 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
4527 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
4528 chplan_new = pmlmeext->channel_set;
4531 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
4533 if (i == MAX_CHANNEL_NUM ||
4534 chplan_sta[i].ChannelNum == 0 ||
4535 chplan_sta[i].ChannelNum > 14)
4538 if (j == chplan_ap.Len ||
4539 chplan_ap.Channel[j] > 14)
4542 if (chplan_sta[i].ChannelNum ==
4543 chplan_ap.Channel[j]) {
4544 chplan_new[k].ChannelNum =
4545 chplan_ap.Channel[j];
4546 chplan_new[k].ScanType = SCAN_ACTIVE;
4550 } else if (chplan_sta[i].ChannelNum <
4551 chplan_ap.Channel[j]) {
4552 chplan_new[k].ChannelNum =
4553 chplan_sta[i].ChannelNum;
4554 chplan_new[k].ScanType =
4558 } else if (chplan_sta[i].ChannelNum >
4559 chplan_ap.Channel[j]) {
4560 chplan_new[k].ChannelNum =
4561 chplan_ap.Channel[j];
4562 chplan_new[k].ScanType =
4569 /* change AP not support channel to Passive scan */
4570 while (i < MAX_CHANNEL_NUM &&
4571 chplan_sta[i].ChannelNum != 0 &&
4572 chplan_sta[i].ChannelNum <= 14) {
4573 chplan_new[k].ChannelNum =
4574 chplan_sta[i].ChannelNum;
4575 chplan_new[k].ScanType = SCAN_PASSIVE;
4580 /* add channel AP supported */
4581 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14){
4582 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4583 chplan_new[k].ScanType = SCAN_ACTIVE;
4588 /* keep original STA 2.4G channel plan */
4589 while (i < MAX_CHANNEL_NUM &&
4590 chplan_sta[i].ChannelNum != 0 &&
4591 chplan_sta[i].ChannelNum <= 14) {
4592 chplan_new[k].ChannelNum =
4593 chplan_sta[i].ChannelNum;
4594 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4599 /* skip AP 2.4G channel plan */
4600 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14)
4604 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
4606 if (i == MAX_CHANNEL_NUM ||
4607 chplan_sta[i].ChannelNum == 0)
4610 if (j == chplan_ap.Len ||
4611 chplan_ap.Channel[j] == 0)
4614 if (chplan_sta[i].ChannelNum ==
4615 chplan_ap.Channel[j]) {
4616 chplan_new[k].ChannelNum =
4617 chplan_ap.Channel[j];
4618 chplan_new[k].ScanType = SCAN_ACTIVE;
4622 } else if (chplan_sta[i].ChannelNum <
4623 chplan_ap.Channel[j]) {
4624 chplan_new[k].ChannelNum =
4625 chplan_sta[i].ChannelNum;
4626 chplan_new[k].ScanType = SCAN_PASSIVE;
4629 } else if (chplan_sta[i].ChannelNum >
4630 chplan_ap.Channel[j]) {
4631 chplan_new[k].ChannelNum =
4632 chplan_ap.Channel[j];
4633 chplan_new[k].ScanType = SCAN_ACTIVE;
4639 /* change AP not support channel to Passive scan */
4640 while (i < MAX_CHANNEL_NUM &&
4641 chplan_sta[i].ChannelNum != 0) {
4642 chplan_new[k].ChannelNum =
4643 chplan_sta[i].ChannelNum;
4644 chplan_new[k].ScanType = SCAN_PASSIVE;
4649 /* add channel AP supported */
4650 while (j < chplan_ap.Len && chplan_ap.Channel[j] != 0) {
4651 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4652 chplan_new[k].ScanType = SCAN_ACTIVE;
4657 /* keep original STA 5G channel plan */
4658 while (i < MAX_CHANNEL_NUM &&
4659 chplan_sta[i].ChannelNum != 0) {
4660 chplan_new[k].ChannelNum =
4661 chplan_sta[i].ChannelNum;
4662 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4667 pmlmeext->update_channel_plan_by_ap_done = 1;
4670 /* If channel is used by AP, set channel scan type to active */
4671 channel = bssid->DSConfig;
4672 chplan_new = pmlmeext->channel_set;
4674 while (i < MAX_CHANNEL_NUM && chplan_new[i].ChannelNum != 0) {
4675 if (chplan_new[i].ChannelNum == channel) {
4676 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
4677 /* 5G Bnad 2, 3 (DFS) doesn't change
4679 if (channel >= 52 && channel <= 144)
4682 chplan_new[i].ScanType = SCAN_ACTIVE;
4683 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4684 "%s: change channel %d scan type from passive to active\n",
4693 /****************************************************************************
4695 Following are the functions to report events
4697 *****************************************************************************/
4699 void report_survey_event23a(struct rtw_adapter *padapter,
4700 struct recv_frame *precv_frame)
4702 struct cmd_obj *pcmd_obj;
4705 struct survey_event *psurvey_evt;
4706 struct C2HEvent_Header *pc2h_evt_hdr;
4707 struct mlme_ext_priv *pmlmeext;
4708 struct cmd_priv *pcmdpriv;
4713 pmlmeext = &padapter->mlmeextpriv;
4714 pcmdpriv = &padapter->cmdpriv;
4716 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4720 cmdsz = sizeof(struct survey_event) + sizeof(struct C2HEvent_Header);
4721 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4727 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4728 pcmd_obj->cmdsz = cmdsz;
4729 pcmd_obj->parmbuf = pevtcmd;
4731 pcmd_obj->rsp = NULL;
4732 pcmd_obj->rspsz = 0;
4734 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4735 pc2h_evt_hdr->len = sizeof(struct survey_event);
4736 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
4737 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4739 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4741 psurvey_evt->bss = collect_bss_info(padapter, precv_frame);
4742 if (!psurvey_evt->bss) {
4748 process_80211d(padapter, psurvey_evt->bss);
4750 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4752 pmlmeext->sitesurvey_res.bss_cnt++;
4755 void report_surveydone_event23a(struct rtw_adapter *padapter)
4757 struct cmd_obj *pcmd_obj;
4760 struct surveydone_event *psurveydone_evt;
4761 struct C2HEvent_Header *pc2h_evt_hdr;
4762 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4763 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4765 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4769 cmdsz = sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header);
4770 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4776 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4777 pcmd_obj->cmdsz = cmdsz;
4778 pcmd_obj->parmbuf = pevtcmd;
4780 pcmd_obj->rsp = NULL;
4781 pcmd_obj->rspsz = 0;
4783 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4784 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
4785 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
4786 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4788 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4789 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
4791 DBG_8723A("survey done event(%x)\n", psurveydone_evt->bss_cnt);
4793 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4796 void report_join_res23a(struct rtw_adapter *padapter, int res)
4798 struct cmd_obj *pcmd_obj;
4801 struct joinbss_event *pjoinbss_evt;
4802 struct C2HEvent_Header *pc2h_evt_hdr;
4803 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4804 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4805 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4807 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4811 cmdsz = sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header);
4812 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4818 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4819 pcmd_obj->cmdsz = cmdsz;
4820 pcmd_obj->parmbuf = pevtcmd;
4822 pcmd_obj->rsp = NULL;
4823 pcmd_obj->rspsz = 0;
4825 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4826 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
4827 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
4828 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4830 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4831 memcpy((unsigned char *)&pjoinbss_evt->network.network,
4832 &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
4833 pjoinbss_evt->network.join_res = res;
4835 DBG_8723A("report_join_res23a(%d)\n", res);
4837 rtw_joinbss_event_prehandle23a(padapter, (u8 *)&pjoinbss_evt->network);
4839 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4842 void report_del_sta_event23a(struct rtw_adapter *padapter,
4843 unsigned char *MacAddr, unsigned short reason)
4845 struct cmd_obj *pcmd_obj;
4848 struct sta_info *psta;
4850 struct stadel_event *pdel_sta_evt;
4851 struct C2HEvent_Header *pc2h_evt_hdr;
4852 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4853 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4855 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4859 cmdsz = sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header);
4860 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4866 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4867 pcmd_obj->cmdsz = cmdsz;
4868 pcmd_obj->parmbuf = pevtcmd;
4870 pcmd_obj->rsp = NULL;
4871 pcmd_obj->rspsz = 0;
4873 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4874 pc2h_evt_hdr->len = sizeof(struct stadel_event);
4875 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
4876 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4878 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4879 ether_addr_copy((unsigned char *)&pdel_sta_evt->macaddr, MacAddr);
4880 memcpy((unsigned char *)pdel_sta_evt->rsvd, (unsigned char *)&reason,
4883 psta = rtw_get_stainfo23a(&padapter->stapriv, MacAddr);
4885 mac_id = (int)psta->mac_id;
4889 pdel_sta_evt->mac_id = mac_id;
4891 DBG_8723A("report_del_sta_event23a: delete STA, mac_id =%d\n", mac_id);
4893 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4896 void report_add_sta_event23a(struct rtw_adapter *padapter,
4897 unsigned char *MacAddr, int cam_idx)
4899 struct cmd_obj *pcmd_obj;
4902 struct stassoc_event *padd_sta_evt;
4903 struct C2HEvent_Header *pc2h_evt_hdr;
4904 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4905 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4907 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4911 cmdsz = sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header);
4912 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4918 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4919 pcmd_obj->cmdsz = cmdsz;
4920 pcmd_obj->parmbuf = pevtcmd;
4922 pcmd_obj->rsp = NULL;
4923 pcmd_obj->rspsz = 0;
4925 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4926 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
4927 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
4928 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4930 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4931 ether_addr_copy((unsigned char *)&padd_sta_evt->macaddr, MacAddr);
4932 padd_sta_evt->cam_id = cam_idx;
4934 DBG_8723A("report_add_sta_event23a: add STA\n");
4936 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4939 /****************************************************************************
4941 Following are the event callback functions
4943 *****************************************************************************/
4945 /* for sta/adhoc mode */
4946 void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta)
4948 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4949 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4950 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4953 VCS_update23a(padapter, psta);
4956 if (pmlmepriv->htpriv.ht_option) {
4957 psta->htpriv.ht_option = true;
4959 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
4961 if (support_short_GI23a(padapter, &pmlmeinfo->ht_cap))
4962 psta->htpriv.sgi = true;
4964 psta->qos_option = true;
4967 psta->htpriv.ht_option = false;
4969 psta->htpriv.ampdu_enable = false;
4971 psta->htpriv.sgi = false;
4972 psta->qos_option = false;
4975 psta->htpriv.bwmode = pmlmeext->cur_bwmode;
4976 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
4978 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
4979 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
4982 if (pmlmepriv->qos_option)
4983 psta->qos_option = true;
4985 psta->state = _FW_LINKED;
4988 void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter,
4991 struct sta_info *psta, *psta_bmc;
4992 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4993 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4994 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
4995 struct sta_priv *pstapriv = &padapter->stapriv;
4998 hw_var_set_mlme_join(padapter, 1);
4999 hw_var_set_bssid(padapter, null_addr);
5001 /* restore to initial setting. */
5002 update_tx_basic_rate23a(padapter,
5003 padapter->registrypriv.wireless_mode);
5005 goto exit_mlmeext_joinbss_event_callback23a;
5008 if ((pmlmeinfo->state&0x03) == MSR_ADHOC) {
5010 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
5012 pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
5013 update_bmc_sta_support_rate23a(padapter, psta_bmc->mac_id);
5014 Update_RA_Entry23a(padapter, psta_bmc);
5018 /* turn on dynamic functions */
5019 rtl8723a_odm_support_ability_set(padapter, DYNAMIC_ALL_FUNC_ENABLE);
5021 /* update IOT-releated issue */
5022 update_IOT_info23a(padapter);
5024 HalSetBrateCfg23a(padapter, cur_network->SupportedRates);
5027 rtl8723a_set_beacon_interval(padapter, pmlmeinfo->bcn_interval);
5029 /* update capability */
5030 update_capinfo23a(padapter, pmlmeinfo->capability);
5032 /* WMM, Update EDCA param */
5033 WMMOnAssocRsp23a(padapter);
5036 HTOnAssocRsp23a(padapter);
5038 /* Set cur_channel&cur_bwmode&cur_ch_offset */
5039 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5041 psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
5042 if (psta) { /* only for infra. mode */
5043 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5045 /* DBG_8723A("set_sta_rate23a\n"); */
5047 psta->wireless_mode = pmlmeext->cur_wireless_mode;
5049 /* set per sta rate after updating HT cap. */
5050 set_sta_rate23a(padapter, psta);
5053 hw_var_set_mlme_join(padapter, 2);
5055 if ((pmlmeinfo->state&0x03) == MSR_INFRA) {
5056 /* correcting TSF */
5057 rtw_correct_TSF(padapter);
5059 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5062 rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_CONNECT, 0);
5064 exit_mlmeext_joinbss_event_callback23a:
5065 DBG_8723A("=>%s\n", __func__);
5068 void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter,
5069 struct sta_info *psta)
5071 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5072 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5074 DBG_8723A("%s\n", __func__);
5076 if ((pmlmeinfo->state & 0x03) == MSR_ADHOC) {
5077 /* adhoc master or sta_count>1 */
5078 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
5080 } else { /* adhoc client */
5081 /* correcting TSF */
5082 rtw_correct_TSF(padapter);
5085 if (send_beacon23a(padapter) != _SUCCESS) {
5086 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
5088 pmlmeinfo->state ^= MSR_ADHOC;
5093 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
5095 hw_var_set_mlme_join(padapter, 2);
5098 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5100 /* rate radaptive */
5101 Update_RA_Entry23a(padapter, psta);
5103 /* update adhoc sta_info */
5104 update_sta_info23a(padapter, psta);
5107 void mlmeext_sta_del_event_callback23a(struct rtw_adapter *padapter)
5109 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5110 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5112 if (is_client_associated_to_ap23a(padapter) ||
5113 is_IBSS_empty23a(padapter)) {
5114 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5116 hw_var_set_mlme_disconnect(padapter);
5117 hw_var_set_bssid(padapter, null_addr);
5119 /* restore to initial setting. */
5120 update_tx_basic_rate23a(padapter,
5121 padapter->registrypriv.wireless_mode);
5123 /* switch to the 20M Hz mode after disconnect */
5124 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5125 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5127 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
5128 pmlmeext->cur_ch_offset,
5129 pmlmeext->cur_bwmode);
5131 flush_all_cam_entry23a(padapter);
5133 pmlmeinfo->state = MSR_NOLINK;
5135 /* set MSR to no link state -> infra. mode */
5136 rtl8723a_set_media_status(padapter, MSR_INFRA);
5138 del_timer_sync(&pmlmeext->link_timer);
5142 static u8 chk_ap_is_alive(struct rtw_adapter *padapter, struct sta_info *psta)
5146 if (sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta) &&
5147 sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) &&
5148 sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
5153 sta_update_last_rx_pkts(psta);
5157 void linked_status_chk23a(struct rtw_adapter *padapter)
5160 struct sta_info *psta;
5161 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5162 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5163 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5164 struct sta_priv *pstapriv = &padapter->stapriv;
5166 if (is_client_associated_to_ap23a(padapter)) {
5167 /* linked infrastructure client mode */
5169 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
5174 psta = rtw_get_stainfo23a(pstapriv,
5175 pmlmeinfo->network.MacAddress);
5177 bool is_p2p_enable = false;
5179 if (chk_ap_is_alive(padapter, psta) == false)
5182 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
5185 if (pmlmeext->active_keep_alive_check &&
5186 (rx_chk == _FAIL || tx_chk == _FAIL)) {
5187 u8 backup_oper_channel = 0;
5189 /* switch to correct channel of current
5190 network before issue keep-alive frames */
5191 if (rtw_get_oper_ch23a(padapter) !=
5192 pmlmeext->cur_channel) {
5193 backup_oper_channel =
5194 rtw_get_oper_ch23a(padapter);
5195 SelectChannel23a(padapter,
5196 pmlmeext->cur_channel);
5199 if (rx_chk != _SUCCESS)
5200 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
5202 if ((tx_chk != _SUCCESS &&
5203 pmlmeinfo->link_count++ == 0xf) ||
5204 rx_chk != _SUCCESS) {
5205 tx_chk = issue_nulldata23a(padapter,
5208 /* if tx acked and p2p disabled,
5209 set rx_chk _SUCCESS to reset retry
5211 if (tx_chk == _SUCCESS &&
5216 /* back to the original operation channel */
5217 if (backup_oper_channel>0)
5218 SelectChannel23a(padapter,
5219 backup_oper_channel);
5221 if (rx_chk != _SUCCESS) {
5222 if (pmlmeext->retry == 0) {
5223 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5224 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5225 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5229 if (tx_chk != _SUCCESS &&
5230 pmlmeinfo->link_count++ == 0xf)
5231 tx_chk = issue_nulldata23a(padapter,
5236 if (rx_chk == _FAIL) {
5238 if (pmlmeext->retry > rx_chk_limit) {
5239 DBG_8723A_LEVEL(_drv_always_,
5240 "%s(%s): disconnect or "
5241 "roaming\n", __func__,
5242 padapter->pnetdev->name);
5243 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress,
5244 WLAN_REASON_EXPIRATION_CHK);
5248 pmlmeext->retry = 0;
5250 if (tx_chk == _FAIL)
5251 pmlmeinfo->link_count &= 0xf;
5253 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
5254 pmlmeinfo->link_count = 0;
5258 } else if (is_client_associated_to_ibss23a(padapter)) {
5259 /* linked IBSS mode */
5260 /* for each assoc list entry to check the rx pkt counter */
5261 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
5262 if (pmlmeinfo->FW_sta_info[i].status == 1) {
5263 psta = pmlmeinfo->FW_sta_info[i].psta;
5268 if (pmlmeinfo->FW_sta_info[i].rx_pkt ==
5269 sta_rx_pkts(psta)) {
5271 if (pmlmeinfo->FW_sta_info[i].retry<3) {
5272 pmlmeinfo->FW_sta_info[i].retry++;
5274 pmlmeinfo->FW_sta_info[i].retry = 0;
5275 pmlmeinfo->FW_sta_info[i].status = 0;
5276 report_del_sta_event23a(padapter, psta->hwaddr,
5277 65535/* indicate disconnect caused by no rx */
5281 pmlmeinfo->FW_sta_info[i].retry = 0;
5282 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
5286 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5290 static void survey_timer_hdl(unsigned long data)
5292 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5293 struct cmd_obj *ph2c;
5294 struct sitesurvey_parm *psurveyPara;
5295 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5296 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5298 /* issue rtw_sitesurvey_cmd23a */
5299 if (pmlmeext->sitesurvey_res.state > SCAN_START) {
5300 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
5301 pmlmeext->sitesurvey_res.channel_idx++;
5303 if (pmlmeext->scan_abort == true) {
5304 pmlmeext->sitesurvey_res.channel_idx =
5305 pmlmeext->sitesurvey_res.ch_num;
5306 DBG_8723A("%s idx:%d\n", __func__,
5307 pmlmeext->sitesurvey_res.channel_idx);
5309 pmlmeext->scan_abort = false;/* reset */
5312 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
5314 goto exit_survey_timer_hdl;
5316 psurveyPara = kzalloc(sizeof(struct sitesurvey_parm),
5320 goto exit_survey_timer_hdl;
5323 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara,
5324 GEN_CMD_CODE(_SiteSurvey));
5325 rtw_enqueue_cmd23a(pcmdpriv, ph2c);
5328 exit_survey_timer_hdl:
5332 static void link_timer_hdl(unsigned long data)
5334 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5335 /* static unsigned int rx_pkt = 0; */
5336 /* static u64 tx_cnt = 0; */
5337 /* struct xmit_priv *pxmitpriv = &padapter->xmitpriv; */
5338 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5339 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5340 /* struct sta_priv *pstapriv = &padapter->stapriv; */
5342 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
5343 DBG_8723A("link_timer_hdl:no beacon while connecting\n");
5344 pmlmeinfo->state = MSR_NOLINK;
5345 report_join_res23a(padapter, -3);
5346 } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
5348 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
5349 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
5351 pmlmeinfo->state = 0;
5352 report_join_res23a(padapter, -1);
5357 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
5358 /* pmlmeinfo->reauth_count = 0; */
5362 DBG_8723A("link_timer_hdl: auth timeout and try again\n");
5363 pmlmeinfo->auth_seq = 1;
5364 issue_auth(padapter, NULL, 0);
5365 set_link_timer(pmlmeext, REAUTH_TO);
5366 } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
5367 /* re-assoc timer */
5368 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
5369 pmlmeinfo->state = MSR_NOLINK;
5370 report_join_res23a(padapter, -2);
5374 DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
5375 issue_assocreq(padapter);
5376 set_link_timer(pmlmeext, REASSOC_TO);
5380 static void addba_timer_hdl(unsigned long data)
5382 struct sta_info *psta = (struct sta_info *)data;
5383 struct ht_priv *phtpriv;
5388 phtpriv = &psta->htpriv;
5390 if (phtpriv->ht_option && phtpriv->ampdu_enable) {
5391 if (phtpriv->candidate_tid_bitmap)
5392 phtpriv->candidate_tid_bitmap = 0x0;
5396 void init_addba_retry_timer23a(struct sta_info *psta)
5398 setup_timer(&psta->addba_retry_timer, addba_timer_hdl,
5399 (unsigned long)psta);
5402 void init_mlme_ext_timer23a(struct rtw_adapter *padapter)
5404 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5406 setup_timer(&pmlmeext->survey_timer, survey_timer_hdl,
5407 (unsigned long)padapter);
5409 setup_timer(&pmlmeext->link_timer, link_timer_hdl,
5410 (unsigned long)padapter);
5413 int NULL_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5418 int setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5420 enum nl80211_iftype type;
5421 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5422 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5423 const struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
5425 switch (psetop->mode) {
5426 case NL80211_IFTYPE_P2P_GO:
5427 case NL80211_IFTYPE_AP:
5428 pmlmeinfo->state = MSR_AP;
5431 case NL80211_IFTYPE_P2P_CLIENT:
5432 case NL80211_IFTYPE_STATION:
5434 pmlmeinfo->state &= ~(BIT(0)|BIT(1));
5435 /* set to STATION_STATE */
5436 pmlmeinfo->state |= MSR_INFRA;
5439 case NL80211_IFTYPE_ADHOC:
5447 hw_var_set_opmode(padapter, type);
5448 /* Set_NETYPE0_MSR(padapter, type); */
5453 int createbss_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5455 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5456 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5457 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5458 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5459 /* u32 initialgain; */
5461 if (pparm->ifmode == NL80211_IFTYPE_AP ||
5462 pparm->ifmode == NL80211_IFTYPE_P2P_GO) {
5463 #ifdef CONFIG_8723AU_AP_MODE
5464 if (pmlmeinfo->state == MSR_AP) {
5471 /* below is for ad-hoc master */
5472 if (pparm->ifmode == NL80211_IFTYPE_ADHOC) {
5473 rtw_joinbss_reset23a(padapter);
5475 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5476 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5477 pmlmeinfo->ERP_enable = 0;
5478 pmlmeinfo->WMM_enable = 0;
5479 pmlmeinfo->HT_enable = 0;
5480 pmlmeinfo->HT_caps_enable = 0;
5481 pmlmeinfo->HT_info_enable = 0;
5483 /* disable dynamic functions, such as high power, DIG */
5484 rtl8723a_odm_support_ability_backup(padapter);
5486 rtl8723a_odm_support_ability_clr(padapter,
5487 DYNAMIC_FUNC_DISABLE);
5489 /* cancel link timer */
5490 del_timer_sync(&pmlmeext->link_timer);
5493 flush_all_cam_entry23a(padapter);
5495 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5496 return H2C_PARAMETERS_ERROR;
5498 memcpy(pnetwork, pparm, sizeof(struct wlan_bssid_ex));
5500 start_create_ibss(padapter);
5506 int join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5508 struct registry_priv *pregpriv = &padapter->registrypriv;
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 struct ieee80211_ht_operation *pht_info;
5516 /* u32 initialgain; */
5519 /* check already connecting to AP or not */
5520 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
5521 if (pmlmeinfo->state & MSR_INFRA)
5522 issue_deauth_ex(padapter, pnetwork->MacAddress,
5523 WLAN_REASON_DEAUTH_LEAVING, 5, 100);
5525 pmlmeinfo->state = MSR_NOLINK;
5528 flush_all_cam_entry23a(padapter);
5530 del_timer_sync(&pmlmeext->link_timer);
5532 /* set MSR to nolink -> infra. mode */
5533 rtl8723a_set_media_status(padapter, MSR_INFRA);
5535 hw_var_set_mlme_disconnect(padapter);
5538 rtw_joinbss_reset23a(padapter);
5540 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5541 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5542 pmlmeinfo->ERP_enable = 0;
5543 pmlmeinfo->WMM_enable = 0;
5544 pmlmeinfo->HT_enable = 0;
5545 pmlmeinfo->HT_caps_enable = 0;
5546 pmlmeinfo->HT_info_enable = 0;
5547 pmlmeinfo->bwmode_updated = false;
5548 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
5550 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5551 return H2C_PARAMETERS_ERROR;
5553 memcpy(pnetwork, pbuf, sizeof(struct wlan_bssid_ex));
5555 /* Check AP vendor to move rtw_joinbss_cmd23a() */
5556 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pnetwork->IEs,
5557 pnetwork->IELength); */
5559 for (i = 0; i < pnetwork->IELength;) {
5560 p = pnetwork->IEs + i;
5563 case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */
5564 if (!memcmp(p + 2, WMM_OUI23A, 4))
5565 pmlmeinfo->WMM_enable = 1;
5568 case WLAN_EID_HT_CAPABILITY: /* Get HT Cap IE. */
5569 pmlmeinfo->HT_caps_enable = 1;
5572 case WLAN_EID_HT_OPERATION: /* Get HT Info IE. */
5573 pmlmeinfo->HT_info_enable = 1;
5575 /* spec case only for cisco's ap because cisco's ap
5576 * issue assoc rsp using mcs rate @40MHz or @20MHz */
5577 pht_info = (struct ieee80211_ht_operation *)(p + 2);
5579 if (pregpriv->cbw40_enable &&
5580 (pht_info->ht_param &
5581 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
5582 /* switch to the 40M Hz mode according to AP */
5583 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
5584 switch (pht_info->ht_param &
5585 IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
5586 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
5587 pmlmeext->cur_ch_offset =
5588 HAL_PRIME_CHNL_OFFSET_LOWER;
5591 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
5592 pmlmeext->cur_ch_offset =
5593 HAL_PRIME_CHNL_OFFSET_UPPER;
5597 pmlmeext->cur_ch_offset =
5598 HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5602 DBG_8723A("set ch/bw before connected\n");
5613 hw_var_set_bssid(padapter, pmlmeinfo->network.MacAddress);
5614 hw_var_set_mlme_join(padapter, 0);
5616 /* cancel link timer */
5617 del_timer_sync(&pmlmeext->link_timer);
5619 start_clnt_join(padapter);
5624 int disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5626 const struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
5627 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5628 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5629 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5631 if (is_client_associated_to_ap23a(padapter)) {
5632 issue_deauth_ex(padapter, pnetwork->MacAddress,
5633 WLAN_REASON_DEAUTH_LEAVING,
5634 param->deauth_timeout_ms/100, 100);
5637 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5639 /* pmlmeinfo->state = MSR_NOLINK; */
5641 hw_var_set_mlme_disconnect(padapter);
5642 hw_var_set_bssid(padapter, null_addr);
5644 /* restore to initial setting. */
5645 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
5647 if ((pmlmeinfo->state & 0x03) == MSR_ADHOC ||
5648 (pmlmeinfo->state & 0x03) == MSR_AP)
5649 rtl8723a_set_bcn_func(padapter, 0); /* Stop BCN */
5651 /* set MSR to no link state -> infra. mode */
5652 rtl8723a_set_media_status(padapter, MSR_INFRA);
5654 pmlmeinfo->state = MSR_NOLINK;
5656 /* switch to the 20M Hz mode after disconnect */
5657 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5658 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5660 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
5661 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5663 flush_all_cam_entry23a(padapter);
5665 del_timer_sync(&pmlmeext->link_timer);
5667 rtw_free_uc_swdec_pending_queue23a(padapter);
5673 rtw_scan_ch_decision(struct rtw_adapter *padapter,
5674 struct rtw_ieee80211_channel *out, u32 out_num,
5675 const struct rtw_ieee80211_channel *in, u32 in_num)
5678 int scan_ch_num = 0;
5680 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5682 /* clear out first */
5683 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
5685 /* acquire channels from in */
5687 for (i = 0;i<in_num;i++) {
5688 if (in[i].hw_value &&
5689 !(in[i].flags & IEEE80211_CHAN_DISABLED) &&
5690 (set_idx = rtw_ch_set_search_ch23a(pmlmeext->channel_set,
5691 in[i].hw_value)) >= 0) {
5692 memcpy(&out[j], &in[i],
5693 sizeof(struct rtw_ieee80211_channel));
5695 if (pmlmeext->channel_set[set_idx].ScanType ==
5697 out[j].flags &= IEEE80211_CHAN_NO_IR;
5705 /* if out is empty, use channel_set as default */
5707 for (i = 0;i<pmlmeext->max_chan_nums;i++) {
5708 out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
5710 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
5711 out[i].flags &= IEEE80211_CHAN_NO_IR;
5717 if (padapter->setband == GHZ_24) { /* 2.4G */
5718 for (i = 0; i < j ; i++) {
5719 if (out[i].hw_value > 35)
5721 sizeof(struct rtw_ieee80211_channel));
5726 } else if (padapter->setband == GHZ_50) { /* 5G */
5727 for (i = 0; i < j ; i++) {
5728 if (out[i].hw_value > 35) {
5729 memcpy(&out[scan_ch_num++], &out[i],
5730 sizeof(struct rtw_ieee80211_channel));
5740 int sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5742 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5743 const struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
5744 u8 bdelayscan = false;
5748 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
5749 pmlmeext->sitesurvey_res.state = SCAN_START;
5750 pmlmeext->sitesurvey_res.bss_cnt = 0;
5751 pmlmeext->sitesurvey_res.channel_idx = 0;
5753 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
5754 if (pparm->ssid[i].ssid_len) {
5755 memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid,
5756 pparm->ssid[i].ssid,
5757 IEEE80211_MAX_SSID_LEN);
5758 pmlmeext->sitesurvey_res.ssid[i].ssid_len =
5759 pparm->ssid[i].ssid_len;
5761 pmlmeext->sitesurvey_res.ssid[i].ssid_len = 0;
5765 pmlmeext->sitesurvey_res.ch_num =
5766 rtw_scan_ch_decision(padapter,
5767 pmlmeext->sitesurvey_res.ch,
5768 RTW_CHANNEL_SCAN_AMOUNT,
5769 pparm->ch, pparm->ch_num);
5771 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
5773 /* issue null data if associating to the AP */
5774 if (is_client_associated_to_ap23a(padapter)) {
5775 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
5777 /* switch to correct channel of current network
5778 before issue keep-alive frames */
5779 if (rtw_get_oper_ch23a(padapter) !=
5780 pmlmeext->cur_channel)
5781 SelectChannel23a(padapter,
5782 pmlmeext->cur_channel);
5784 issue_nulldata23a(padapter, NULL, 1, 3, 500);
5790 /* delay 50ms to protect nulldata(1). */
5791 set_survey_timer(pmlmeext, 50);
5796 if (pmlmeext->sitesurvey_res.state == SCAN_START ||
5797 pmlmeext->sitesurvey_res.state == SCAN_TXNULL) {
5798 /* disable dynamic functions, such as high power, DIG */
5799 rtl8723a_odm_support_ability_backup(padapter);
5800 rtl8723a_odm_support_ability_clr(padapter,
5801 DYNAMIC_FUNC_DISABLE);
5803 /* config the initial gain under scanning, need to
5804 write the BB registers */
5805 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == true)
5810 rtl8723a_set_initial_gain(padapter, initialgain);
5812 /* set MSR to no link state */
5813 rtl8723a_set_media_status(padapter, MSR_NOLINK);
5815 rtl8723a_mlme_sitesurvey(padapter, 1);
5817 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
5820 rtw_site_survey(padapter);
5825 int setauth_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5827 const struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
5828 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5829 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5831 if (pparm->mode < 4)
5832 pmlmeinfo->auth_algo = pparm->mode;
5837 int setkey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5839 unsigned short ctrl;
5840 const struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
5841 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5842 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5843 unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
5845 /* main tx key for wep. */
5847 pmlmeinfo->key_index = pparm->keyid;
5850 ctrl = BIT(15) | (pparm->algorithm) << 2 | pparm->keyid;
5852 DBG_8723A_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 "
5853 "WEP104-5 TKIP-2 AES-4) keyid:%d\n",
5854 pparm->algorithm, pparm->keyid);
5855 rtl8723a_cam_write(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
5857 /* allow multicast packets to driver */
5858 rtl8723a_on_rcr_am(padapter);
5863 int set_stakey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5866 u8 cam_id;/* cam_entry */
5867 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5868 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5869 const struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
5872 /* 0~3 for default key */
5874 /* for concurrent mode (ap+sta): */
5875 /* default key is disable, using sw encrypt/decrypt */
5876 /* cam_entry = 4 for sta mode (macid = 0) */
5877 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
5879 /* for concurrent mode (sta+sta): */
5880 /* default key is disable, using sw encrypt/decrypt */
5881 /* cam_entry = 4 mapping to macid = 0 */
5882 /* cam_entry = 5 mapping to macid = 2 */
5886 DBG_8723A_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 "
5887 "WEP104-5 TKIP-2 AES-4) camid:%d\n",
5888 pparm->algorithm, cam_id);
5889 if ((pmlmeinfo->state & 0x03) == MSR_AP) {
5890 struct sta_info *psta;
5891 struct sta_priv *pstapriv = &padapter->stapriv;
5893 if (pparm->algorithm == 0) { /* clear cam entry */
5894 clear_cam_entry23a(padapter, pparm->id);
5895 return H2C_SUCCESS_RSP;
5898 psta = rtw_get_stainfo23a(pstapriv, pparm->addr);
5900 ctrl = BIT(15) | (pparm->algorithm << 2);
5902 DBG_8723A("r871x_set_stakey_hdl23a(): enc_algorithm "
5903 "=%d\n", pparm->algorithm);
5905 if (psta->mac_id < 1 || psta->mac_id > (NUM_STA - 4)) {
5906 DBG_8723A("r871x_set_stakey_hdl23a():set_stakey"
5907 " failed, mac_id(aid) =%d\n",
5909 return H2C_REJECTED;
5912 /* 0~3 for default key, cmd_id = macid + 3,
5914 cam_id = psta->mac_id + 3;
5916 DBG_8723A("Write CAM, mac_addr =%pM, "
5917 "cam_entry =%d\n", pparm->addr, cam_id);
5919 rtl8723a_cam_write(padapter, cam_id, ctrl,
5920 pparm->addr, pparm->key);
5922 return H2C_SUCCESS_RSP;
5924 DBG_8723A("r871x_set_stakey_hdl23a(): sta has been "
5926 return H2C_REJECTED;
5930 /* below for sta mode */
5932 if (pparm->algorithm == 0) { /* clear cam entry */
5933 clear_cam_entry23a(padapter, pparm->id);
5937 ctrl = BIT(15) | (pparm->algorithm << 2);
5939 rtl8723a_cam_write(padapter, cam_id, ctrl, pparm->addr, pparm->key);
5941 pmlmeinfo->enc_algo = pparm->algorithm;
5946 int add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5948 const struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
5949 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5950 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5951 struct sta_info *psta;
5953 psta = rtw_get_stainfo23a(&padapter->stapriv, pparm->addr);
5958 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
5959 pmlmeinfo->HT_enable) ||
5960 (pmlmeinfo->state & 0x03) == MSR_AP) {
5961 issue_action_BA23a(padapter, pparm->addr,
5962 WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
5963 mod_timer(&psta->addba_retry_timer,
5964 jiffies + msecs_to_jiffies(ADDBA_TO));
5966 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
5971 int set_tx_beacon_cmd23a(struct rtw_adapter *padapter)
5973 struct cmd_obj *ph2c;
5974 struct Tx_Beacon_param *ptxBeacon_parm;
5975 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5976 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5977 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5981 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
5987 ptxBeacon_parm = kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC);
5988 if (!ptxBeacon_parm) {
5994 memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network,
5995 sizeof(struct wlan_bssid_ex));
5997 len_diff = update_hidden_ssid(ptxBeacon_parm->network.IEs,
5998 ptxBeacon_parm->network.IELength,
5999 pmlmeinfo->hidden_ssid_mode);
6000 ptxBeacon_parm->network.IELength += len_diff;
6002 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm,
6003 GEN_CMD_CODE(_TX_Beacon));
6005 res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
6011 int mlme_evt_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6013 u8 evt_code, evt_seq;
6015 const struct C2HEvent_Header *c2h;
6016 void (*event_callback)(struct rtw_adapter *dev, const u8 *pbuf);
6018 c2h = (struct C2HEvent_Header *)pbuf;
6023 /* checking if event code is valid */
6024 if (evt_code >= MAX_C2HEVT) {
6025 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
6026 "Event Code(%d) mismatch!\n", evt_code);
6030 /* checking if event size match the event parm size */
6031 if (wlanevents[evt_code].parmsize != 0 &&
6032 wlanevents[evt_code].parmsize != evt_sz) {
6033 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
6034 "Event(%d) Parm Size mismatch (%d vs %d)!\n",
6035 evt_code, wlanevents[evt_code].parmsize, evt_sz);
6039 event_callback = wlanevents[evt_code].event_callback;
6040 event_callback(padapter, pbuf + sizeof(struct C2HEvent_Header));
6047 int h2c_msg_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6050 return H2C_PARAMETERS_ERROR;
6055 int tx_beacon_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6057 if (send_beacon23a(padapter) == _FAIL) {
6058 DBG_8723A("issue_beacon23a, fail!\n");
6059 return H2C_PARAMETERS_ERROR;
6061 #ifdef CONFIG_8723AU_AP_MODE
6062 else { /* tx bc/mc frames after update TIM */
6063 struct sta_info *psta_bmc;
6064 struct list_head *phead;
6065 struct xmit_frame *pxmitframe, *ptmp;
6066 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6067 struct sta_priv *pstapriv = &padapter->stapriv;
6069 /* for BC/MC Frames */
6070 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
6074 if (pstapriv->tim_bitmap & BIT(0) && psta_bmc->sleepq_len > 0) {
6075 msleep(10);/* 10ms, ATIM(HIQ) Windows */
6076 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
6077 spin_lock_bh(&pxmitpriv->lock);
6079 phead = get_list_head(&psta_bmc->sleep_q);
6081 list_for_each_entry_safe(pxmitframe, ptmp,
6084 list_del_init(&pxmitframe->list);
6086 psta_bmc->sleepq_len--;
6087 if (psta_bmc->sleepq_len>0)
6088 pxmitframe->attrib.mdata = 1;
6090 pxmitframe->attrib.mdata = 0;
6092 pxmitframe->attrib.triggered = 1;
6094 pxmitframe->attrib.qsel = 0x11;/* HIQ */
6096 rtl8723au_hal_xmitframe_enqueue(padapter,
6099 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
6100 spin_unlock_bh(&pxmitpriv->lock);
6108 int set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6110 const struct set_ch_parm *set_ch_parm;
6111 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6114 return H2C_PARAMETERS_ERROR;
6116 set_ch_parm = (struct set_ch_parm *)pbuf;
6118 DBG_8723A("%s(%s): ch:%u, bw:%u, ch_offset:%u\n", __func__,
6119 padapter->pnetdev->name, set_ch_parm->ch,
6120 set_ch_parm->bw, set_ch_parm->ch_offset);
6122 pmlmeext->cur_channel = set_ch_parm->ch;
6123 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
6124 pmlmeext->cur_bwmode = set_ch_parm->bw;
6126 set_channel_bwmode23a(padapter, set_ch_parm->ch,
6127 set_ch_parm->ch_offset, set_ch_parm->bw);
6132 int set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6134 const struct SetChannelPlan_param *setChannelPlan_param;
6135 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6138 return H2C_PARAMETERS_ERROR;
6140 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
6142 pmlmeext->max_chan_nums =
6143 init_channel_set(padapter, setChannelPlan_param->channel_plan,
6144 pmlmeext->channel_set);
6145 init_channel_list(padapter, pmlmeext->channel_set,
6146 pmlmeext->max_chan_nums, &pmlmeext->channel_list);
6151 int led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6153 struct LedBlink_param *ledBlink_param;
6156 return H2C_PARAMETERS_ERROR;
6158 ledBlink_param = (struct LedBlink_param *)pbuf;
6163 int set_csa_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6165 return H2C_REJECTED;
6168 /* TDLS_WRCR : write RCR DATA BIT */
6169 /* TDLS_SD_PTI : issue peer traffic indication */
6170 /* TDLS_CS_OFF : go back to the channel linked with AP,
6171 terminating channel switch procedure */
6172 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and
6174 /* TDLS_DONE_CH_SEN : channel sensing and report candidate channel */
6175 /* TDLS_OFF_CH : first time set channel to off channel */
6176 /* TDLS_BASE_CH : go back tp the channel linked with AP when set
6177 base channel as target channel */
6178 /* TDLS_P_OFF_CH : periodically go to off channel */
6179 /* TDLS_P_BASE_CH : periodically go back to base channel */
6180 /* TDLS_RS_RCR : restore RCR */
6181 /* TDLS_CKALV_PH1 : check alive timer phase1 */
6182 /* TDLS_CKALV_PH2 : check alive timer phase2 */
6183 /* TDLS_FREE_STA : free tdls sta */
6184 int tdls_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6186 return H2C_REJECTED;