1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 ******************************************************************************/
15 #define _RTW_MLME_EXT_C_
17 #include <osdep_service.h>
18 #include <drv_types.h>
20 #include <rtw_mlme_ext.h>
21 #include <wlan_bssdef.h>
22 #include <mlme_osdep.h>
23 #include <recv_osdep.h>
24 #include <linux/ieee80211.h>
25 #include <rtl8723a_hal.h>
27 static int OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
28 static int OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
29 static int OnProbeReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
30 static int OnProbeRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
31 static int DoReserved23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
32 static int OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
33 static int OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
34 static int OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
35 static int OnAuth23aClient23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
36 static int OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
37 static int OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
39 static int on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
40 static int OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
41 static int OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
42 static int OnAction23a_back23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
43 static int on_action_public23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
44 static int OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
45 static int OnAction23a_wmm(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
46 static int OnAction23a_p2p(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
48 static void issue_assocreq(struct rtw_adapter *padapter);
49 static void issue_probereq(struct rtw_adapter *padapter,
50 struct cfg80211_ssid *pssid, u8 *da);
51 static int issue_probereq_ex(struct rtw_adapter *padapter,
52 struct cfg80211_ssid *pssid,
53 u8 *da, int try_cnt, int wait_ms);
54 static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da,
55 u8 is_valid_p2p_probereq);
56 static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
57 unsigned short status);
58 static int issue_deauth_ex(struct rtw_adapter *padapter, u8 *da,
59 unsigned short reason, int try_cnt, int wait_ms);
60 static void start_clnt_assoc(struct rtw_adapter *padapter);
61 static void start_clnt_auth(struct rtw_adapter *padapter);
62 static void start_clnt_join(struct rtw_adapter *padapter);
63 static void start_create_ibss(struct rtw_adapter *padapter);
64 static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter,
65 struct recv_frame *precv_frame);
67 #ifdef CONFIG_8723AU_AP_MODE
68 static int OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
69 static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
70 struct sta_info *pstat, u16 pkt_type);
73 static struct mlme_handler mlme_sta_tbl[]={
74 {"OnAssocReq23a", &OnAssocReq23a},
75 {"OnAssocRsp23a", &OnAssocRsp23a},
76 {"OnReAssocReq", &OnAssocReq23a},
77 {"OnReAssocRsp", &OnAssocRsp23a},
78 {"OnProbeReq23a", &OnProbeReq23a},
79 {"OnProbeRsp23a", &OnProbeRsp23a},
81 /*----------------------------------------------------------
83 -----------------------------------------------------------*/
84 {"DoReserved23a", &DoReserved23a},
85 {"DoReserved23a", &DoReserved23a},
86 {"OnBeacon23a", &OnBeacon23a},
87 {"OnATIM", &OnAtim23a},
88 {"OnDisassoc23a", &OnDisassoc23a},
89 {"OnAuth23a", &OnAuth23aClient23a},
90 {"OnDeAuth23a", &OnDeAuth23a},
91 {"OnAction23a", &OnAction23a},
94 static struct action_handler OnAction23a_tbl[]={
95 {WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct23a},
96 {WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction23a_qos},
97 {WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction23a_dls},
98 {WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction23a_back23a},
99 {WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public23a},
100 {WLAN_CATEGORY_HT, "ACTION_HT", &OnAction23a_ht},
101 {WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved23a},
102 {WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction23a_wmm},
103 {WLAN_CATEGORY_VENDOR_SPECIFIC, "ACTION_P2P", &OnAction23a_p2p},
106 static u8 null_addr[ETH_ALEN]= {0, 0, 0, 0, 0, 0};
108 /**************************************************
109 OUI definitions for the vendor specific IE
110 ***************************************************/
111 unsigned char WMM_OUI23A[] = {0x00, 0x50, 0xf2, 0x02};
112 unsigned char WPS_OUI23A[] = {0x00, 0x50, 0xf2, 0x04};
113 unsigned char P2P_OUI23A[] = {0x50, 0x6F, 0x9A, 0x09};
114 unsigned char WFD_OUI23A[] = {0x50, 0x6F, 0x9A, 0x0A};
116 unsigned char WMM_INFO_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
117 unsigned char WMM_PARA_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
119 static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
121 /********************************************************
123 *********************************************************/
124 unsigned char MCS_rate_2R23A[16] = {
125 0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0,
126 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
127 unsigned char MCS_rate_1R23A[16] = {
128 0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0,
129 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
131 /********************************************************
132 ChannelPlan definitions
133 *********************************************************/
135 static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
136 /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
137 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
138 /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
139 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
140 /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
141 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
142 /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
143 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
144 /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
145 {{10, 11, 12, 13}, 4},
146 /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
150 static struct rt_channel_plan_5g RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
151 /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
153 /* 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 */
154 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
155 116, 120, 124, 128, 132, 136, 140}, 19},
156 /* 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 */
157 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
158 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
159 /* 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 */
160 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
161 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22},
162 /* 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */
163 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
164 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
165 /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
166 {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},
167 /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
168 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},
169 /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
170 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12},
171 /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
172 {{149, 153, 157, 161, 165}, 5},
173 /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
174 {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
175 /* 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 */
176 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
177 116, 136, 140, 149, 153, 157, 161, 165}, 20},
178 /* 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 */
179 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
180 116, 120, 124, 149, 153, 157, 161, 165}, 20},
181 /* 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 */
182 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
183 116, 120, 124, 128, 132, 136, 140}, 19},
184 /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
185 {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
186 /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
187 {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},
188 /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
189 {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149,
190 153, 157, 161, 165}, 15},
191 /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
192 {{56, 60, 64, 149, 153, 157, 161, 165}, 8},
194 /* Driver self defined for old channel plan Compatible,
195 Remember to modify if have new channel plan definition ===== */
196 /* 0x11, RT_CHANNEL_DOMAIN_5G_FCC */
197 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
198 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},
199 /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
200 {{36, 40, 44, 48}, 4},
201 /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
202 {{36, 40, 44, 48, 149, 153, 157, 161}, 8},
205 static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
206 /* 0x00 ~ 0x1F , Old Define ===== */
207 {0x02, 0x11}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
208 {0x02, 0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
209 {0x01, 0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
210 {0x01, 0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
211 {0x01, 0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
212 {0x03, 0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
213 {0x03, 0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
214 {0x01, 0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
215 {0x03, 0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
216 {0x03, 0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
217 {0x00, 0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
218 {0x02, 0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
219 {0x01, 0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
220 {0x02, 0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
221 {0x02, 0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
222 {0x02, 0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
223 {0x01, 0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
224 {0x02, 0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
225 {0x01, 0x12}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
226 {0x00, 0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
227 {0x02, 0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
228 {0x00, 0x12}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
229 {0x00, 0x13}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
230 {0x03, 0x12}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
231 {0x05, 0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
232 {0x02, 0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
233 {0x00, 0x00}, /* 0x1A, */
234 {0x00, 0x00}, /* 0x1B, */
235 {0x00, 0x00}, /* 0x1C, */
236 {0x00, 0x00}, /* 0x1D, */
237 {0x00, 0x00}, /* 0x1E, */
238 {0x05, 0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
239 /* 0x20 ~ 0x7F , New Define ===== */
240 {0x00, 0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
241 {0x01, 0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
242 {0x02, 0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
243 {0x03, 0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
244 {0x04, 0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
245 {0x02, 0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
246 {0x00, 0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
247 {0x03, 0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
248 {0x00, 0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
249 {0x00, 0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
250 {0x00, 0x00}, /* 0x2A, */
251 {0x00, 0x00}, /* 0x2B, */
252 {0x00, 0x00}, /* 0x2C, */
253 {0x00, 0x00}, /* 0x2D, */
254 {0x00, 0x00}, /* 0x2E, */
255 {0x00, 0x00}, /* 0x2F, */
256 {0x00, 0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
257 {0x00, 0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
258 {0x00, 0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
259 {0x00, 0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
260 {0x02, 0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
261 {0x00, 0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
262 {0x00, 0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
263 {0x03, 0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
264 {0x03, 0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
265 {0x02, 0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
266 {0x00, 0x00}, /* 0x3A, */
267 {0x00, 0x00}, /* 0x3B, */
268 {0x00, 0x00}, /* 0x3C, */
269 {0x00, 0x00}, /* 0x3D, */
270 {0x00, 0x00}, /* 0x3E, */
271 {0x00, 0x00}, /* 0x3F, */
272 {0x02, 0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
273 {0x03, 0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
276 static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE =
277 {0x03, 0x02}; /* use the conbination for max channel numbers */
279 static void dummy_event_callback(struct rtw_adapter *adapter, const u8 *pbuf)
283 static struct fwevent wlanevents[] =
285 {0, &dummy_event_callback}, /*0*/
293 {0, &rtw_survey_event_cb23a}, /*8*/
294 {sizeof (struct surveydone_event), &rtw_surveydone_event_callback23a},
295 {0, &rtw23a_joinbss_event_cb}, /*10*/
296 {sizeof(struct stassoc_event), &rtw_stassoc_event_callback23a},
297 {sizeof(struct stadel_event), &rtw_stadel_event_callback23a},
298 {0, &dummy_event_callback},
299 {0, &dummy_event_callback},
304 {0, &dummy_event_callback},
308 {0, &dummy_event_callback},
313 static void rtw_correct_TSF(struct rtw_adapter *padapter)
315 hw_var_set_correct_tsf(padapter);
319 rtw_update_TSF(struct mlme_ext_priv *pmlmeext, struct ieee80211_mgmt *mgmt)
321 pmlmeext->TSFValue = get_unaligned_le64(&mgmt->u.beacon.timestamp);
325 * Search the @param channel_num in given @param channel_set
326 * @ch_set: the given channel set
327 * @ch: the given channel number
329 * return the index of channel_num in channel_set, -1 if not found
331 int rtw_ch_set_search_ch23a(struct rt_channel_info *ch_set, const u32 ch)
335 for (i = 0; ch_set[i]. ChannelNum != 0; i++) {
336 if (ch == ch_set[i].ChannelNum)
340 if (i >= ch_set[i].ChannelNum)
345 /****************************************************************************
347 Following are the initialization functions for WiFi MLME
349 *****************************************************************************/
351 int init_hw_mlme_ext23a(struct rtw_adapter *padapter)
353 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
355 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
356 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
360 static void init_mlme_ext_priv23a_value(struct rtw_adapter *padapter)
362 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
363 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
364 unsigned char mixed_datarate[NumRates] = {
365 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
366 _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_,
367 _48M_RATE_, _54M_RATE_, 0xff};
368 unsigned char mixed_basicrate[NumRates] = {
369 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
370 _12M_RATE_, _24M_RATE_, 0xff,};
372 atomic_set(&pmlmeext->event_seq, 0);
373 /* reset to zero when disconnect at client mode */
374 pmlmeext->mgnt_seq = 0;
376 pmlmeext->cur_channel = padapter->registrypriv.channel;
377 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
378 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
382 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
384 memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
385 memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
387 if (pmlmeext->cur_channel > 14)
388 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
390 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
392 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
393 pmlmeext->sitesurvey_res.channel_idx = 0;
394 pmlmeext->sitesurvey_res.bss_cnt = 0;
395 pmlmeext->scan_abort = false;
397 pmlmeinfo->state = MSR_NOLINK;
398 pmlmeinfo->reauth_count = 0;
399 pmlmeinfo->reassoc_count = 0;
400 pmlmeinfo->link_count = 0;
401 pmlmeinfo->auth_seq = 0;
402 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
403 pmlmeinfo->key_index = 0;
406 pmlmeinfo->enc_algo = 0;
407 pmlmeinfo->authModeToggle = 0;
409 memset(pmlmeinfo->chg_txt, 0, 128);
411 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
412 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
414 pmlmeinfo->dialogToken = 0;
416 pmlmeext->action_public_rxseq = 0xffff;
417 pmlmeext->action_public_dialog_token = 0xff;
420 static int has_channel(struct rt_channel_info *channel_set,
421 u8 chanset_size, u8 chan) {
424 for (i = 0; i < chanset_size; i++) {
425 if (channel_set[i].ChannelNum == chan)
432 static void init_channel_list(struct rtw_adapter *padapter,
433 struct rt_channel_info *channel_set,
435 struct p2p_channels *channel_list)
437 struct p2p_oper_class_map op_class[] = {
438 { IEEE80211G, 81, 1, 13, 1, BW20 },
439 { IEEE80211G, 82, 14, 14, 1, BW20 },
440 { IEEE80211A, 115, 36, 48, 4, BW20 },
441 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
442 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
443 { IEEE80211A, 124, 149, 161, 4, BW20 },
444 { IEEE80211A, 125, 149, 169, 4, BW20 },
445 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
446 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
447 { -1, 0, 0, 0, 0, BW20 }
454 for (op = 0; op_class[op].op_class; op++) {
456 struct p2p_oper_class_map *o = &op_class[op];
457 struct p2p_reg_class *reg = NULL;
459 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
460 if (!has_channel(channel_set, chanset_size, ch))
463 if ((0 == padapter->registrypriv.ht_enable) &&
467 if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) &&
468 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
472 reg = &channel_list->reg_class[cla];
474 reg->reg_class = o->op_class;
477 reg->channel[reg->channels] = ch;
481 channel_list->reg_classes = cla;
484 static u8 init_channel_set(struct rtw_adapter *padapter, u8 cplan,
485 struct rt_channel_info *c_set)
488 u8 b5GBand = false, b2_4GBand = false;
489 u8 Index2G = 0, Index5G = 0;
491 memset(c_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM);
493 if (cplan >= RT_CHANNEL_DOMAIN_MAX &&
494 cplan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) {
495 DBG_8723A("ChannelPlan ID %x error !!!!!\n", cplan);
499 if (padapter->registrypriv.wireless_mode & WIRELESS_11G) {
501 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
502 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
504 Index2G = RTW_ChannelPlanMap[cplan].Index2G;
507 if (padapter->registrypriv.wireless_mode & WIRELESS_11A) {
509 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
510 Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
512 Index5G = RTW_ChannelPlanMap[cplan].Index5G;
516 for (i = 0; i < RTW_ChannelPlan2G[Index2G].Len; i++) {
517 c_set[ch_size].ChannelNum =
518 RTW_ChannelPlan2G[Index2G].Channel[i];
520 if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == cplan) ||
521 /* Channel 1~11 is active, and 12~14 is passive */
522 RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == cplan) {
523 if (c_set[ch_size].ChannelNum >= 1 &&
524 c_set[ch_size].ChannelNum <= 11)
525 c_set[ch_size].ScanType = SCAN_ACTIVE;
526 else if (c_set[ch_size].ChannelNum >= 12 &&
527 c_set[ch_size].ChannelNum <= 14)
528 c_set[ch_size].ScanType = SCAN_PASSIVE;
529 } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == cplan ||
530 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == cplan ||
531 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) {
532 /* channel 12~13, passive scan */
533 if (c_set[ch_size].ChannelNum <= 11)
534 c_set[ch_size].ScanType = SCAN_ACTIVE;
536 c_set[ch_size].ScanType = SCAN_PASSIVE;
538 c_set[ch_size].ScanType = SCAN_ACTIVE;
545 for (i = 0; i < RTW_ChannelPlan5G[Index5G].Len; i++) {
546 if (RTW_ChannelPlan5G[Index5G].Channel[i] <= 48 ||
547 RTW_ChannelPlan5G[Index5G].Channel[i] >= 149) {
548 c_set[ch_size].ChannelNum =
549 RTW_ChannelPlan5G[Index5G].Channel[i];
550 if (RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == cplan) {
551 /* passive scan for all 5G channels */
552 c_set[ch_size].ScanType =
555 c_set[ch_size].ScanType =
557 DBG_8723A("%s(): channel_set[%d].ChannelNum = "
558 "%d\n", __func__, ch_size,
559 c_set[ch_size].ChannelNum);
568 int init_mlme_ext_priv23a(struct rtw_adapter *padapter)
570 struct registry_priv *pregistrypriv = &padapter->registrypriv;
571 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
572 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
573 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
575 pmlmeext->padapter = padapter;
577 init_mlme_ext_priv23a_value(padapter);
578 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
580 init_mlme_ext_timer23a(padapter);
582 #ifdef CONFIG_8723AU_AP_MODE
583 init_mlme_ap_info23a(padapter);
586 pmlmeext->max_chan_nums = init_channel_set(padapter,
587 pmlmepriv->ChannelPlan,
588 pmlmeext->channel_set);
589 init_channel_list(padapter, pmlmeext->channel_set,
590 pmlmeext->max_chan_nums, &pmlmeext->channel_list);
592 pmlmeext->chan_scan_time = SURVEY_TO;
593 pmlmeext->mlmeext_init = true;
595 pmlmeext->active_keep_alive_check = true;
599 void free_mlme_ext_priv23a (struct mlme_ext_priv *pmlmeext)
601 struct rtw_adapter *padapter = pmlmeext->padapter;
606 if (padapter->bDriverStopped == true) {
607 del_timer_sync(&pmlmeext->survey_timer);
608 del_timer_sync(&pmlmeext->link_timer);
609 /* del_timer_sync(&pmlmeext->ADDBA_timer); */
614 _mgt_dispatcher23a(struct rtw_adapter *padapter, struct mlme_handler *ptable,
615 struct recv_frame *precv_frame)
617 struct sk_buff *skb = precv_frame->pkt;
618 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
621 /* receive the frames that ra(a1) is my address
622 or ra(a1) is bc address. */
623 if (!ether_addr_equal(hdr->addr1, myid(&padapter->eeprompriv))&&
624 !is_broadcast_ether_addr(hdr->addr1))
627 ptable->func(padapter, precv_frame);
631 void mgt_dispatcher23a(struct rtw_adapter *padapter,
632 struct recv_frame *precv_frame)
634 struct mlme_handler *ptable;
635 #ifdef CONFIG_8723AU_AP_MODE
636 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
637 #endif /* CONFIG_8723AU_AP_MODE */
638 struct sk_buff *skb = precv_frame->pkt;
639 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
640 struct sta_info *psta;
644 if (!ieee80211_is_mgmt(mgmt->frame_control))
647 /* receive the frames that ra(a1) is my address or ra(a1) is
649 if (!ether_addr_equal(mgmt->da, myid(&padapter->eeprompriv)) &&
650 !is_broadcast_ether_addr(mgmt->da))
653 ptable = mlme_sta_tbl;
655 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
659 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
660 ("Currently we do not support reserved sub-fr-type ="
666 psta = rtw_get_stainfo23a(&padapter->stapriv, mgmt->sa);
669 if (ieee80211_has_retry(mgmt->frame_control)) {
670 if (precv_frame->attrib.seq_num ==
671 psta->RxMgmtFrameSeqNum) {
672 /* drop the duplicate management frame */
673 DBG_8723A("Drop duplicate management frame "
674 "with seq_num = %d.\n",
675 precv_frame->attrib.seq_num);
679 psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num;
682 #ifdef CONFIG_8723AU_AP_MODE
684 case IEEE80211_STYPE_AUTH:
685 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
686 ptable->func = &OnAuth23a;
688 ptable->func = &OnAuth23aClient23a;
690 case IEEE80211_STYPE_ASSOC_REQ:
691 case IEEE80211_STYPE_REASSOC_REQ:
692 _mgt_dispatcher23a(padapter, ptable, precv_frame);
694 case IEEE80211_STYPE_PROBE_REQ:
695 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
696 _mgt_dispatcher23a(padapter, ptable, precv_frame);
698 _mgt_dispatcher23a(padapter, ptable, precv_frame);
700 case IEEE80211_STYPE_BEACON:
701 _mgt_dispatcher23a(padapter, ptable, precv_frame);
703 case IEEE80211_STYPE_ACTION:
704 /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) */
705 _mgt_dispatcher23a(padapter, ptable, precv_frame);
708 _mgt_dispatcher23a(padapter, ptable, precv_frame);
712 _mgt_dispatcher23a(padapter, ptable, precv_frame);
716 /****************************************************************************
718 Following are the callback functions for each subtype of the management frames
720 *****************************************************************************/
723 OnProbeReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
726 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
727 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
728 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
729 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
730 struct sk_buff *skb = precv_frame->pkt;
731 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
734 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
737 if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
738 !check_fwstate(pmlmepriv,
739 WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
742 if (unlikely(!ieee80211_is_probe_req(mgmt->frame_control))) {
743 printk(KERN_WARNING "%s: Received non probe request frame\n",
748 len -= offsetof(struct ieee80211_mgmt, u.probe_req.variable);
750 ie = cfg80211_find_ie(WLAN_EID_SSID, mgmt->u.probe_req.variable, len);
752 /* check (wildcard) SSID */
756 if ((ie[1] && memcmp(ie + 2, cur->Ssid.ssid, cur->Ssid.ssid_len)) ||
757 (ie[1] == 0 && pmlmeinfo->hidden_ssid_mode)) {
761 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
762 pmlmepriv->cur_network.join_res)
763 issue_probersp(padapter, mgmt->sa, false);
770 OnProbeRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
772 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
774 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
775 report_survey_event23a(padapter, precv_frame);
783 OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
786 struct sta_info *psta;
787 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
788 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
789 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
790 struct sta_priv *pstapriv = &padapter->stapriv;
791 struct sk_buff *skb = precv_frame->pkt;
792 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
793 int pkt_len = skb->len;
794 struct wlan_bssid_ex *pbss;
800 pie = mgmt->u.beacon.variable;
801 pie_len = pkt_len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
802 p = rtw_get_ie23a(pie, WLAN_EID_EXT_SUPP_RATES, &ielen, pie_len);
803 if (p && ielen > 0) {
804 if (p[1 + ielen] == 0x2D && p[2 + ielen] != 0x2D) {
805 /* Invalid value 0x2D is detected in Extended Supported
806 * Rates (ESR) IE. Try to fix the IE length to avoid
807 * failed Beacon parsing.
809 DBG_8723A("[WIFIDBG] Error in ESR IE is detected in "
810 "Beacon of BSSID: %pM. Fix the length of "
811 "ESR IE to avoid failed Beacon parsing.\n",
817 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
818 report_survey_event23a(padapter, precv_frame);
822 if (!ether_addr_equal(mgmt->bssid,
823 get_my_bssid23a(&pmlmeinfo->network)))
826 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
827 /* we should update current network before auth,
828 or some IE is wrong */
829 pbss = collect_bss_info(padapter, precv_frame);
831 update_network23a(&pmlmepriv->cur_network.network, pbss,
833 rtw_get_bcn_info23a(&pmlmepriv->cur_network);
837 /* check the vendor of the assoc AP */
838 pmlmeinfo->assoc_AP_vendor =
839 check_assoc_AP23a((u8 *)&mgmt->u.beacon, pkt_len -
840 offsetof(struct ieee80211_mgmt, u));
842 /* update TSF Value */
843 rtw_update_TSF(pmlmeext, mgmt);
846 start_clnt_auth(padapter);
851 if (((pmlmeinfo->state & 0x03) == MSR_AP) &&
852 (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
853 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
855 ret = rtw_check_bcn_info23a(padapter, mgmt, pkt_len);
856 if (ret != _SUCCESS) {
857 DBG_8723A_LEVEL(_drv_always_, "ap has changed, "
859 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress, 65535);
862 /* update WMM, ERP in the beacon */
863 /* todo: the timer is used instead of
864 the number of the beacon received */
865 if ((sta_rx_pkts(psta) & 0xf) == 0) {
866 /* DBG_8723A("update_bcn_info\n"); */
867 update_beacon23a_info(padapter, mgmt,
871 } else if ((pmlmeinfo->state&0x03) == MSR_ADHOC) {
872 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
874 /* update WMM, ERP in the beacon */
875 /* todo: the timer is used instead of the
876 number of the beacon received */
877 if ((sta_rx_pkts(psta) & 0xf) == 0) {
878 /* DBG_8723A("update_bcn_info\n"); */
879 update_beacon23a_info(padapter, mgmt,
883 /* allocate a new CAM entry for IBSS station */
884 cam_idx = allocate_fw_sta_entry23a(padapter);
885 if (cam_idx == NUM_STA)
888 /* get supported rate */
889 if (update_sta_support_rate23a(padapter, pie, pie_len,
891 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
895 /* update TSF Value */
896 rtw_update_TSF(pmlmeext, mgmt);
898 /* report sta add event */
899 report_add_sta_event23a(padapter, mgmt->sa,
909 #ifdef CONFIG_8723AU_AP_MODE
911 OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
913 static struct sta_info stat;
914 struct sta_info *pstat = NULL;
915 struct sta_priv *pstapriv = &padapter->stapriv;
916 struct security_priv *psecuritypriv = &padapter->securitypriv;
917 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
918 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
919 struct sk_buff *skb = precv_frame->pkt;
920 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
924 u16 auth_mode, seq, algorithm;
925 int status, len = skb->len;
927 if ((pmlmeinfo->state & 0x03) != MSR_AP)
930 DBG_8723A("+OnAuth23a\n");
934 auth_mode = psecuritypriv->dot11AuthAlgrthm;
936 pframe = mgmt->u.auth.variable;
937 len = skb->len - offsetof(struct ieee80211_mgmt, u.auth.variable);
939 seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
940 algorithm = le16_to_cpu(mgmt->u.auth.auth_alg);
942 DBG_8723A("auth alg =%x, seq =%X\n", algorithm, seq);
944 if (auth_mode == 2 &&
945 psecuritypriv->dot11PrivacyAlgrthm != WLAN_CIPHER_SUITE_WEP40 &&
946 psecuritypriv->dot11PrivacyAlgrthm != WLAN_CIPHER_SUITE_WEP104)
949 /* rx a shared-key auth but shared not enabled, or */
950 /* rx a open-system auth but shared-key is enabled */
951 if ((algorithm != WLAN_AUTH_OPEN && auth_mode == 0) ||
952 (algorithm == WLAN_AUTH_OPEN && auth_mode == 1)) {
953 DBG_8723A("auth rejected due to bad alg [alg =%d, auth_mib "
954 "=%d] %02X%02X%02X%02X%02X%02X\n",
955 algorithm, auth_mode,
956 sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
958 status = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
963 if (rtw_access_ctrl23a(padapter, sa) == false) {
964 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
968 pstat = rtw_get_stainfo23a(pstapriv, sa);
970 /* allocate a new one */
971 DBG_8723A("going to alloc stainfo for sa ="MAC_FMT"\n",
973 pstat = rtw_alloc_stainfo23a(pstapriv, sa, GFP_ATOMIC);
975 DBG_8723A(" Exceed the upper limit of supported "
977 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
981 pstat->state = WIFI_FW_AUTH_NULL;
984 /* pstat->flags = 0; */
985 /* pstat->capability = 0; */
987 spin_lock_bh(&pstapriv->asoc_list_lock);
988 if (!list_empty(&pstat->asoc_list)) {
989 list_del_init(&pstat->asoc_list);
990 pstapriv->asoc_list_cnt--;
991 if (pstat->expire_to > 0) {
992 /* TODO: STA re_auth within expire_to */
995 spin_unlock_bh(&pstapriv->asoc_list_lock);
998 /* TODO: STA re_auth and auth timeout */
1002 spin_lock_bh(&pstapriv->auth_list_lock);
1003 if (list_empty(&pstat->auth_list)) {
1004 list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
1005 pstapriv->auth_list_cnt++;
1007 spin_unlock_bh(&pstapriv->auth_list_lock);
1009 if (pstat->auth_seq == 0)
1010 pstat->expire_to = pstapriv->auth_to;
1012 if ((pstat->auth_seq + 1) != seq) {
1013 DBG_8723A("(1)auth rejected because out of seq [rx_seq =%d, "
1014 "exp_seq =%d]!\n", seq, pstat->auth_seq+1);
1015 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1019 if (algorithm == WLAN_AUTH_OPEN && (auth_mode == 0 || auth_mode == 2)) {
1021 pstat->state &= ~WIFI_FW_AUTH_NULL;
1022 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1023 pstat->expire_to = pstapriv->assoc_to;
1024 pstat->authalg = algorithm;
1026 DBG_8723A("(2)auth rejected because out of seq "
1027 "[rx_seq =%d, exp_seq =%d]!\n",
1028 seq, pstat->auth_seq+1);
1029 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1032 } else { /* shared system or auto authentication */
1034 /* prepare for the challenging txt... */
1035 pstat->state &= ~WIFI_FW_AUTH_NULL;
1036 pstat->state |= WIFI_FW_AUTH_STATE;
1037 pstat->authalg = algorithm;
1038 pstat->auth_seq = 2;
1039 } else if (seq == 3) {
1040 /* checking for challenging txt... */
1041 DBG_8723A("checking for challenging txt...\n");
1043 p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pframe, len);
1044 if (!p || p[1] <= 0) {
1045 DBG_8723A("auth rejected because challenge "
1047 status = WLAN_STATUS_CHALLENGE_FAIL;
1051 if (!memcmp(p + 2, pstat->chg_txt, 128)) {
1052 pstat->state &= ~WIFI_FW_AUTH_STATE;
1053 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1054 /* challenging txt is correct... */
1055 pstat->expire_to = pstapriv->assoc_to;
1057 DBG_8723A("auth rejected because challenge "
1059 status = WLAN_STATUS_CHALLENGE_FAIL;
1063 DBG_8723A("(3)auth rejected because out of seq "
1064 "[rx_seq =%d, exp_seq =%d]!\n",
1065 seq, pstat->auth_seq+1);
1066 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1071 /* Now, we are going to issue_auth... */
1072 pstat->auth_seq = seq + 1;
1074 issue_auth(padapter, pstat, WLAN_STATUS_SUCCESS);
1076 if (pstat->state & WIFI_FW_AUTH_SUCCESS)
1077 pstat->auth_seq = 0;
1084 rtw_free_stainfo23a(padapter, pstat);
1087 memset((char *)pstat, '\0', sizeof(stat));
1088 pstat->auth_seq = 2;
1089 ether_addr_copy(pstat->hwaddr, sa);
1091 issue_auth(padapter, pstat, (unsigned short)status);
1098 OnAuth23aClient23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1100 unsigned int seq, status, algthm;
1101 unsigned int go2asoc = 0;
1102 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1103 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1104 struct sk_buff *skb = precv_frame->pkt;
1105 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1108 int plen = skb->len;
1110 DBG_8723A("%s\n", __func__);
1112 /* check A1 matches or not */
1113 if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
1116 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
1119 pie = mgmt->u.auth.variable;
1120 plen -= offsetof(struct ieee80211_mgmt, u.auth.variable);
1122 algthm = le16_to_cpu(mgmt->u.auth.auth_alg);
1123 seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
1124 status = le16_to_cpu(mgmt->u.auth.status_code);
1127 DBG_8723A("clnt auth fail, status: %d\n", status);
1128 /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
1129 if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
1130 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1131 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1133 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
1134 /* pmlmeinfo->reauth_count = 0; */
1137 set_link_timer(pmlmeext, 1);
1142 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
1143 /* legendary shared system */
1144 p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pie, plen);
1147 /* DBG_8723A("marc: no challenge text?\n"); */
1151 memcpy((void *)(pmlmeinfo->chg_txt), p + 2, p[1]);
1152 pmlmeinfo->auth_seq = 3;
1153 issue_auth(padapter, NULL, 0);
1154 set_link_timer(pmlmeext, REAUTH_TO);
1161 } else if (seq == 4) {
1162 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1167 /* this is also illegal */
1168 /* DBG_8723A("marc: clnt auth failed due to illegal seq =%x\n",
1174 DBG_8723A_LEVEL(_drv_always_, "auth success, start assoc\n");
1175 start_clnt_assoc(padapter);
1181 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
1186 #ifdef CONFIG_8723AU_AP_MODE
1187 static int rtw_validate_vendor_specific_ies(const u8 *pos, int elen)
1191 /* first 3 bytes in vendor specific information element are the IEEE
1192 * OUI of the vendor. The following byte is used a vendor specific
1195 DBG_8723A("short vendor specific information element "
1196 "ignored (len =%i)\n", elen);
1200 oui = RTW_GET_BE24(pos);
1202 case WLAN_OUI_MICROSOFT:
1203 /* Microsoft/Wi-Fi information elements are further typed and
1206 case WLAN_OUI_TYPE_MICROSOFT_WPA:
1207 /* Microsoft OUI (00:50:F2) with OUI Type 1:
1208 * real WPA information element */
1210 case WLAN_OUI_TYPE_MICROSOFT_WMM:
1212 DBG_8723A("short WME information element "
1213 "ignored (len =%i)\n", elen);
1217 case WME_OUI_SUBTYPE_INFORMATION_ELEMENT:
1218 case WME_OUI_SUBTYPE_PARAMETER_ELEMENT:
1220 case WME_OUI_SUBTYPE_TSPEC_ELEMENT:
1223 DBG_8723A("unknown WME information element "
1224 "ignored (subtype =%d len =%i)\n",
1229 case WLAN_OUI_TYPE_MICROSOFT_WPS:
1230 /* Wi-Fi Protected Setup (WPS) IE */
1233 DBG_8723A("Unknown Microsoft information element "
1234 "ignored (type =%d len =%i)\n",
1242 case VENDOR_HT_CAPAB_OUI_TYPE:
1245 DBG_8723A("Unknown Broadcom information element "
1246 "ignored (type =%d len =%i)\n", pos[3], elen);
1252 DBG_8723A("unknown vendor specific information element "
1253 "ignored (vendor OUI %02x:%02x:%02x len =%i)\n",
1254 pos[0], pos[1], pos[2], elen);
1261 static int rtw_validate_frame_ies(const u8 *start, uint len)
1263 const u8 *pos = start;
1275 DBG_8723A("%s: IEEE 802.11 failed (id =%d elen =%d "
1276 "left =%i)\n", __func__, id, elen, left);
1282 case WLAN_EID_SUPP_RATES:
1283 case WLAN_EID_FH_PARAMS:
1284 case WLAN_EID_DS_PARAMS:
1285 case WLAN_EID_CF_PARAMS:
1287 case WLAN_EID_IBSS_PARAMS:
1288 case WLAN_EID_CHALLENGE:
1289 case WLAN_EID_ERP_INFO:
1290 case WLAN_EID_EXT_SUPP_RATES:
1292 case WLAN_EID_VENDOR_SPECIFIC:
1293 if (rtw_validate_vendor_specific_ies(pos, elen))
1297 case WLAN_EID_PWR_CAPABILITY:
1298 case WLAN_EID_SUPPORTED_CHANNELS:
1299 case WLAN_EID_MOBILITY_DOMAIN:
1300 case WLAN_EID_FAST_BSS_TRANSITION:
1301 case WLAN_EID_TIMEOUT_INTERVAL:
1302 case WLAN_EID_HT_CAPABILITY:
1303 case WLAN_EID_HT_OPERATION:
1306 DBG_8723A("%s IEEE 802.11 ignored unknown element "
1307 "(id =%d elen =%d)\n", __func__, id, elen);
1323 OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1325 #ifdef CONFIG_8723AU_AP_MODE
1326 u16 capab_info, listen_interval;
1327 struct sta_info *pstat;
1328 unsigned char reassoc;
1329 int i, wpa_ie_len, left;
1330 unsigned char supportRate[16];
1332 unsigned short status = WLAN_STATUS_SUCCESS;
1333 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1334 struct security_priv *psecuritypriv = &padapter->securitypriv;
1335 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1336 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1337 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
1338 struct sta_priv *pstapriv = &padapter->stapriv;
1339 struct sk_buff *skb = precv_frame->pkt;
1340 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1341 const u8 *pos, *p, *wpa_ie, *wps_ie;
1342 u8 *pframe = skb->data;
1343 uint pkt_len = skb->len;
1346 if ((pmlmeinfo->state & 0x03) != MSR_AP)
1349 left = pkt_len - sizeof(struct ieee80211_hdr_3addr);
1350 if (ieee80211_is_assoc_req(mgmt->frame_control)) {
1352 pos = mgmt->u.assoc_req.variable;
1353 left -= offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
1354 } else { /* WIFI_REASSOCREQ */
1356 pos = mgmt->u.reassoc_req.variable;
1357 left -= offsetof(struct ieee80211_mgmt, u.reassoc_req.variable);
1361 DBG_8723A("handle_assoc(reassoc =%d) - too short payload "
1362 "(len =%lu)\n", reassoc, (unsigned long)pkt_len);
1366 pstat = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1368 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1369 goto asoc_class2_error;
1372 /* These two are located at the same offsets whether it's an
1373 * assoc_req or a reassoc_req */
1374 capab_info = get_unaligned_le16(&mgmt->u.assoc_req.capab_info);
1376 get_unaligned_le16(&mgmt->u.assoc_req.listen_interval);
1378 DBG_8723A("%s\n", __func__);
1380 /* check if this stat has been successfully authenticated/assocated */
1381 if (!(pstat->state & WIFI_FW_AUTH_SUCCESS)) {
1382 if (!(pstat->state & WIFI_FW_ASSOC_SUCCESS)) {
1383 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1384 goto asoc_class2_error;
1386 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
1387 pstat->state |= WIFI_FW_ASSOC_STATE;
1390 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1391 pstat->state |= WIFI_FW_ASSOC_STATE;
1394 pstat->capability = capab_info;
1396 /* now parse all ieee802_11 ie to point to elems */
1398 if (rtw_validate_frame_ies(pos, left)) {
1399 DBG_8723A("STA " MAC_FMT " sent invalid association request\n",
1400 MAC_ARG(pstat->hwaddr));
1401 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1402 goto OnAssocReq23aFail;
1405 /* now we should check all the fields... */
1407 p = cfg80211_find_ie(WLAN_EID_SSID, pos, left);
1408 if (!p || p[1] == 0) {
1409 /* broadcast ssid, however it is not allowed in assocreq */
1410 DBG_8723A("STA " MAC_FMT " sent invalid association request "
1411 "lacking an SSID\n", MAC_ARG(pstat->hwaddr));
1412 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1413 goto OnAssocReq23aFail;
1415 /* check if ssid match */
1416 if (memcmp(p + 2, cur->Ssid.ssid, cur->Ssid.ssid_len))
1417 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1419 if (p[1] != cur->Ssid.ssid_len)
1420 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1423 if (status != WLAN_STATUS_SUCCESS)
1424 goto OnAssocReq23aFail;
1426 /* check if the supported rate is ok */
1427 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, pos, left);
1429 DBG_8723A("Rx a sta assoc-req which supported rate is "
1431 /* use our own rate set as statoin used */
1432 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
1433 /* supportRateNum = AP_BSSRATE_LEN; */
1435 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1436 goto OnAssocReq23aFail;
1438 memcpy(supportRate, p + 2, p[1]);
1439 supportRateNum = p[1];
1441 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, pos, left);
1443 if (supportRateNum <= sizeof(supportRate)) {
1444 memcpy(supportRate+supportRateNum, p + 2, p[1]);
1445 supportRateNum += p[1];
1450 /* todo: mask supportRate between AP & STA -> move to update raid */
1451 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
1453 /* update station supportRate */
1454 pstat->bssratelen = supportRateNum;
1455 memcpy(pstat->bssrateset, supportRate, supportRateNum);
1456 Update23aTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
1458 /* check RSN/WPA/WPS */
1459 pstat->dot8021xalg = 0;
1461 pstat->wpa_group_cipher = 0;
1462 pstat->wpa2_group_cipher = 0;
1463 pstat->wpa_pairwise_cipher = 0;
1464 pstat->wpa2_pairwise_cipher = 0;
1465 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
1467 wpa_ie = cfg80211_find_ie(WLAN_EID_RSN, pos, left);
1469 wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1470 WLAN_OUI_TYPE_MICROSOFT_WPA,
1473 int group_cipher = 0, pairwise_cipher = 0;
1475 wpa_ie_len = wpa_ie[1];
1476 if (psecuritypriv->wpa_psk & BIT(1)) {
1477 r = rtw_parse_wpa2_ie23a(wpa_ie, wpa_ie_len + 2,
1479 &pairwise_cipher, NULL);
1480 if (r == _SUCCESS) {
1481 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1482 pstat->wpa_psk |= BIT(1);
1484 pstat->wpa2_group_cipher = group_cipher &
1485 psecuritypriv->wpa2_group_cipher;
1486 pstat->wpa2_pairwise_cipher = pairwise_cipher &
1487 psecuritypriv->wpa2_pairwise_cipher;
1489 status = WLAN_STATUS_INVALID_IE;
1490 } else if (psecuritypriv->wpa_psk & BIT(0)) {
1491 r = rtw_parse_wpa_ie23a(wpa_ie, wpa_ie_len + 2,
1492 &group_cipher, &pairwise_cipher,
1494 if (r == _SUCCESS) {
1495 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1496 pstat->wpa_psk |= BIT(0);
1498 pstat->wpa_group_cipher = group_cipher &
1499 psecuritypriv->wpa_group_cipher;
1500 pstat->wpa_pairwise_cipher = pairwise_cipher &
1501 psecuritypriv->wpa_pairwise_cipher;
1503 status = WLAN_STATUS_INVALID_IE;
1508 if (wpa_ie && status == WLAN_STATUS_SUCCESS) {
1509 if (!pstat->wpa_group_cipher)
1510 status = WLAN_STATUS_INVALID_GROUP_CIPHER;
1512 if (!pstat->wpa_pairwise_cipher)
1513 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
1517 if (status != WLAN_STATUS_SUCCESS)
1518 goto OnAssocReq23aFail;
1520 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
1522 wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1523 WLAN_OUI_TYPE_MICROSOFT_WPS,
1528 DBG_8723A("STA included WPS IE in (Re)Association "
1529 "Request - assume WPS is used\n");
1530 pstat->flags |= WLAN_STA_WPS;
1532 DBG_8723A("STA did not include WPA/RSN IE in (Re)"
1533 "Association Request - possible WPS use\n");
1534 pstat->flags |= WLAN_STA_MAYBE_WPS;
1539 if (psecuritypriv->wpa_psk == 0) {
1540 DBG_8723A("STA " MAC_FMT ": WPA/RSN IE in association "
1541 "request, but AP don't support WPA/RSN\n",
1542 MAC_ARG(pstat->hwaddr));
1544 status = WLAN_STATUS_INVALID_IE;
1546 goto OnAssocReq23aFail;
1550 DBG_8723A("STA included WPS IE in (Re)Association "
1551 "Request - WPS is used\n");
1552 pstat->flags |= WLAN_STA_WPS;
1555 copy_len = ((wpa_ie_len + 2) > sizeof(pstat->wpa_ie)) ?
1556 sizeof(pstat->wpa_ie) : (wpa_ie_len + 2);
1560 memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len);
1563 /* check if there is WMM IE & support WWM-PS */
1564 pstat->flags &= ~WLAN_STA_WME;
1565 pstat->qos_option = 0;
1566 pstat->qos_info = 0;
1567 pstat->has_legacy_ac = true;
1568 pstat->uapsd_vo = 0;
1569 pstat->uapsd_vi = 0;
1570 pstat->uapsd_be = 0;
1571 pstat->uapsd_bk = 0;
1572 if (pmlmepriv->qos_option) {
1573 const u8 *end = pos + left;
1579 p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1580 WLAN_OUI_TYPE_MICROSOFT_WMM,
1583 pstat->flags |= WLAN_STA_WME;
1585 pstat->qos_option = 1;
1586 pstat->qos_info = *(p + 8);
1589 (pstat->qos_info >> 5) & 0x3;
1591 if ((pstat->qos_info & 0xf) != 0xf)
1592 pstat->has_legacy_ac = true;
1594 pstat->has_legacy_ac = false;
1596 if (pstat->qos_info & 0xf) {
1597 if (pstat->qos_info & BIT(0))
1598 pstat->uapsd_vo = BIT(0)|BIT(1);
1600 pstat->uapsd_vo = 0;
1602 if (pstat->qos_info & BIT(1))
1603 pstat->uapsd_vi = BIT(0)|BIT(1);
1605 pstat->uapsd_vi = 0;
1607 if (pstat->qos_info & BIT(2))
1608 pstat->uapsd_bk = BIT(0)|BIT(1);
1610 pstat->uapsd_bk = 0;
1612 if (pstat->qos_info & BIT(3))
1613 pstat->uapsd_be = BIT(0)|BIT(1);
1615 pstat->uapsd_be = 0;
1626 /* save HT capabilities in the sta object */
1627 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
1628 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pos, left);
1630 if (p && p[1] >= sizeof(struct ieee80211_ht_cap)) {
1631 pstat->flags |= WLAN_STA_HT;
1633 pstat->flags |= WLAN_STA_WME;
1635 memcpy(&pstat->htpriv.ht_cap, p + 2,
1636 sizeof(struct ieee80211_ht_cap));
1638 pstat->flags &= ~WLAN_STA_HT;
1640 if (!pmlmepriv->htpriv.ht_option && pstat->flags & WLAN_STA_HT){
1641 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1642 goto OnAssocReq23aFail;
1645 if (pstat->flags & WLAN_STA_HT &&
1646 (pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP ||
1647 pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) {
1648 DBG_8723A("HT: " MAC_FMT " tried to use TKIP with HT "
1649 "association\n", MAC_ARG(pstat->hwaddr));
1651 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
1652 /* goto OnAssocReq23aFail; */
1655 pstat->flags |= WLAN_STA_NONERP;
1656 for (i = 0; i < pstat->bssratelen; i++) {
1657 if ((pstat->bssrateset[i] & 0x7f) > 22) {
1658 pstat->flags &= ~WLAN_STA_NONERP;
1663 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1664 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
1666 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1668 if (status != WLAN_STATUS_SUCCESS)
1669 goto OnAssocReq23aFail;
1671 /* TODO: identify_proprietary_vendor_ie(); */
1672 /* Realtek proprietary IE */
1673 /* identify if this is Broadcom sta */
1674 /* identify if this is ralink sta */
1675 /* Customer proprietary IE */
1677 /* get a unique AID */
1678 if (pstat->aid > 0) {
1679 DBG_8723A(" old AID %d\n", pstat->aid);
1681 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
1682 if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
1685 if (pstat->aid > NUM_STA)
1686 pstat->aid = NUM_STA;
1687 if (pstat->aid > pstapriv->max_num_sta) {
1691 DBG_8723A(" no room for more AIDs\n");
1693 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1695 goto OnAssocReq23aFail;
1697 pstapriv->sta_aid[pstat->aid - 1] = pstat;
1698 DBG_8723A("allocate new AID = (%d)\n", pstat->aid);
1702 pstat->state &= ~WIFI_FW_ASSOC_STATE;
1703 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
1705 spin_lock_bh(&pstapriv->auth_list_lock);
1706 if (!list_empty(&pstat->auth_list)) {
1707 list_del_init(&pstat->auth_list);
1708 pstapriv->auth_list_cnt--;
1710 spin_unlock_bh(&pstapriv->auth_list_lock);
1712 spin_lock_bh(&pstapriv->asoc_list_lock);
1713 if (list_empty(&pstat->asoc_list)) {
1714 pstat->expire_to = pstapriv->expire_to;
1715 list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
1716 pstapriv->asoc_list_cnt++;
1718 spin_unlock_bh(&pstapriv->asoc_list_lock);
1720 /* now the station is qualified to join our BSS... */
1721 if (pstat && pstat->state & WIFI_FW_ASSOC_SUCCESS &&
1722 status == WLAN_STATUS_SUCCESS) {
1723 #ifdef CONFIG_8723AU_AP_MODE
1724 /* 1 bss_cap_update & sta_info_update23a */
1725 bss_cap_update_on_sta_join23a(padapter, pstat);
1726 sta_info_update23a(padapter, pstat);
1728 /* issue assoc rsp before notify station join event. */
1729 if (ieee80211_is_assoc_req(mgmt->frame_control))
1730 issue_assocrsp(padapter, status, pstat,
1731 IEEE80211_STYPE_ASSOC_RESP);
1733 issue_assocrsp(padapter, status, pstat,
1734 IEEE80211_STYPE_REASSOC_RESP);
1736 /* 2 - report to upper layer */
1737 DBG_8723A("indicate_sta_join_event to upper layer - hostapd\n");
1738 rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
1740 /* 3-(1) report sta add event */
1741 report_add_sta_event23a(padapter, pstat->hwaddr, pstat->aid);
1749 #ifdef CONFIG_8723AU_AP_MODE
1750 issue_deauth23a(padapter, mgmt->sa, status);
1756 #ifdef CONFIG_8723AU_AP_MODE
1758 if (ieee80211_is_assoc_req(mgmt->frame_control))
1759 issue_assocrsp(padapter, status, pstat,
1760 IEEE80211_STYPE_ASSOC_RESP);
1762 issue_assocrsp(padapter, status, pstat,
1763 IEEE80211_STYPE_REASSOC_RESP);
1766 #endif /* CONFIG_8723AU_AP_MODE */
1772 OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1774 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1775 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1776 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1777 struct sk_buff *skb = precv_frame->pkt;
1778 struct ieee80211_mgmt *pmgmt = (struct ieee80211_mgmt *) skb->data;
1780 unsigned short status;
1782 u8 *pframe = skb->data;
1783 int pkt_len = skb->len;
1786 DBG_8723A("%s\n", __func__);
1788 /* check A1 matches or not */
1789 if (!ether_addr_equal(myid(&padapter->eeprompriv), pmgmt->da))
1792 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
1795 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1798 del_timer_sync(&pmlmeext->link_timer);
1801 status = le16_to_cpu(pmgmt->u.assoc_resp.status_code);
1803 DBG_8723A("assoc reject, status code: %d\n", status);
1804 pmlmeinfo->state = MSR_NOLINK;
1806 goto report_assoc_result;
1809 /* get capabilities */
1810 pmlmeinfo->capability = le16_to_cpu(pmgmt->u.assoc_resp.capab_info);
1813 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
1816 res = pmlmeinfo->aid = le16_to_cpu(pmgmt->u.assoc_resp.aid) & 0x3fff;
1818 pie = pframe + offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
1820 offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
1822 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
1823 pmgmt->u.assoc_resp.variable, pielen);
1825 HT_caps_handler23a(padapter, p);
1827 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
1828 pmgmt->u.assoc_resp.variable, pielen);
1830 HT_info_handler23a(padapter, p);
1832 p = cfg80211_find_ie(WLAN_EID_ERP_INFO,
1833 pmgmt->u.assoc_resp.variable, pielen);
1835 ERP_IE_handler23a(padapter, p);
1837 pie = pframe + offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
1839 p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1840 WLAN_OUI_TYPE_MICROSOFT_WMM,
1841 pie, pframe + pkt_len - pie);
1846 /* if this IE is too short, try the next */
1849 /* if this IE is WMM params, we found what we wanted */
1855 WMM_param_handler23a(padapter, p);
1857 pmlmeinfo->state &= ~WIFI_FW_ASSOC_STATE;
1858 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
1860 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
1861 UpdateBrateTbl23a(padapter, pmlmeinfo->network.SupportedRates);
1863 report_assoc_result:
1864 pmlmepriv->assoc_rsp_len = 0;
1866 kfree(pmlmepriv->assoc_rsp);
1867 pmlmepriv->assoc_rsp = kmalloc(pkt_len, GFP_ATOMIC);
1868 if (pmlmepriv->assoc_rsp) {
1869 memcpy(pmlmepriv->assoc_rsp, pframe, pkt_len);
1870 pmlmepriv->assoc_rsp_len = pkt_len;
1873 kfree(pmlmepriv->assoc_rsp);
1875 report_join_res23a(padapter, res);
1881 OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1883 unsigned short reason;
1884 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1885 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1886 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1887 struct sk_buff *skb = precv_frame->pkt;
1888 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1890 if (!ether_addr_equal(mgmt->bssid,
1891 get_my_bssid23a(&pmlmeinfo->network)))
1894 reason = le16_to_cpu(mgmt->u.deauth.reason_code);
1896 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1898 #ifdef CONFIG_8723AU_AP_MODE
1899 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1900 struct sta_info *psta;
1901 struct sta_priv *pstapriv = &padapter->stapriv;
1903 DBG_8723A_LEVEL(_drv_always_, "ap recv deauth reason code(%d) "
1904 "sta:%pM\n", reason, mgmt->sa);
1906 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1910 spin_lock_bh(&pstapriv->asoc_list_lock);
1911 if (!list_empty(&psta->asoc_list)) {
1912 list_del_init(&psta->asoc_list);
1913 pstapriv->asoc_list_cnt--;
1914 updated = ap_free_sta23a(padapter, psta,
1917 spin_unlock_bh(&pstapriv->asoc_list_lock);
1919 associated_clients_update23a(padapter, updated);
1926 DBG_8723A_LEVEL(_drv_always_, "sta recv deauth reason code(%d) "
1927 "sta:%pM\n", reason, mgmt->bssid);
1929 receive_disconnect23a(padapter, mgmt->bssid, reason);
1931 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1937 OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1939 unsigned short reason;
1940 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1941 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1942 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1943 struct sk_buff *skb = precv_frame->pkt;
1944 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1946 if (!ether_addr_equal(mgmt->bssid,
1947 get_my_bssid23a(&pmlmeinfo->network)))
1950 reason = le16_to_cpu(mgmt->u.disassoc.reason_code);
1952 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1954 #ifdef CONFIG_8723AU_AP_MODE
1955 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1956 struct sta_info *psta;
1957 struct sta_priv *pstapriv = &padapter->stapriv;
1959 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason code(%d)"
1960 " sta:%pM\n", reason, mgmt->sa);
1962 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1966 spin_lock_bh(&pstapriv->asoc_list_lock);
1967 if (!list_empty(&psta->asoc_list)) {
1968 list_del_init(&psta->asoc_list);
1969 pstapriv->asoc_list_cnt--;
1970 updated = ap_free_sta23a(padapter, psta,
1973 spin_unlock_bh(&pstapriv->asoc_list_lock);
1975 associated_clients_update23a(padapter, updated);
1982 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason "
1983 "code(%d) sta:%pM\n", reason, mgmt->bssid);
1985 receive_disconnect23a(padapter, mgmt->bssid, reason);
1987 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1992 OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1994 DBG_8723A("%s\n", __func__);
1999 on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2005 OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2011 OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2016 static int OnAction23a_back23a(struct rtw_adapter *padapter,
2017 struct recv_frame *precv_frame)
2020 struct sta_info *psta = NULL;
2021 struct recv_reorder_ctrl *preorder_ctrl;
2022 unsigned char category, action;
2023 unsigned short tid, status, capab, params, reason_code = 0;
2024 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2025 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2026 struct sk_buff *skb = precv_frame->pkt;
2027 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
2028 struct sta_priv *pstapriv = &padapter->stapriv;
2030 /* check RA matches or not */
2031 if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
2034 DBG_8723A("%s\n", __func__);
2036 if ((pmlmeinfo->state&0x03) != MSR_AP)
2037 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
2041 psta = rtw_get_stainfo23a(pstapriv, addr);
2046 category = mgmt->u.action.category;
2047 if (category == WLAN_CATEGORY_BACK) { /* representing Block Ack */
2048 if (!pmlmeinfo->HT_enable)
2050 /* action_code is located in the same place for all
2051 action events, so pick any */
2052 action = mgmt->u.action.u.wme_action.action_code;
2053 DBG_8723A("%s, action =%d\n", __func__, action);
2055 case WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
2056 memcpy(&pmlmeinfo->ADDBA_req,
2057 &mgmt->u.action.u.addba_req.dialog_token,
2058 sizeof(struct ADDBA_request));
2059 process_addba_req23a(padapter,
2060 (u8 *)&pmlmeinfo->ADDBA_req, addr);
2061 if (pmlmeinfo->bAcceptAddbaReq == true)
2062 issue_action_BA23a(padapter, addr,
2063 WLAN_ACTION_ADDBA_RESP, 0);
2065 /* reject ADDBA Req */
2066 issue_action_BA23a(padapter, addr,
2067 WLAN_ACTION_ADDBA_RESP, 37);
2070 case WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
2071 status = get_unaligned_le16(
2072 &mgmt->u.action.u.addba_resp.status);
2073 capab = get_unaligned_le16(
2074 &mgmt->u.action.u.addba_resp.capab);
2075 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
2076 if (status == 0) { /* successful */
2077 DBG_8723A("agg_enable for TID =%d\n", tid);
2078 psta->htpriv.agg_enable_bitmap |= BIT(tid);
2079 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
2081 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
2084 case WLAN_ACTION_DELBA: /* DELBA */
2085 params = get_unaligned_le16(
2086 &mgmt->u.action.u.delba.params);
2089 if (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) {
2090 preorder_ctrl = &psta->recvreorder_ctrl[tid];
2091 preorder_ctrl->enable = false;
2092 preorder_ctrl->indicate_seq = 0xffff;
2094 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
2095 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
2097 reason_code = get_unaligned_le16(
2098 &mgmt->u.action.u.delba.reason_code);
2099 /* todo: how to notify the host while receiving
2109 static int on_action_public23a(struct rtw_adapter *padapter,
2110 struct recv_frame *precv_frame)
2112 struct sk_buff *skb = precv_frame->pkt;
2113 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2114 u8 *pframe = skb->data;
2117 /* check RA matches or not */
2118 if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
2121 channel = rtw_get_oper_ch23a(padapter);
2123 if (channel <= RTW_CH_MAX_2G_CHANNEL)
2124 freq = ieee80211_channel_to_frequency(channel,
2125 IEEE80211_BAND_2GHZ);
2127 freq = ieee80211_channel_to_frequency(channel,
2128 IEEE80211_BAND_5GHZ);
2130 if (cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, pframe,
2138 OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2144 OnAction23a_wmm(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2150 OnAction23a_p2p(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2156 OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2160 struct action_handler *ptable;
2161 struct sk_buff *skb = precv_frame->pkt;
2162 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
2164 category = mgmt->u.action.category;
2167 i < sizeof(OnAction23a_tbl) / sizeof(struct action_handler); i++) {
2168 ptable = &OnAction23a_tbl[i];
2170 if (category == ptable->num)
2171 ptable->func(padapter, precv_frame);
2177 static int DoReserved23a(struct rtw_adapter *padapter,
2178 struct recv_frame *precv_frame)
2183 struct xmit_frame *alloc_mgtxmitframe23a(struct xmit_priv *pxmitpriv)
2185 struct xmit_frame *pmgntframe;
2186 struct xmit_buf *pxmitbuf;
2188 pmgntframe = rtw_alloc_xmitframe23a_ext(pxmitpriv);
2191 DBG_8723A("%s(%s): alloc xmitframe fail\n", __func__,
2192 pxmitpriv->adapter->pnetdev->name);
2196 pxmitbuf = rtw_alloc_xmitbuf23a_ext(pxmitpriv);
2198 DBG_8723A("%s(%s): alloc xmitbuf fail\n", __func__,
2199 pxmitpriv->adapter->pnetdev->name);
2200 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
2205 pmgntframe->frame_tag = MGNT_FRAMETAG;
2206 pmgntframe->pxmitbuf = pxmitbuf;
2207 pmgntframe->buf_addr = pxmitbuf->pbuf;
2208 pxmitbuf->priv_data = pmgntframe;
2214 /****************************************************************************
2216 Following are some TX functions for WiFi MLME
2218 *****************************************************************************/
2220 void update_mgnt_tx_rate23a(struct rtw_adapter *padapter, u8 rate)
2222 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2224 pmlmeext->tx_rate = rate;
2225 DBG_8723A("%s(): rate = %x\n", __func__, rate);
2228 void update_mgntframe_attrib23a(struct rtw_adapter *padapter,
2229 struct pkt_attrib *pattrib)
2231 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2233 memset((u8 *)pattrib, 0, sizeof(struct pkt_attrib));
2235 pattrib->hdrlen = 24;
2236 pattrib->nr_frags = 1;
2237 pattrib->priority = 7;
2238 pattrib->mac_id = 0;
2239 pattrib->qsel = 0x12;
2241 pattrib->pktlen = 0;
2243 if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
2244 pattrib->raid = 6;/* b mode */
2246 pattrib->raid = 5;/* a/g mode */
2248 pattrib->encrypt = 0;
2249 pattrib->bswenc = false;
2251 pattrib->qos_en = false;
2252 pattrib->ht_en = false;
2253 pattrib->bwmode = HT_CHANNEL_WIDTH_20;
2254 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2255 pattrib->sgi = false;
2257 pattrib->seqnum = pmlmeext->mgnt_seq;
2259 pattrib->retry_ctrl = true;
2262 void dump_mgntframe23a(struct rtw_adapter *padapter,
2263 struct xmit_frame *pmgntframe)
2265 if (padapter->bSurpriseRemoved == true ||
2266 padapter->bDriverStopped == true)
2269 rtl8723au_mgnt_xmit(padapter, pmgntframe);
2272 int dump_mgntframe23a_and_wait(struct rtw_adapter *padapter,
2273 struct xmit_frame *pmgntframe, int timeout_ms)
2277 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2278 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
2279 struct submit_ctx sctx;
2281 if (padapter->bSurpriseRemoved == true ||
2282 padapter->bDriverStopped == true)
2285 rtw_sctx_init23a(&sctx, timeout_ms);
2286 pxmitbuf->sctx = &sctx;
2288 ret = rtl8723au_mgnt_xmit(padapter, pmgntframe);
2290 if (ret == _SUCCESS)
2291 ret = rtw_sctx_wait23a(&sctx);
2293 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
2294 pxmitbuf->sctx = NULL;
2295 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
2300 int dump_mgntframe23a_and_wait_ack23a(struct rtw_adapter *padapter,
2301 struct xmit_frame *pmgntframe)
2304 u32 timeout_ms = 500;/* 500ms */
2305 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2307 if (padapter->bSurpriseRemoved == true ||
2308 padapter->bDriverStopped == true)
2311 mutex_lock(&pxmitpriv->ack_tx_mutex);
2312 pxmitpriv->ack_tx = true;
2314 pmgntframe->ack_report = 1;
2315 if (rtl8723au_mgnt_xmit(padapter, pmgntframe) == _SUCCESS)
2316 ret = rtw_ack_tx_wait23a(pxmitpriv, timeout_ms);
2318 pxmitpriv->ack_tx = false;
2319 mutex_unlock(&pxmitpriv->ack_tx_mutex);
2324 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
2332 ssid_ie = rtw_get_ie23a(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
2334 /* DBG_8723A("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n",
2335 __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
2337 if (ssid_ie && ssid_len_ori > 0) {
2338 switch (hidden_ssid_mode) {
2340 next_ie = ssid_ie + 2 + ssid_len_ori;
2341 remain_len = ies_len -(next_ie-ies);
2344 memcpy(ssid_ie+2, next_ie, remain_len);
2345 len_diff -= ssid_len_ori;
2349 memset(&ssid_ie[2], 0, ssid_len_ori);
2359 void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
2361 struct xmit_frame *pmgntframe;
2362 struct pkt_attrib *pattrib;
2363 unsigned char *pframe;
2364 struct ieee80211_mgmt *mgmt;
2365 unsigned int rate_len;
2366 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2367 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2368 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2369 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2370 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2371 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2376 /* DBG_8723A("%s\n", __func__); */
2378 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2380 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2383 #ifdef CONFIG_8723AU_AP_MODE
2384 spin_lock_bh(&pmlmepriv->bcn_update_lock);
2387 /* update attribute */
2388 pattrib = &pmgntframe->attrib;
2389 update_mgntframe_attrib23a(padapter, pattrib);
2390 pattrib->qsel = 0x10;
2392 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2394 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2395 mgmt = (struct ieee80211_mgmt *)pframe;
2397 mgmt->frame_control =
2398 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
2401 ether_addr_copy(mgmt->da, bc_addr);
2402 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
2403 ether_addr_copy(mgmt->bssid, get_my_bssid23a(cur_network));
2405 /* timestamp will be inserted by hardware */
2407 put_unaligned_le16(cur_network->beacon_interval,
2408 &mgmt->u.beacon.beacon_int);
2410 put_unaligned_le16(cur_network->capability,
2411 &mgmt->u.beacon.capab_info);
2413 pframe = mgmt->u.beacon.variable;
2414 pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
2416 if ((pmlmeinfo->state & 0x03) == MSR_AP) {
2419 /* DBG_8723A("ie len =%d\n", cur_network->IELength); */
2420 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2421 len_diff = update_hidden_ssid(pframe, cur_network->IELength,
2422 pmlmeinfo->hidden_ssid_mode);
2423 pframe += (cur_network->IELength+len_diff);
2424 pattrib->pktlen += (cur_network->IELength+len_diff);
2426 iebuf = mgmt->u.beacon.variable;
2427 buflen = pattrib->pktlen -
2428 offsetof(struct ieee80211_mgmt, u.beacon.variable);
2429 wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
2430 WLAN_OUI_TYPE_MICROSOFT_WPS,
2433 if (wps_ie && wps_ie[1] > 0) {
2434 rtw_get_wps_attr_content23a(wps_ie, wps_ie[1],
2435 WPS_ATTR_SELECTED_REGISTRAR,
2439 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
2441 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
2447 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2448 cur_network->Ssid.ssid_len,
2449 cur_network->Ssid.ssid, &pattrib->pktlen);
2451 /* supported rates... */
2452 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2453 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2454 ((rate_len > 8)? 8: rate_len),
2455 cur_network->SupportedRates, &pattrib->pktlen);
2457 /* DS parameter set */
2458 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)
2459 &cur_network->DSConfig, &pattrib->pktlen);
2461 /* if ((pmlmeinfo->state&0x03) == MSR_ADHOC) */
2465 /* IBSS Parameter Set... */
2466 /* ATIMWindow = cur->ATIMWindow; */
2468 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2469 (unsigned char *)&ATIMWindow,
2473 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2474 &erpinfo, &pattrib->pktlen);
2477 /* EXTERNDED SUPPORTED RATE */
2479 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2481 cur_network->SupportedRates + 8,
2484 /* todo:HT for adhoc */
2488 #ifdef CONFIG_8723AU_AP_MODE
2489 pmlmepriv->update_bcn = false;
2491 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
2494 if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
2495 DBG_8723A("beacon frame too large\n");
2499 pattrib->last_txcmdsz = pattrib->pktlen;
2501 /* DBG_8723A("issue bcn_sz =%d\n", pattrib->last_txcmdsz); */
2503 dump_mgntframe23a_and_wait(padapter, pmgntframe, timeout_ms);
2505 dump_mgntframe23a(padapter, pmgntframe);
2508 static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da,
2509 u8 is_valid_p2p_probereq)
2511 struct xmit_frame *pmgntframe;
2512 struct pkt_attrib *pattrib;
2513 unsigned char *pframe;
2514 struct ieee80211_mgmt *mgmt;
2515 unsigned char *mac, *bssid;
2516 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2517 #ifdef CONFIG_8723AU_AP_MODE
2521 int ssid_ielen_diff;
2524 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2525 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2526 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2527 unsigned int rate_len;
2529 /* DBG_8723A("%s\n", __func__); */
2531 if (cur_network->IELength > MAX_IE_SZ)
2534 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2536 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2540 /* update attribute */
2541 pattrib = &pmgntframe->attrib;
2542 update_mgntframe_attrib23a(padapter, pattrib);
2544 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2546 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
2547 mgmt = (struct ieee80211_mgmt *)pframe;
2549 mac = myid(&padapter->eeprompriv);
2550 bssid = cur_network->MacAddress;
2552 mgmt->frame_control =
2553 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
2555 ether_addr_copy(mgmt->da, da);
2556 ether_addr_copy(mgmt->sa, mac);
2557 ether_addr_copy(mgmt->bssid, bssid);
2559 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
2560 pmlmeext->mgnt_seq++;
2562 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2564 /* timestamp will be inserted by hardware */
2565 put_unaligned_le16(cur_network->beacon_interval,
2566 &mgmt->u.probe_resp.beacon_int);
2568 put_unaligned_le16(cur_network->capability,
2569 &mgmt->u.probe_resp.capab_info);
2571 pframe = mgmt->u.probe_resp.variable;
2573 offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
2575 /* below for ad-hoc mode */
2577 #ifdef CONFIG_8723AU_AP_MODE
2578 if ((pmlmeinfo->state & 0x03) == MSR_AP) {
2579 pwps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
2580 WLAN_OUI_TYPE_MICROSOFT_WPS,
2582 cur_network->IELength);
2584 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2585 pframe += cur_network->IELength;
2586 pattrib->pktlen += cur_network->IELength;
2588 /* retrieve SSID IE from cur_network->Ssid */
2590 ssid_ie = rtw_get_ie23a(mgmt->u.probe_resp.variable,
2591 WLAN_EID_SSID, &ssid_ielen,
2592 pframe - mgmt->u.probe_resp.variable);
2594 ssid_ielen_diff = cur_network->Ssid.ssid_len - ssid_ielen;
2596 if (ssid_ie && cur_network->Ssid.ssid_len) {
2597 uint remainder_ielen;
2600 remainder_ie = ssid_ie + 2;
2602 remainder_ielen = pframe - remainder_ie;
2604 DBG_8723A_LEVEL(_drv_warning_, "%s(%s): "
2605 "remainder_ielen > MAX_IE_SZ\n",
2606 __func__, padapter->pnetdev->name);
2607 if (remainder_ielen > MAX_IE_SZ)
2608 remainder_ielen = MAX_IE_SZ;
2610 memcpy(buf, remainder_ie, remainder_ielen);
2611 memcpy(remainder_ie + ssid_ielen_diff, buf,
2613 *(ssid_ie + 1) = cur_network->Ssid.ssid_len;
2614 memcpy(ssid_ie + 2, cur_network->Ssid.ssid,
2615 cur_network->Ssid.ssid_len);
2617 pframe += ssid_ielen_diff;
2618 pattrib->pktlen += ssid_ielen_diff;
2624 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2625 cur_network->Ssid.ssid_len,
2626 cur_network->Ssid.ssid,
2629 /* supported rates... */
2630 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2631 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2632 ((rate_len > 8)? 8: rate_len),
2633 cur_network->SupportedRates,
2636 /* DS parameter set */
2637 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1,
2638 (unsigned char *)&cur_network->DSConfig,
2641 if ((pmlmeinfo->state & 0x03) == MSR_ADHOC) {
2644 /* IBSS Parameter Set... */
2645 /* ATIMWindow = cur->ATIMWindow; */
2647 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2648 (unsigned char *)&ATIMWindow,
2652 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2653 &erpinfo, &pattrib->pktlen);
2656 /* EXTERNDED SUPPORTED RATE */
2658 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2660 cur_network->SupportedRates + 8,
2663 /* todo:HT for adhoc */
2666 pattrib->last_txcmdsz = pattrib->pktlen;
2668 dump_mgntframe23a(padapter, pmgntframe);
2673 static int _issue_probereq(struct rtw_adapter *padapter,
2674 struct cfg80211_ssid *pssid, u8 *da, int wait_ack)
2677 struct xmit_frame *pmgntframe;
2678 struct pkt_attrib *pattrib;
2679 unsigned char *pframe;
2680 struct ieee80211_hdr *pwlanhdr;
2682 unsigned char bssrate[NumRates];
2683 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2684 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2685 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2686 int bssrate_len = 0;
2687 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2689 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2690 ("+%s\n", __func__));
2692 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2696 /* update attribute */
2697 pattrib = &pmgntframe->attrib;
2698 update_mgntframe_attrib23a(padapter, pattrib);
2700 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2702 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2703 pwlanhdr = (struct ieee80211_hdr *)pframe;
2705 mac = myid(&padapter->eeprompriv);
2707 pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2708 IEEE80211_STYPE_PROBE_REQ);
2711 /* unicast probe request frame */
2712 ether_addr_copy(pwlanhdr->addr1, da);
2713 ether_addr_copy(pwlanhdr->addr3, da);
2715 /* broadcast probe request frame */
2716 ether_addr_copy(pwlanhdr->addr1, bc_addr);
2717 ether_addr_copy(pwlanhdr->addr3, bc_addr);
2720 ether_addr_copy(pwlanhdr->addr2, mac);
2722 pwlanhdr->seq_ctrl =
2723 cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
2725 pmlmeext->mgnt_seq++;
2727 pframe += sizeof (struct ieee80211_hdr_3addr);
2728 pattrib->pktlen = sizeof (struct ieee80211_hdr_3addr);
2731 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, pssid->ssid_len,
2732 pssid->ssid, &pattrib->pktlen);
2734 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, 0, NULL,
2737 get_rate_set23a(padapter, bssrate, &bssrate_len);
2739 if (bssrate_len > 8) {
2740 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
2741 bssrate, &pattrib->pktlen);
2742 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2743 (bssrate_len - 8), (bssrate + 8),
2746 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2747 bssrate_len, bssrate, &pattrib->pktlen);
2750 /* add wps_ie for wps2.0 */
2751 if (pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie) {
2752 memcpy(pframe, pmlmepriv->wps_probe_req_ie,
2753 pmlmepriv->wps_probe_req_ie_len);
2754 pframe += pmlmepriv->wps_probe_req_ie_len;
2755 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
2758 pattrib->last_txcmdsz = pattrib->pktlen;
2760 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2761 ("issuing probe_req, tx_len =%d\n", pattrib->last_txcmdsz));
2764 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
2766 dump_mgntframe23a(padapter, pmgntframe);
2774 static inline void issue_probereq(struct rtw_adapter *padapter,
2775 struct cfg80211_ssid *pssid, u8 *da)
2777 _issue_probereq(padapter, pssid, da, false);
2780 static int issue_probereq_ex(struct rtw_adapter *padapter,
2781 struct cfg80211_ssid *pssid, u8 *da,
2782 int try_cnt, int wait_ms)
2786 unsigned long start = jiffies;
2789 ret = _issue_probereq(padapter, pssid, da,
2790 wait_ms > 0 ? true : false);
2794 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
2797 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
2800 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
2807 if (try_cnt && wait_ms) {
2809 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
2810 "in %u ms\n", __func__,
2811 padapter->pnetdev->name,
2812 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
2813 ret == _SUCCESS?", acked":"", i, try_cnt,
2814 jiffies_to_msecs(jiffies - start));
2816 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
2817 __func__, padapter->pnetdev->name,
2818 rtw_get_oper_ch23a(padapter),
2819 ret == _SUCCESS?", acked":"", i, try_cnt,
2820 jiffies_to_msecs(jiffies - start));
2826 /* if psta == NULL, indiate we are station(client) now... */
2827 static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
2828 unsigned short status)
2830 struct xmit_frame *pmgntframe;
2831 struct pkt_attrib *pattrib;
2832 unsigned char *pframe;
2833 struct ieee80211_mgmt *mgmt;
2836 int use_shared_key = 0;
2837 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2838 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2839 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2841 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2845 /* update attribute */
2846 pattrib = &pmgntframe->attrib;
2847 update_mgntframe_attrib23a(padapter, pattrib);
2849 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2851 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2852 mgmt = (struct ieee80211_mgmt *)pframe;
2854 mgmt->frame_control =
2855 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2856 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
2857 pmlmeext->mgnt_seq++;
2859 pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.auth.variable);
2861 if (psta) { /* for AP mode */
2862 #ifdef CONFIG_8723AU_AP_MODE
2863 unsigned short val16;
2865 ether_addr_copy(mgmt->da, psta->hwaddr);
2866 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
2867 ether_addr_copy(mgmt->bssid, myid(&padapter->eeprompriv));
2869 /* setting auth algo number */
2870 val16 = (u16)psta->authalg;
2872 if (status != WLAN_STATUS_SUCCESS)
2878 mgmt->u.auth.auth_alg = cpu_to_le16(val16);
2880 /* setting auth seq number */
2881 mgmt->u.auth.auth_transaction =
2882 cpu_to_le16((u16)psta->auth_seq);
2884 /* setting status code... */
2885 mgmt->u.auth.status_code = cpu_to_le16(status);
2887 pframe = mgmt->u.auth.variable;
2888 /* added challenging text... */
2889 if ((psta->auth_seq == 2) &&
2890 (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
2891 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
2892 psta->chg_txt, &pattrib->pktlen);
2895 struct ieee80211_mgmt *iv_mgmt;
2897 ether_addr_copy(mgmt->da, get_my_bssid23a(&pmlmeinfo->network));
2898 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
2899 ether_addr_copy(mgmt->bssid,
2900 get_my_bssid23a(&pmlmeinfo->network));
2902 /* setting auth algo number */
2903 /* 0:OPEN System, 1:Shared key */
2904 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
2906 auth_algo = WLAN_AUTH_SHARED_KEY;
2908 auth_algo = WLAN_AUTH_OPEN;
2910 /* DBG_8723A("%s auth_algo = %s auth_seq =%d\n", __func__,
2911 (pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED",
2912 pmlmeinfo->auth_seq); */
2914 /* setting IV for auth seq #3 */
2915 if ((pmlmeinfo->auth_seq == 3) &&
2916 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
2917 (use_shared_key == 1)) {
2918 u32 *piv = (u32 *)&mgmt->u.auth;
2920 iv_mgmt = (struct ieee80211_mgmt *)(pframe + 4);
2921 /* DBG_8723A("==> iv(%d), key_index(%d)\n",
2922 pmlmeinfo->iv, pmlmeinfo->key_index); */
2923 val32 = (pmlmeinfo->iv & 0x3fffffff) |
2924 (pmlmeinfo->key_index << 30);
2926 put_unaligned_le32(val32, piv);
2928 pattrib->pktlen += 4;
2930 pattrib->iv_len = IEEE80211_WEP_IV_LEN;
2934 iv_mgmt->u.auth.auth_alg = cpu_to_le16(auth_algo);
2936 /* setting auth seq number */
2937 iv_mgmt->u.auth.auth_transaction =
2938 cpu_to_le16(pmlmeinfo->auth_seq);
2940 /* setting status code... */
2941 iv_mgmt->u.auth.status_code = cpu_to_le16(status);
2943 pframe = iv_mgmt->u.auth.variable;
2945 /* then checking to see if sending challenging text... */
2946 if ((pmlmeinfo->auth_seq == 3) &&
2947 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
2948 (use_shared_key == 1)) {
2949 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
2953 mgmt->frame_control |=
2954 cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2956 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2958 pattrib->encrypt = WLAN_CIPHER_SUITE_WEP40;
2960 pattrib->icv_len = IEEE80211_WEP_ICV_LEN;
2962 pattrib->pktlen += pattrib->icv_len;
2966 pattrib->last_txcmdsz = pattrib->pktlen;
2968 rtw_wep_encrypt23a(padapter, pmgntframe);
2969 DBG_8723A("%s\n", __func__);
2970 dump_mgntframe23a(padapter, pmgntframe);
2975 #ifdef CONFIG_8723AU_AP_MODE
2976 static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
2977 struct sta_info *pstat, u16 pkt_type)
2979 struct xmit_frame *pmgntframe;
2980 struct ieee80211_mgmt *mgmt;
2981 struct pkt_attrib *pattrib;
2982 unsigned char *pframe;
2983 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2984 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2985 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2986 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2987 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
2989 u8 *ie = pnetwork->IEs;
2991 DBG_8723A("%s\n", __func__);
2993 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2997 /* update attribute */
2998 pattrib = &pmgntframe->attrib;
2999 update_mgntframe_attrib23a(padapter, pattrib);
3001 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3003 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3004 mgmt = (struct ieee80211_mgmt *)pframe;
3006 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | pkt_type);
3008 ether_addr_copy(mgmt->da, pstat->hwaddr);
3009 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
3010 ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
3012 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3014 pmlmeext->mgnt_seq++;
3016 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3018 offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
3020 mgmt->u.assoc_resp.capab_info = cpu_to_le16(pnetwork->capability);
3021 mgmt->u.assoc_resp.status_code = cpu_to_le16(status);
3022 mgmt->u.assoc_resp.aid = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
3024 pframe = mgmt->u.assoc_resp.variable;
3026 if (pstat->bssratelen <= 8) {
3027 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3028 pstat->bssratelen, pstat->bssrateset,
3031 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3032 pstat->bssrateset, &pattrib->pktlen);
3033 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3034 pstat->bssratelen - 8,
3035 pstat->bssrateset + 8, &pattrib->pktlen);
3038 if (pstat->flags & WLAN_STA_HT && pmlmepriv->htpriv.ht_option) {
3039 /* FILL HT CAP INFO IE */
3040 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
3041 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ie,
3042 pnetwork->IELength);
3044 memcpy(pframe, p, p[1] + 2);
3045 pframe += (p[1] + 2);
3046 pattrib->pktlen += (p[1] + 2);
3049 /* FILL HT ADD INFO IE */
3050 /* p = hostapd_eid_ht_operation(hapd, p); */
3051 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, ie,
3052 pnetwork->IELength);
3053 if (p && p[1] > 0) {
3054 memcpy(pframe, p, p[1] + 2);
3055 pframe += (p[1] + 2);
3056 pattrib->pktlen += (p[1] + 2);
3061 if (pstat->flags & WLAN_STA_WME && pmlmepriv->qos_option) {
3062 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02,
3066 for (p = ie; ; p += (ie_len + 2)) {
3067 p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p,
3068 pnetwork->IELength - (ie_len + 2));
3073 if (p && !memcmp(p + 2, WMM_PARA_IE, 6)) {
3074 memcpy(pframe, p, ie_len + 2);
3075 pframe += (ie_len + 2);
3076 pattrib->pktlen += (ie_len + 2);
3081 if (!p || ie_len == 0)
3086 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) {
3087 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3088 REALTEK_96B_IE, &pattrib->pktlen);
3091 pattrib->last_txcmdsz = pattrib->pktlen;
3093 dump_mgntframe23a(padapter, pmgntframe);
3097 static void issue_assocreq(struct rtw_adapter *padapter)
3100 struct xmit_frame *pmgntframe;
3101 struct pkt_attrib *pattrib;
3102 unsigned char *pframe;
3104 struct ieee80211_mgmt *mgmt;
3105 unsigned int i, j, index = 0;
3106 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
3107 struct registry_priv *pregpriv = &padapter->registrypriv;
3108 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3109 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3110 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3111 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3112 int bssrate_len = 0, sta_bssrate_len = 0, pie_len;
3115 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3119 /* update attribute */
3120 pattrib = &pmgntframe->attrib;
3121 update_mgntframe_attrib23a(padapter, pattrib);
3123 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3125 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
3126 mgmt = (struct ieee80211_mgmt *)pframe;
3128 mgmt->frame_control =
3129 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ);
3131 ether_addr_copy(mgmt->da, get_my_bssid23a(&pmlmeinfo->network));
3132 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
3133 ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
3135 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3136 pmlmeext->mgnt_seq++;
3139 put_unaligned_le16(pmlmeinfo->network.capability,
3140 &mgmt->u.assoc_req.capab_info);
3141 /* todo: listen interval for power saving */
3142 put_unaligned_le16(3, &mgmt->u.assoc_req.listen_interval);
3144 pframe = mgmt->u.assoc_req.variable;
3145 pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
3148 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
3149 pmlmeinfo->network.Ssid.ssid_len,
3150 pmlmeinfo->network.Ssid.ssid, &pattrib->pktlen);
3152 /* supported rate & extended supported rate */
3154 get_rate_set23a(padapter, sta_bssrate, &sta_bssrate_len);
3155 /* DBG_8723A("sta_bssrate_len =%d\n", sta_bssrate_len); */
3157 /* for JAPAN, channel 14 can only uses B Mode(CCK) */
3158 if (pmlmeext->cur_channel == 14)
3159 sta_bssrate_len = 4;
3161 /* for (i = 0; i < sta_bssrate_len; i++) { */
3162 /* DBG_8723A("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
3165 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3166 if (pmlmeinfo->network.SupportedRates[i] == 0)
3168 DBG_8723A("network.SupportedRates[%d]=%02X\n", i,
3169 pmlmeinfo->network.SupportedRates[i]);
3172 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3173 if (pmlmeinfo->network.SupportedRates[i] == 0)
3176 /* Check if the AP's supported rates are also
3177 supported by STA. */
3178 for (j = 0; j < sta_bssrate_len; j++) {
3179 /* Avoid the proprietary data rate (22Mbps) of
3180 Handlink WSG-4000 AP */
3181 if ((pmlmeinfo->network.SupportedRates[i] |
3182 IEEE80211_BASIC_RATE_MASK) ==
3183 (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
3184 /* DBG_8723A("match i = %d, j =%d\n", i, j); */
3189 if (j == sta_bssrate_len) {
3190 /* the rate is not supported by STA */
3191 DBG_8723A("%s(): the rate[%d]=%02X is not supported by "
3192 "STA!\n", __func__, i,
3193 pmlmeinfo->network.SupportedRates[i]);
3195 /* the rate is supported by STA */
3196 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
3200 bssrate_len = index;
3201 DBG_8723A("bssrate_len = %d\n", bssrate_len);
3203 if (bssrate_len == 0) {
3204 rtw_free_xmitbuf23a(pxmitpriv, pmgntframe->pxmitbuf);
3205 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
3206 goto exit; /* don't connect to AP if no joint supported rate */
3209 if (bssrate_len > 8) {
3210 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3211 bssrate, &pattrib->pktlen);
3212 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3213 (bssrate_len - 8), (bssrate + 8),
3216 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3217 bssrate_len, bssrate, &pattrib->pktlen);
3221 pie = pmlmeinfo->network.IEs;
3222 pie_len = pmlmeinfo->network.IELength;
3224 p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
3226 pframe = rtw_set_ie23a(pframe, WLAN_EID_RSN, p[1], p + 2,
3230 if (padapter->mlmepriv.htpriv.ht_option) {
3231 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, pie_len);
3233 if (p && !is_ap_in_tkip23a(padapter)) {
3234 struct ieee80211_ht_cap *cap = &pmlmeinfo->ht_cap;
3236 memcpy(cap, p + 2, sizeof(struct ieee80211_ht_cap));
3238 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
3239 if (pregpriv->cbw40_enable == 0) {
3240 cap->cap_info &= ~cpu_to_le16(
3241 IEEE80211_HT_CAP_SGI_40 |
3242 IEEE80211_HT_CAP_SUP_WIDTH_20_40);
3244 cap->cap_info |= cpu_to_le16(
3245 IEEE80211_HT_CAP_SUP_WIDTH_20_40);
3248 /* todo: disable SM power save mode */
3249 cap->cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SM_PS);
3251 rf_type = rtl8723a_get_rf_type(padapter);
3252 /* switch (pregpriv->rf_config) */
3255 /* RX STBC One spatial stream */
3256 if (pregpriv->rx_stbc)
3257 cap->cap_info |= cpu_to_le16(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3259 memcpy(&cap->mcs, MCS_rate_1R23A, 16);
3265 /* enable for 2.4/5 GHz */
3266 if (pregpriv->rx_stbc == 0x3 ||
3267 (pmlmeext->cur_wireless_mode &
3269 /* enable for 2.4GHz */
3270 pregpriv->rx_stbc == 0x1) ||
3271 (pmlmeext->cur_wireless_mode &
3273 pregpriv->rx_stbc == 0x2) ||
3274 /* enable for 5GHz */
3275 pregpriv->wifi_spec == 1) {
3276 DBG_8723A("declare supporting RX "
3278 /* RX STBC two spatial stream */
3279 cap->cap_info |= cpu_to_le16(2 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3281 memcpy(&cap->mcs, MCS_rate_2R23A, 16);
3285 if (rtl8723a_BT_coexist(padapter) &&
3286 rtl8723a_BT_using_antenna_1(padapter)) {
3288 cap->ampdu_params_info &=
3289 ~IEEE80211_HT_AMPDU_PARM_FACTOR;
3290 /* cap->ampdu_params_info |= MAX_AMPDU_FACTOR_8K */
3293 pframe = rtw_set_ie23a(pframe, WLAN_EID_HT_CAPABILITY,
3294 p[1], (u8 *)&pmlmeinfo->ht_cap,
3299 /* vendor specific IE, such as WPA, WMM, WPS */
3300 for (i = 0; i < pmlmeinfo->network.IELength;) {
3301 p = pmlmeinfo->network.IEs + i;
3304 case WLAN_EID_VENDOR_SPECIFIC:
3305 if (!memcmp(p + 2, RTW_WPA_OUI23A_TYPE, 4) ||
3306 !memcmp(p + 2, WMM_OUI23A, 4) ||
3307 !memcmp(p + 2, WPS_OUI23A, 4)) {
3310 if (!padapter->registrypriv.wifi_spec) {
3311 /* Commented by Kurt 20110629 */
3312 /* In some older APs, WPS handshake */
3313 /* would be fail if we append vender
3314 extensions informations to AP */
3315 if (!memcmp(p + 2, WPS_OUI23A, 4))
3318 pframe = rtw_set_ie23a(pframe,
3319 WLAN_EID_VENDOR_SPECIFIC,
3332 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
3333 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3334 REALTEK_96B_IE, &pattrib->pktlen);
3336 pattrib->last_txcmdsz = pattrib->pktlen;
3337 dump_mgntframe23a(padapter, pmgntframe);
3342 pmlmepriv->assoc_req_len = 0;
3343 if (ret == _SUCCESS) {
3344 kfree(pmlmepriv->assoc_req);
3345 pmlmepriv->assoc_req = kmalloc(pattrib->pktlen, GFP_ATOMIC);
3346 if (pmlmepriv->assoc_req) {
3347 memcpy(pmlmepriv->assoc_req, mgmt, pattrib->pktlen);
3348 pmlmepriv->assoc_req_len = pattrib->pktlen;
3351 kfree(pmlmepriv->assoc_req);
3356 /* when wait_ack is true, this function should be called at process context */
3357 static int _issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3358 unsigned int power_mode, int wait_ack)
3361 struct xmit_frame *pmgntframe;
3362 struct pkt_attrib *pattrib;
3363 unsigned char *pframe;
3364 struct ieee80211_hdr *pwlanhdr;
3365 struct xmit_priv *pxmitpriv;
3366 struct mlme_ext_priv *pmlmeext;
3367 struct mlme_ext_info *pmlmeinfo;
3369 /* DBG_8723A("%s:%d\n", __func__, power_mode); */
3374 pxmitpriv = &padapter->xmitpriv;
3375 pmlmeext = &padapter->mlmeextpriv;
3376 pmlmeinfo = &pmlmeext->mlmext_info;
3378 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3382 /* update attribute */
3383 pattrib = &pmgntframe->attrib;
3384 update_mgntframe_attrib23a(padapter, pattrib);
3385 pattrib->retry_ctrl = false;
3387 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3389 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3390 pwlanhdr = (struct ieee80211_hdr *)pframe;
3392 pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
3393 IEEE80211_STYPE_NULLFUNC);
3395 if ((pmlmeinfo->state&0x03) == MSR_AP)
3396 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
3397 else if ((pmlmeinfo->state&0x03) == MSR_INFRA)
3398 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_TODS);
3401 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
3403 ether_addr_copy(pwlanhdr->addr1, da);
3404 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3405 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3407 pwlanhdr->seq_ctrl =
3408 cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3409 pmlmeext->mgnt_seq++;
3411 pframe += sizeof(struct ieee80211_hdr_3addr);
3412 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3414 pattrib->last_txcmdsz = pattrib->pktlen;
3417 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3419 dump_mgntframe23a(padapter, pmgntframe);
3427 /* when wait_ms >0 , this function should be called at process context */
3428 /* da == NULL for station mode */
3429 int issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3430 unsigned int power_mode, int try_cnt, int wait_ms)
3434 unsigned long start = jiffies;
3435 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3436 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3438 /* da == NULL, assume it's null data for sta to ap*/
3440 da = get_my_bssid23a(&pmlmeinfo->network);
3443 ret = _issue_nulldata23a(padapter, da, power_mode,
3444 wait_ms > 0 ? true : false);
3448 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3451 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3454 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3461 if (try_cnt && wait_ms) {
3463 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3464 "in %u ms\n", __func__,
3465 padapter->pnetdev->name,
3466 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3467 ret == _SUCCESS?", acked":"", i, try_cnt,
3468 jiffies_to_msecs(jiffies - start));
3470 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3471 __func__, padapter->pnetdev->name,
3472 rtw_get_oper_ch23a(padapter),
3473 ret == _SUCCESS?", acked":"", i, try_cnt,
3474 jiffies_to_msecs(jiffies - start));
3480 /* when wait_ack is true, this function should be called at process context */
3481 static int _issue_qos_nulldata23a(struct rtw_adapter *padapter,
3482 unsigned char *da, u16 tid, int wait_ack)
3485 struct xmit_frame *pmgntframe;
3486 struct pkt_attrib *pattrib;
3487 unsigned char *pframe;
3488 struct ieee80211_qos_hdr *pwlanhdr;
3489 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3490 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3491 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3493 DBG_8723A("%s\n", __func__);
3495 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3499 /* update attribute */
3500 pattrib = &pmgntframe->attrib;
3501 update_mgntframe_attrib23a(padapter, pattrib);
3503 pattrib->hdrlen += 2;
3504 pattrib->qos_en = true;
3506 pattrib->ack_policy = 0;
3509 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3511 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3512 pwlanhdr = (struct ieee80211_qos_hdr *)pframe;
3514 pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
3515 IEEE80211_STYPE_QOS_NULLFUNC);
3517 if ((pmlmeinfo->state&0x03) == MSR_AP)
3518 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
3519 else if ((pmlmeinfo->state&0x03) == MSR_INFRA)
3520 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_TODS);
3523 pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
3525 pwlanhdr->qos_ctrl = cpu_to_le16(tid & IEEE80211_QOS_CTL_TID_MASK);
3526 pwlanhdr->qos_ctrl |= cpu_to_le16((pattrib->ack_policy << 5) &
3527 IEEE80211_QOS_CTL_ACK_POLICY_MASK);
3529 pwlanhdr->qos_ctrl |= cpu_to_le16(IEEE80211_QOS_CTL_EOSP);
3531 ether_addr_copy(pwlanhdr->addr1, da);
3532 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3533 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3535 pwlanhdr->seq_ctrl =
3536 cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3537 pmlmeext->mgnt_seq++;
3539 pframe += sizeof(struct ieee80211_qos_hdr);
3540 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
3542 pattrib->last_txcmdsz = pattrib->pktlen;
3545 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3547 dump_mgntframe23a(padapter, pmgntframe);
3555 /* when wait_ms >0 , this function should be called at process context */
3556 /* da == NULL for station mode */
3557 int issue_qos_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3558 u16 tid, int try_cnt, int wait_ms)
3562 unsigned long start = jiffies;
3563 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3564 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3566 /* da == NULL, assume it's null data for sta to ap*/
3568 da = get_my_bssid23a(&pmlmeinfo->network);
3571 ret = _issue_qos_nulldata23a(padapter, da, tid,
3572 wait_ms > 0 ? true : false);
3576 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3579 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3581 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3588 if (try_cnt && wait_ms) {
3590 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3591 "in %u ms\n", __func__,
3592 padapter->pnetdev->name,
3593 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3594 ret == _SUCCESS?", acked":"", i, try_cnt,
3595 jiffies_to_msecs(jiffies - start));
3597 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3598 __func__, padapter->pnetdev->name,
3599 rtw_get_oper_ch23a(padapter),
3600 ret == _SUCCESS?", acked":"", i, try_cnt,
3601 jiffies_to_msecs(jiffies - start));
3607 static int _issue_deauth(struct rtw_adapter *padapter, unsigned char *da,
3608 unsigned short reason, u8 wait_ack)
3610 struct xmit_frame *pmgntframe;
3611 struct pkt_attrib *pattrib;
3612 struct ieee80211_mgmt *mgmt;
3613 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3614 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3615 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3618 /* DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
3620 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3624 /* update attribute */
3625 pattrib = &pmgntframe->attrib;
3626 update_mgntframe_attrib23a(padapter, pattrib);
3627 pattrib->retry_ctrl = false;
3629 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3631 mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
3633 mgmt->frame_control =
3634 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH);
3636 ether_addr_copy(mgmt->da, da);
3637 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
3638 ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
3640 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3641 pmlmeext->mgnt_seq++;
3643 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr) + 2;
3645 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
3647 pattrib->last_txcmdsz = pattrib->pktlen;
3650 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3652 dump_mgntframe23a(padapter, pmgntframe);
3660 int issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
3661 unsigned short reason)
3663 DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
3664 return _issue_deauth(padapter, da, reason, false);
3667 static int issue_deauth_ex(struct rtw_adapter *padapter, u8 *da,
3668 unsigned short reason, int try_cnt, int wait_ms)
3672 unsigned long start = jiffies;
3675 ret = _issue_deauth(padapter, da, reason,
3676 wait_ms >0 ? true : false);
3680 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3683 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3686 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3693 if (try_cnt && wait_ms) {
3695 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3696 "in %u ms\n", __func__,
3697 padapter->pnetdev->name,
3698 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3699 ret == _SUCCESS?", acked":"", i, try_cnt,
3700 jiffies_to_msecs(jiffies - start));
3702 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3703 __func__, padapter->pnetdev->name,
3704 rtw_get_oper_ch23a(padapter),
3705 ret == _SUCCESS?", acked":"", i, try_cnt,
3706 jiffies_to_msecs(jiffies - start));
3712 void issue_action_spct_ch_switch23a(struct rtw_adapter *padapter,
3713 u8 *ra, u8 new_ch, u8 ch_offset)
3715 struct xmit_frame *pmgntframe;
3716 struct pkt_attrib *pattrib;
3717 unsigned char *pframe;
3718 struct ieee80211_mgmt *mgmt;
3719 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3720 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3722 DBG_8723A("%s(%s): ra ="MAC_FMT", ch:%u, offset:%u\n", __func__,
3723 padapter->pnetdev->name, MAC_ARG(ra), new_ch, ch_offset);
3725 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3729 /* update attribute */
3730 pattrib = &pmgntframe->attrib;
3731 update_mgntframe_attrib23a(padapter, pattrib);
3733 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3735 mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
3737 mgmt->frame_control =
3738 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
3740 ether_addr_copy(mgmt->da, ra); /* RA */
3741 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv)); /* TA */
3742 ether_addr_copy(mgmt->bssid, ra); /* DA = RA */
3744 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3745 pmlmeext->mgnt_seq++;
3747 mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
3748 mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH;
3750 pframe = mgmt->u.action.u.chan_switch.variable;
3751 pattrib->pktlen = offsetof(struct ieee80211_mgmt,
3752 u.action.u.chan_switch.variable);
3754 pframe = rtw_set_ie23a_ch_switch (pframe, &pattrib->pktlen, 0,
3756 pframe = rtw_set_ie23a_secondary_ch_offset(pframe, &pattrib->pktlen,
3757 hal_ch_offset_to_secondary_ch_offset23a(ch_offset));
3759 pattrib->last_txcmdsz = pattrib->pktlen;
3761 dump_mgntframe23a(padapter, pmgntframe);
3764 void issue_action_BA23a(struct rtw_adapter *padapter,
3765 const unsigned char *raddr,
3766 unsigned char action, unsigned short status)
3770 u16 BA_timeout_value;
3771 u16 BA_starting_seqctrl;
3773 int max_rx_ampdu_factor;
3774 struct xmit_frame *pmgntframe;
3775 struct pkt_attrib *pattrib;
3776 struct ieee80211_mgmt *mgmt;
3777 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3778 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3779 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3780 struct sta_info *psta;
3781 struct sta_priv *pstapriv = &padapter->stapriv;
3782 struct registry_priv *pregpriv = &padapter->registrypriv;
3783 u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
3785 DBG_8723A("%s, action =%d, status =%d\n", __func__, action, status);
3787 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3791 /* update attribute */
3792 pattrib = &pmgntframe->attrib;
3793 update_mgntframe_attrib23a(padapter, pattrib);
3795 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3797 mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
3799 mgmt->frame_control =
3800 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
3802 ether_addr_copy(mgmt->da, raddr);
3803 ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
3804 ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
3806 mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
3807 pmlmeext->mgnt_seq++;
3809 mgmt->u.action.category = WLAN_CATEGORY_BACK;
3811 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr) + 1;
3813 status = cpu_to_le16(status);
3816 case WLAN_ACTION_ADDBA_REQ:
3817 pattrib->pktlen += sizeof(mgmt->u.action.u.addba_req);
3819 mgmt->u.action.u.addba_req.action_code = action;
3822 pmlmeinfo->dialogToken++;
3823 } while (pmlmeinfo->dialogToken == 0);
3825 mgmt->u.action.u.addba_req.dialog_token =
3826 pmlmeinfo->dialogToken;
3828 if (rtl8723a_BT_coexist(padapter) &&
3829 rtl8723a_BT_using_antenna_1(padapter) &&
3830 (pmlmeinfo->assoc_AP_vendor != broadcomAP ||
3831 memcmp(raddr, tendaAPMac, 3))) {
3832 /* A-MSDU NOT Supported */
3834 /* immediate Block Ack */
3835 BA_para_set |= (1 << 1) &
3836 IEEE80211_ADDBA_PARAM_POLICY_MASK;
3838 BA_para_set |= (status << 2) &
3839 IEEE80211_ADDBA_PARAM_TID_MASK;
3840 /* max buffer size is 8 MSDU */
3841 BA_para_set |= (8 << 6) &
3842 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3844 /* immediate ack & 64 buffer size */
3845 BA_para_set = (0x1002 | ((status & 0xf) << 2));
3848 put_unaligned_le16(BA_para_set,
3849 &mgmt->u.action.u.addba_req.capab);
3851 BA_timeout_value = 5000;/* 5ms */
3852 BA_timeout_value = cpu_to_le16(BA_timeout_value);
3853 put_unaligned_le16(BA_timeout_value,
3854 &mgmt->u.action.u.addba_req.timeout);
3856 psta = rtw_get_stainfo23a(pstapriv, raddr);
3860 idx = status & 0x07;
3862 (psta->sta_xmitpriv.txseq_tid[idx] & 0xfff) + 1;
3864 DBG_8723A("BA_starting_seqctrl = %d for TID =%d\n",
3867 psta->BA_starting_seqctrl[idx] = start_seq;
3869 BA_starting_seqctrl = start_seq << 4;
3871 BA_starting_seqctrl = 0;
3873 put_unaligned_le16(BA_starting_seqctrl,
3874 &mgmt->u.action.u.addba_req.start_seq_num);
3878 case WLAN_ACTION_ADDBA_RESP:
3879 pattrib->pktlen += sizeof(mgmt->u.action.u.addba_resp);
3881 mgmt->u.action.u.addba_resp.action_code = action;
3882 mgmt->u.action.u.addba_resp.dialog_token =
3883 pmlmeinfo->ADDBA_req.dialog_token;
3884 put_unaligned_le16(status,
3885 &mgmt->u.action.u.addba_resp.status);
3887 GetHalDefVar8192CUsb(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
3888 &max_rx_ampdu_factor);
3890 BA_para = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f;
3891 if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_64K)
3892 BA_para_set = BA_para | 0x1000; /* 64 buffer size */
3893 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_32K)
3894 BA_para_set = BA_para | 0x0800; /* 32 buffer size */
3895 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_16K)
3896 BA_para_set = BA_para | 0x0400; /* 16 buffer size */
3897 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_8K)
3898 BA_para_set = BA_para | 0x0200; /* 8 buffer size */
3900 BA_para_set = BA_para | 0x1000; /* 64 buffer size */
3902 if (rtl8723a_BT_coexist(padapter) &&
3903 rtl8723a_BT_using_antenna_1(padapter) &&
3904 (pmlmeinfo->assoc_AP_vendor != broadcomAP ||
3905 memcmp(raddr, tendaAPMac, 3))) {
3906 /* max buffer size is 8 MSDU */
3907 BA_para_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3908 BA_para_set |= (8 << 6) &
3909 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3912 if (pregpriv->ampdu_amsdu == 0)/* disabled */
3913 BA_para_set &= ~BIT(0);
3914 else if (pregpriv->ampdu_amsdu == 1)/* enabled */
3915 BA_para_set |= BIT(0);
3917 put_unaligned_le16(BA_para_set,
3918 &mgmt->u.action.u.addba_resp.capab);
3920 put_unaligned_le16(pmlmeinfo->ADDBA_req.BA_timeout_value,
3921 &mgmt->u.action.u.addba_resp.timeout);
3923 pattrib->pktlen += 8;
3925 case WLAN_ACTION_DELBA:
3926 pattrib->pktlen += sizeof(mgmt->u.action.u.delba);
3928 mgmt->u.action.u.delba.action_code = action;
3929 BA_para_set = (status & 0x1F) << 3;
3930 mgmt->u.action.u.delba.params = cpu_to_le16(BA_para_set);
3931 mgmt->u.action.u.delba.reason_code =
3932 cpu_to_le16(WLAN_REASON_QSTA_NOT_USE);
3934 pattrib->pktlen += 5;
3940 pattrib->last_txcmdsz = pattrib->pktlen;
3942 dump_mgntframe23a(padapter, pmgntframe);
3945 int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr)
3947 struct sta_priv *pstapriv = &padapter->stapriv;
3948 struct sta_info *psta = NULL;
3949 /* struct recv_reorder_ctrl *preorder_ctrl; */
3950 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3951 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3954 if ((pmlmeinfo->state&0x03) != MSR_AP)
3955 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3958 psta = rtw_get_stainfo23a(pstapriv, addr);
3962 if (initiator == 0) { /* recipient */
3963 for (tid = 0; tid < MAXTID; tid++) {
3964 if (psta->recvreorder_ctrl[tid].enable == true) {
3965 DBG_8723A("rx agg disable tid(%d)\n", tid);
3966 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
3967 psta->recvreorder_ctrl[tid].enable = false;
3968 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
3971 } else if (initiator == 1) { /* originator */
3972 for (tid = 0; tid < MAXTID; tid++) {
3973 if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
3974 DBG_8723A("tx agg disable tid(%d)\n", tid);
3975 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
3976 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3977 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
3985 int send_beacon23a(struct rtw_adapter *padapter)
3990 unsigned long start = jiffies;
3991 unsigned int passing_time;
3993 rtl8723a_bcn_valid(padapter);
3995 issue_beacon23a(padapter, 100);
3999 bxmitok = rtl8723a_get_bcn_valid(padapter);
4001 } while ((poll % 10) != 0 && !bxmitok &&
4002 !padapter->bSurpriseRemoved &&
4003 !padapter->bDriverStopped);
4005 } while (!bxmitok && issue<100 && !padapter->bSurpriseRemoved &&
4006 !padapter->bDriverStopped);
4008 if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
4011 passing_time = jiffies_to_msecs(jiffies - start);
4014 DBG_8723A("%s fail! %u ms\n", __func__, passing_time);
4018 if (passing_time > 100 || issue > 3)
4019 DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n",
4020 __func__, issue, poll, passing_time);
4025 /****************************************************************************
4027 Following are some utitity functions for WiFi MLME
4029 *****************************************************************************/
4031 bool IsLegal5GChannel(struct rtw_adapter *Adapter, u8 channel)
4035 u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
4036 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
4037 114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
4038 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
4040 for (i = 0; i < sizeof(Channel_5G); i++)
4041 if (channel == Channel_5G[i])
4046 static void rtw_site_survey(struct rtw_adapter *padapter)
4048 unsigned char survey_channel = 0;
4049 enum rt_scan_type ScanType = SCAN_PASSIVE;
4050 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4051 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4052 struct rtw_ieee80211_channel *ch;
4054 if (pmlmeext->sitesurvey_res.channel_idx <
4055 pmlmeext->sitesurvey_res.ch_num) {
4056 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
4057 survey_channel = ch->hw_value;
4058 ScanType = (ch->flags & IEEE80211_CHAN_NO_IR) ?
4059 SCAN_PASSIVE : SCAN_ACTIVE;
4062 if (survey_channel != 0) {
4063 /* PAUSE 4-AC Queue when site_survey */
4064 if (pmlmeext->sitesurvey_res.channel_idx == 0)
4065 set_channel_bwmode23a(padapter, survey_channel,
4066 HAL_PRIME_CHNL_OFFSET_DONT_CARE,
4067 HT_CHANNEL_WIDTH_20);
4069 SelectChannel23a(padapter, survey_channel);
4071 if (ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */
4075 for (i = 0;i<RTW_SSID_SCAN_AMOUNT;i++) {
4076 if (pmlmeext->sitesurvey_res.ssid[i].ssid_len) {
4077 /* todo: to issue two probe req??? */
4078 issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4079 /* msleep(SURVEY_TO>>1); */
4080 issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4084 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
4085 /* todo: to issue two probe req??? */
4086 issue_probereq(padapter, NULL, NULL);
4087 /* msleep(SURVEY_TO>>1); */
4088 issue_probereq(padapter, NULL, NULL);
4092 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
4094 /* channel number is 0 or this channel is not valid. */
4095 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
4097 /* switch back to the original channel */
4099 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
4100 pmlmeext->cur_ch_offset,
4101 pmlmeext->cur_bwmode);
4103 /* flush 4-AC Queue after rtw_site_survey */
4107 rtl8723a_set_media_status(padapter, pmlmeinfo->state & 0x3);
4109 /* restore RX GAIN */
4110 rtl8723a_set_initial_gain(padapter, 0xff);
4111 /* turn on dynamic functions */
4112 rtl8723a_odm_support_ability_restore(padapter);
4114 if (is_client_associated_to_ap23a(padapter) == true)
4115 issue_nulldata23a(padapter, NULL, 0, 3, 500);
4117 rtl8723a_mlme_sitesurvey(padapter, 0);
4119 report_surveydone_event23a(padapter);
4121 pmlmeext->chan_scan_time = SURVEY_TO;
4122 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
4128 /* collect bss info from Beacon and Probe request/response frames. */
4129 static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter,
4130 struct recv_frame *precv_frame)
4132 struct sk_buff *skb = precv_frame->pkt;
4133 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
4134 struct registry_priv *pregistrypriv = &padapter->registrypriv;
4135 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4136 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4137 struct wlan_bssid_ex *bssid;
4140 unsigned int length;
4145 bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
4149 if (ieee80211_is_beacon(mgmt->frame_control)) {
4150 length -= offsetof(struct ieee80211_mgmt, u.beacon.variable);
4151 pie = mgmt->u.beacon.variable;
4152 bssid->reserved = 1;
4154 get_unaligned_le16(&mgmt->u.beacon.capab_info);
4155 bssid->beacon_interval =
4156 get_unaligned_le16(&mgmt->u.beacon.beacon_int);
4157 bssid->tsf = get_unaligned_le64(&mgmt->u.beacon.timestamp);
4158 } else if (ieee80211_is_probe_req(mgmt->frame_control)) {
4159 length -= offsetof(struct ieee80211_mgmt, u.probe_req.variable);
4160 pie = mgmt->u.probe_req.variable;
4161 bssid->reserved = 2;
4162 bssid->capability = 0;
4163 bssid->beacon_interval =
4164 padapter->registrypriv.dev_network.beacon_interval;
4166 } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4168 offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
4169 pie = mgmt->u.probe_resp.variable;
4170 bssid->reserved = 3;
4172 get_unaligned_le16(&mgmt->u.probe_resp.capab_info);
4173 bssid->beacon_interval =
4174 get_unaligned_le16(&mgmt->u.probe_resp.beacon_int);
4175 bssid->tsf = get_unaligned_le64(&mgmt->u.probe_resp.timestamp);
4177 length -= offsetof(struct ieee80211_mgmt, u.beacon.variable);
4178 pie = mgmt->u.beacon.variable;
4179 bssid->reserved = 0;
4181 get_unaligned_le16(&mgmt->u.beacon.capab_info);
4182 bssid->beacon_interval =
4183 padapter->registrypriv.dev_network.beacon_interval;
4187 if (length > MAX_IE_SZ) {
4188 /* DBG_8723A("IE too long for survey event\n"); */
4193 bssid->Length = offsetof(struct wlan_bssid_ex, IEs) + length;
4195 /* below is to copy the information element */
4196 bssid->IELength = length;
4197 memcpy(bssid->IEs, pie, bssid->IELength);
4199 /* get the signal strength */
4200 /* in dBM.raw data */
4201 bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower;
4202 bssid->SignalQuality =
4203 precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
4204 bssid->SignalStrength =
4205 precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
4208 p = cfg80211_find_ie(WLAN_EID_SSID, bssid->IEs, bssid->IELength);
4211 DBG_8723A("marc: cannot find SSID for survey event\n");
4215 if (p[1] > IEEE80211_MAX_SSID_LEN) {
4216 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4217 "event\n", __func__, __LINE__, p[1]);
4220 memcpy(bssid->Ssid.ssid, p + 2, p[1]);
4221 bssid->Ssid.ssid_len = p[1];
4223 /* checking rate info... */
4225 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, bssid->IEs, bssid->IELength);
4227 if (p[1] > NDIS_802_11_LENGTH_RATES_EX) {
4228 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4229 "event\n", __func__, __LINE__, p[1]);
4232 memcpy(bssid->SupportedRates, p + 2, p[1]);
4236 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, bssid->IEs,
4239 if (p[1] > (NDIS_802_11_LENGTH_RATES_EX-i)) {
4240 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4241 "event\n", __func__, __LINE__, p[1]);
4244 memcpy(bssid->SupportedRates + i, p + 2, p[1]);
4247 /* Checking for DSConfig */
4248 p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bssid->IEs, bssid->IELength);
4250 bssid->DSConfig = 0;
4253 bssid->DSConfig = p[2];
4254 } else {/* In 5G, some ap do not have DSSET IE */
4255 /* checking HT info for channel */
4256 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, bssid->IEs,
4259 struct ieee80211_ht_operation *HT_info =
4260 (struct ieee80211_ht_operation *)(p + 2);
4261 bssid->DSConfig = HT_info->primary_chan;
4262 } else /* use current channel */
4263 bssid->DSConfig = rtw_get_oper_ch23a(padapter);
4266 if (ieee80211_is_probe_req(mgmt->frame_control)) {
4268 bssid->ifmode = NL80211_IFTYPE_STATION;
4269 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4274 if (bssid->capability & WLAN_CAPABILITY_ESS) {
4275 bssid->ifmode = NL80211_IFTYPE_STATION;
4276 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4278 bssid->ifmode = NL80211_IFTYPE_ADHOC;
4279 ether_addr_copy(bssid->MacAddress, mgmt->bssid);
4282 if (bssid->capability & WLAN_CAPABILITY_PRIVACY)
4287 bssid->ATIMWindow = 0;
4289 /* 20/40 BSS Coexistence check */
4290 if (pregistrypriv->wifi_spec == 1 &&
4291 pmlmeinfo->bwmode_updated == false) {
4292 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4294 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, bssid->IEs,
4296 if (p && p[1] > 0) {
4297 struct ieee80211_ht_cap *pHT_caps;
4299 pHT_caps = (struct ieee80211_ht_cap *)(p + 2);
4301 if (pHT_caps->cap_info &
4302 cpu_to_le16(IEEE80211_HT_CAP_40MHZ_INTOLERANT))
4303 pmlmepriv->num_FortyMHzIntolerant++;
4305 pmlmepriv->num_sta_no_ht++;
4309 /* mark bss info receiving from nearby channel as SignalQuality 101 */
4310 if (bssid->DSConfig != rtw_get_oper_ch23a(padapter))
4311 bssid->SignalQuality = 101;
4319 static void start_create_ibss(struct rtw_adapter *padapter)
4321 unsigned short caps;
4322 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4323 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4324 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4326 pmlmeext->cur_channel = (u8)pnetwork->DSConfig;
4327 pmlmeinfo->bcn_interval = pnetwork->beacon_interval;
4329 /* update wireless mode */
4330 update_wireless_mode23a(padapter);
4332 /* update capability */
4333 caps = pnetwork->capability;
4334 update_capinfo23a(padapter, caps);
4335 if (caps & WLAN_CAPABILITY_IBSS) { /* adhoc master */
4336 rtl8723a_set_sec_cfg(padapter, 0xcf);
4338 /* switch channel */
4339 /* SelectChannel23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
4340 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4342 rtl8723a_SetBeaconRelatedRegisters(padapter);
4344 /* set msr to MSR_ADHOC */
4345 pmlmeinfo->state = MSR_ADHOC;
4346 rtl8723a_set_media_status(padapter, pmlmeinfo->state & 0x3);
4349 if (send_beacon23a(padapter) == _FAIL) {
4350 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("issuing beacon frame fail....\n"));
4352 report_join_res23a(padapter, -1);
4353 pmlmeinfo->state = MSR_NOLINK;
4355 hw_var_set_bssid(padapter, padapter->registrypriv.dev_network.MacAddress);
4356 hw_var_set_mlme_join(padapter, 0);
4358 report_join_res23a(padapter, 1);
4359 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
4362 DBG_8723A("%s: invalid cap:%x\n", __func__, caps);
4367 static void start_clnt_join(struct rtw_adapter *padapter)
4369 unsigned short caps;
4371 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4372 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4373 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4376 pmlmeext->cur_channel = (u8)pnetwork->DSConfig;
4377 pmlmeinfo->bcn_interval = pnetwork->beacon_interval;
4379 /* update wireless mode */
4380 update_wireless_mode23a(padapter);
4382 /* update capability */
4383 caps = pnetwork->capability;
4384 update_capinfo23a(padapter, caps);
4385 if (caps & WLAN_CAPABILITY_ESS) {
4386 /* switch channel */
4387 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4389 rtl8723a_set_media_status(padapter, MSR_INFRA);
4391 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ?
4394 rtl8723a_set_sec_cfg(padapter, val8);
4396 /* switch channel */
4397 /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
4399 /* here wait for receiving the beacon to start auth */
4400 /* and enable a timer */
4401 beacon_timeout = decide_wait_for_beacon_timeout23a(pmlmeinfo->bcn_interval);
4402 set_link_timer(pmlmeext, beacon_timeout);
4403 mod_timer(&padapter->mlmepriv.assoc_timer, jiffies +
4404 msecs_to_jiffies((REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout));
4405 pmlmeinfo->state = WIFI_FW_AUTH_NULL | MSR_INFRA;
4406 } else if (caps & WLAN_CAPABILITY_IBSS) { /* adhoc client */
4407 rtl8723a_set_media_status(padapter, MSR_ADHOC);
4409 rtl8723a_set_sec_cfg(padapter, 0xcf);
4411 /* switch channel */
4412 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4414 rtl8723a_SetBeaconRelatedRegisters(padapter);
4416 pmlmeinfo->state = MSR_ADHOC;
4418 report_join_res23a(padapter, 1);
4420 /* DBG_8723A("marc: invalid cap:%x\n", caps); */
4425 static void start_clnt_auth(struct rtw_adapter *padapter)
4427 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4428 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4430 del_timer_sync(&pmlmeext->link_timer);
4432 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
4433 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
4435 pmlmeinfo->auth_seq = 1;
4436 pmlmeinfo->reauth_count = 0;
4437 pmlmeinfo->reassoc_count = 0;
4438 pmlmeinfo->link_count = 0;
4439 pmlmeext->retry = 0;
4441 /* Because of AP's not receiving deauth before */
4442 /* AP may: 1)not response auth or 2)deauth us after link is complete */
4443 /* issue deauth before issuing auth to deal with the situation */
4444 /* Commented by Albert 2012/07/21 */
4445 /* For the Win8 P2P connection, it will be hard to have a
4446 successful connection if this Wi-Fi doesn't connect to it. */
4447 issue_deauth23a(padapter, (&pmlmeinfo->network)->MacAddress,
4448 WLAN_REASON_DEAUTH_LEAVING);
4450 DBG_8723A_LEVEL(_drv_always_, "start auth\n");
4451 issue_auth(padapter, NULL, 0);
4453 set_link_timer(pmlmeext, REAUTH_TO);
4456 static void start_clnt_assoc(struct rtw_adapter *padapter)
4458 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4459 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4461 del_timer_sync(&pmlmeext->link_timer);
4463 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
4464 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
4466 issue_assocreq(padapter);
4468 set_link_timer(pmlmeext, REASSOC_TO);
4471 int receive_disconnect23a(struct rtw_adapter *padapter,
4472 unsigned char *MacAddr, unsigned short reason)
4474 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4475 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4478 if (!ether_addr_equal(MacAddr, get_my_bssid23a(&pmlmeinfo->network)))
4481 DBG_8723A("%s\n", __func__);
4483 if ((pmlmeinfo->state&0x03) == MSR_INFRA) {
4484 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
4485 pmlmeinfo->state = MSR_NOLINK;
4486 report_del_sta_event23a(padapter, MacAddr, reason);
4488 } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) {
4489 pmlmeinfo->state = MSR_NOLINK;
4490 report_join_res23a(padapter, -2);
4497 static void process_80211d(struct rtw_adapter *padapter,
4498 struct wlan_bssid_ex *bssid)
4500 struct registry_priv *pregistrypriv;
4501 struct mlme_ext_priv *pmlmeext;
4502 struct rt_channel_info *chplan_new;
4506 pregistrypriv = &padapter->registrypriv;
4507 pmlmeext = &padapter->mlmeextpriv;
4509 /* Adjust channel plan by AP Country IE */
4510 if (pregistrypriv->enable80211d &&
4511 !pmlmeext->update_channel_plan_by_ap_done) {
4513 struct rt_channel_plan chplan_ap;
4514 struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
4516 u8 fcn; /* first channel number */
4517 u8 noc; /* number of channel */
4520 ie = cfg80211_find_ie(WLAN_EID_COUNTRY, bssid->IEs,
4522 if (!ie || ie[1] < IEEE80211_COUNTRY_IE_MIN_LEN)
4529 memcpy(country, p, 3);
4533 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4534 ("%s: 802.11d country =%s\n", __func__, country));
4537 while ((ie - p) >= 3) {
4542 for (j = 0; j < noc; j++) {
4544 channel = fcn + j; /* 2.4 GHz */
4546 channel = fcn + j * 4; /* 5 GHz */
4548 chplan_ap.Channel[i++] = channel;
4553 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
4554 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
4555 chplan_new = pmlmeext->channel_set;
4558 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
4560 if (i == MAX_CHANNEL_NUM ||
4561 chplan_sta[i].ChannelNum == 0 ||
4562 chplan_sta[i].ChannelNum > 14)
4565 if (j == chplan_ap.Len ||
4566 chplan_ap.Channel[j] > 14)
4569 if (chplan_sta[i].ChannelNum ==
4570 chplan_ap.Channel[j]) {
4571 chplan_new[k].ChannelNum =
4572 chplan_ap.Channel[j];
4573 chplan_new[k].ScanType = SCAN_ACTIVE;
4577 } else if (chplan_sta[i].ChannelNum <
4578 chplan_ap.Channel[j]) {
4579 chplan_new[k].ChannelNum =
4580 chplan_sta[i].ChannelNum;
4581 chplan_new[k].ScanType =
4585 } else if (chplan_sta[i].ChannelNum >
4586 chplan_ap.Channel[j]) {
4587 chplan_new[k].ChannelNum =
4588 chplan_ap.Channel[j];
4589 chplan_new[k].ScanType =
4596 /* change AP not support channel to Passive scan */
4597 while (i < MAX_CHANNEL_NUM &&
4598 chplan_sta[i].ChannelNum != 0 &&
4599 chplan_sta[i].ChannelNum <= 14) {
4600 chplan_new[k].ChannelNum =
4601 chplan_sta[i].ChannelNum;
4602 chplan_new[k].ScanType = SCAN_PASSIVE;
4607 /* add channel AP supported */
4608 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14){
4609 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4610 chplan_new[k].ScanType = SCAN_ACTIVE;
4615 /* keep original STA 2.4G channel plan */
4616 while (i < MAX_CHANNEL_NUM &&
4617 chplan_sta[i].ChannelNum != 0 &&
4618 chplan_sta[i].ChannelNum <= 14) {
4619 chplan_new[k].ChannelNum =
4620 chplan_sta[i].ChannelNum;
4621 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4626 /* skip AP 2.4G channel plan */
4627 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14)
4631 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
4633 if (i == MAX_CHANNEL_NUM ||
4634 chplan_sta[i].ChannelNum == 0)
4637 if (j == chplan_ap.Len ||
4638 chplan_ap.Channel[j] == 0)
4641 if (chplan_sta[i].ChannelNum ==
4642 chplan_ap.Channel[j]) {
4643 chplan_new[k].ChannelNum =
4644 chplan_ap.Channel[j];
4645 chplan_new[k].ScanType = SCAN_ACTIVE;
4649 } else if (chplan_sta[i].ChannelNum <
4650 chplan_ap.Channel[j]) {
4651 chplan_new[k].ChannelNum =
4652 chplan_sta[i].ChannelNum;
4653 chplan_new[k].ScanType = SCAN_PASSIVE;
4656 } else if (chplan_sta[i].ChannelNum >
4657 chplan_ap.Channel[j]) {
4658 chplan_new[k].ChannelNum =
4659 chplan_ap.Channel[j];
4660 chplan_new[k].ScanType = SCAN_ACTIVE;
4666 /* change AP not support channel to Passive scan */
4667 while (i < MAX_CHANNEL_NUM &&
4668 chplan_sta[i].ChannelNum != 0) {
4669 chplan_new[k].ChannelNum =
4670 chplan_sta[i].ChannelNum;
4671 chplan_new[k].ScanType = SCAN_PASSIVE;
4676 /* add channel AP supported */
4677 while (j < chplan_ap.Len && chplan_ap.Channel[j] != 0) {
4678 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4679 chplan_new[k].ScanType = SCAN_ACTIVE;
4684 /* keep original STA 5G channel plan */
4685 while (i < MAX_CHANNEL_NUM &&
4686 chplan_sta[i].ChannelNum != 0) {
4687 chplan_new[k].ChannelNum =
4688 chplan_sta[i].ChannelNum;
4689 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4694 pmlmeext->update_channel_plan_by_ap_done = 1;
4697 /* If channel is used by AP, set channel scan type to active */
4698 channel = bssid->DSConfig;
4699 chplan_new = pmlmeext->channel_set;
4701 while (i < MAX_CHANNEL_NUM && chplan_new[i].ChannelNum != 0) {
4702 if (chplan_new[i].ChannelNum == channel) {
4703 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
4704 /* 5G Bnad 2, 3 (DFS) doesn't change
4706 if (channel >= 52 && channel <= 144)
4709 chplan_new[i].ScanType = SCAN_ACTIVE;
4710 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4711 ("%s: change channel %d scan type "
4712 "from passive to active\n",
4713 __func__, channel));
4721 /****************************************************************************
4723 Following are the functions to report events
4725 *****************************************************************************/
4727 void report_survey_event23a(struct rtw_adapter *padapter,
4728 struct recv_frame *precv_frame)
4730 struct cmd_obj *pcmd_obj;
4733 struct survey_event *psurvey_evt;
4734 struct C2HEvent_Header *pc2h_evt_hdr;
4735 struct mlme_ext_priv *pmlmeext;
4736 struct cmd_priv *pcmdpriv;
4741 pmlmeext = &padapter->mlmeextpriv;
4742 pcmdpriv = &padapter->cmdpriv;
4744 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4748 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
4749 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4755 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4756 pcmd_obj->cmdsz = cmdsz;
4757 pcmd_obj->parmbuf = pevtcmd;
4759 pcmd_obj->rsp = NULL;
4760 pcmd_obj->rspsz = 0;
4762 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4763 pc2h_evt_hdr->len = sizeof(struct survey_event);
4764 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
4765 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4767 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4769 psurvey_evt->bss = collect_bss_info(padapter, precv_frame);
4770 if (!psurvey_evt->bss) {
4776 process_80211d(padapter, psurvey_evt->bss);
4778 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4780 pmlmeext->sitesurvey_res.bss_cnt++;
4785 void report_surveydone_event23a(struct rtw_adapter *padapter)
4787 struct cmd_obj *pcmd_obj;
4790 struct surveydone_event *psurveydone_evt;
4791 struct C2HEvent_Header *pc2h_evt_hdr;
4792 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4793 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4795 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4799 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
4800 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4806 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4807 pcmd_obj->cmdsz = cmdsz;
4808 pcmd_obj->parmbuf = pevtcmd;
4810 pcmd_obj->rsp = NULL;
4811 pcmd_obj->rspsz = 0;
4813 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4814 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
4815 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
4816 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4818 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4819 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
4821 DBG_8723A("survey done event(%x)\n", psurveydone_evt->bss_cnt);
4823 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4828 void report_join_res23a(struct rtw_adapter *padapter, int res)
4830 struct cmd_obj *pcmd_obj;
4833 struct joinbss_event *pjoinbss_evt;
4834 struct C2HEvent_Header *pc2h_evt_hdr;
4835 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4836 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4837 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4839 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4843 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
4844 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4850 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4851 pcmd_obj->cmdsz = cmdsz;
4852 pcmd_obj->parmbuf = pevtcmd;
4854 pcmd_obj->rsp = NULL;
4855 pcmd_obj->rspsz = 0;
4857 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4858 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
4859 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
4860 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4862 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4863 memcpy((unsigned char *)&pjoinbss_evt->network.network,
4864 &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
4865 pjoinbss_evt->network.join_res = res;
4867 DBG_8723A("report_join_res23a(%d)\n", res);
4869 rtw_joinbss_event_prehandle23a(padapter, (u8 *)&pjoinbss_evt->network);
4871 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4876 void report_del_sta_event23a(struct rtw_adapter *padapter,
4877 unsigned char *MacAddr, unsigned short reason)
4879 struct cmd_obj *pcmd_obj;
4882 struct sta_info *psta;
4884 struct stadel_event *pdel_sta_evt;
4885 struct C2HEvent_Header *pc2h_evt_hdr;
4886 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4887 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4889 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4893 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
4894 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4900 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4901 pcmd_obj->cmdsz = cmdsz;
4902 pcmd_obj->parmbuf = pevtcmd;
4904 pcmd_obj->rsp = NULL;
4905 pcmd_obj->rspsz = 0;
4907 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4908 pc2h_evt_hdr->len = sizeof(struct stadel_event);
4909 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
4910 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4912 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4913 ether_addr_copy((unsigned char *)&pdel_sta_evt->macaddr, MacAddr);
4914 memcpy((unsigned char *)pdel_sta_evt->rsvd, (unsigned char *)&reason,
4917 psta = rtw_get_stainfo23a(&padapter->stapriv, MacAddr);
4919 mac_id = (int)psta->mac_id;
4923 pdel_sta_evt->mac_id = mac_id;
4925 DBG_8723A("report_del_sta_event23a: delete STA, mac_id =%d\n", mac_id);
4927 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4932 void report_add_sta_event23a(struct rtw_adapter *padapter,
4933 unsigned char *MacAddr, int cam_idx)
4935 struct cmd_obj *pcmd_obj;
4938 struct stassoc_event *padd_sta_evt;
4939 struct C2HEvent_Header *pc2h_evt_hdr;
4940 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4941 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4943 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4947 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
4948 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4954 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4955 pcmd_obj->cmdsz = cmdsz;
4956 pcmd_obj->parmbuf = pevtcmd;
4958 pcmd_obj->rsp = NULL;
4959 pcmd_obj->rspsz = 0;
4961 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4962 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
4963 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
4964 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4966 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
4967 ether_addr_copy((unsigned char *)&padd_sta_evt->macaddr, MacAddr);
4968 padd_sta_evt->cam_id = cam_idx;
4970 DBG_8723A("report_add_sta_event23a: add STA\n");
4972 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
4977 /****************************************************************************
4979 Following are the event callback functions
4981 *****************************************************************************/
4983 /* for sta/adhoc mode */
4984 void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta)
4986 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4987 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4988 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4991 VCS_update23a(padapter, psta);
4994 if (pmlmepriv->htpriv.ht_option) {
4995 psta->htpriv.ht_option = true;
4997 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
4999 if (support_short_GI23a(padapter, &pmlmeinfo->ht_cap))
5000 psta->htpriv.sgi = true;
5002 psta->qos_option = true;
5005 psta->htpriv.ht_option = false;
5007 psta->htpriv.ampdu_enable = false;
5009 psta->htpriv.sgi = false;
5010 psta->qos_option = false;
5013 psta->htpriv.bwmode = pmlmeext->cur_bwmode;
5014 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
5016 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
5017 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
5020 if (pmlmepriv->qos_option)
5021 psta->qos_option = true;
5023 psta->state = _FW_LINKED;
5026 void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter,
5029 struct sta_info *psta, *psta_bmc;
5030 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5031 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5032 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
5033 struct sta_priv *pstapriv = &padapter->stapriv;
5036 hw_var_set_mlme_join(padapter, 1);
5037 hw_var_set_bssid(padapter, null_addr);
5039 /* restore to initial setting. */
5040 update_tx_basic_rate23a(padapter,
5041 padapter->registrypriv.wireless_mode);
5043 goto exit_mlmeext_joinbss_event_callback23a;
5046 if ((pmlmeinfo->state&0x03) == MSR_ADHOC) {
5048 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
5050 pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
5051 update_bmc_sta_support_rate23a(padapter, psta_bmc->mac_id);
5052 Update_RA_Entry23a(padapter, psta_bmc);
5056 /* turn on dynamic functions */
5057 rtl8723a_odm_support_ability_set(padapter, DYNAMIC_ALL_FUNC_ENABLE);
5059 /* update IOT-releated issue */
5060 update_IOT_info23a(padapter);
5062 HalSetBrateCfg23a(padapter, cur_network->SupportedRates);
5065 rtl8723a_set_beacon_interval(padapter, pmlmeinfo->bcn_interval);
5067 /* update capability */
5068 update_capinfo23a(padapter, pmlmeinfo->capability);
5070 /* WMM, Update EDCA param */
5071 WMMOnAssocRsp23a(padapter);
5074 HTOnAssocRsp23a(padapter);
5076 /* Set cur_channel&cur_bwmode&cur_ch_offset */
5077 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5079 psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
5080 if (psta) { /* only for infra. mode */
5081 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5083 /* DBG_8723A("set_sta_rate23a\n"); */
5085 psta->wireless_mode = pmlmeext->cur_wireless_mode;
5087 /* set per sta rate after updating HT cap. */
5088 set_sta_rate23a(padapter, psta);
5091 hw_var_set_mlme_join(padapter, 2);
5093 if ((pmlmeinfo->state&0x03) == MSR_INFRA) {
5094 /* correcting TSF */
5095 rtw_correct_TSF(padapter);
5097 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5100 rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_CONNECT, 0);
5102 exit_mlmeext_joinbss_event_callback23a:
5103 DBG_8723A("=>%s\n", __func__);
5106 void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter,
5107 struct sta_info *psta)
5109 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5110 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5112 DBG_8723A("%s\n", __func__);
5114 if ((pmlmeinfo->state & 0x03) == MSR_ADHOC) {
5115 /* adhoc master or sta_count>1 */
5116 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
5118 } else { /* adhoc client */
5119 /* correcting TSF */
5120 rtw_correct_TSF(padapter);
5123 if (send_beacon23a(padapter) != _SUCCESS) {
5124 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
5126 pmlmeinfo->state ^= MSR_ADHOC;
5131 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
5133 hw_var_set_mlme_join(padapter, 2);
5136 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5138 /* rate radaptive */
5139 Update_RA_Entry23a(padapter, psta);
5141 /* update adhoc sta_info */
5142 update_sta_info23a(padapter, psta);
5145 void mlmeext_sta_del_event_callback23a(struct rtw_adapter *padapter)
5147 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5148 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5150 if (is_client_associated_to_ap23a(padapter) ||
5151 is_IBSS_empty23a(padapter)) {
5152 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5154 hw_var_set_mlme_disconnect(padapter);
5155 hw_var_set_bssid(padapter, null_addr);
5157 /* restore to initial setting. */
5158 update_tx_basic_rate23a(padapter,
5159 padapter->registrypriv.wireless_mode);
5161 /* switch to the 20M Hz mode after disconnect */
5162 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5163 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5165 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
5166 pmlmeext->cur_ch_offset,
5167 pmlmeext->cur_bwmode);
5169 flush_all_cam_entry23a(padapter);
5171 pmlmeinfo->state = MSR_NOLINK;
5173 /* set MSR to no link state -> infra. mode */
5174 rtl8723a_set_media_status(padapter, MSR_INFRA);
5176 del_timer_sync(&pmlmeext->link_timer);
5180 static u8 chk_ap_is_alive(struct rtw_adapter *padapter, struct sta_info *psta)
5184 if (sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta) &&
5185 sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) &&
5186 sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
5191 sta_update_last_rx_pkts(psta);
5195 void linked_status_chk23a(struct rtw_adapter *padapter)
5198 struct sta_info *psta;
5199 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5200 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5201 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5202 struct sta_priv *pstapriv = &padapter->stapriv;
5204 if (is_client_associated_to_ap23a(padapter)) {
5205 /* linked infrastructure client mode */
5207 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
5212 psta = rtw_get_stainfo23a(pstapriv,
5213 pmlmeinfo->network.MacAddress);
5215 bool is_p2p_enable = false;
5217 if (chk_ap_is_alive(padapter, psta) == false)
5220 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
5223 if (pmlmeext->active_keep_alive_check &&
5224 (rx_chk == _FAIL || tx_chk == _FAIL)) {
5225 u8 backup_oper_channel = 0;
5227 /* switch to correct channel of current
5228 network before issue keep-alive frames */
5229 if (rtw_get_oper_ch23a(padapter) !=
5230 pmlmeext->cur_channel) {
5231 backup_oper_channel =
5232 rtw_get_oper_ch23a(padapter);
5233 SelectChannel23a(padapter,
5234 pmlmeext->cur_channel);
5237 if (rx_chk != _SUCCESS)
5238 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
5240 if ((tx_chk != _SUCCESS &&
5241 pmlmeinfo->link_count++ == 0xf) ||
5242 rx_chk != _SUCCESS) {
5243 tx_chk = issue_nulldata23a(padapter,
5246 /* if tx acked and p2p disabled,
5247 set rx_chk _SUCCESS to reset retry
5249 if (tx_chk == _SUCCESS &&
5254 /* back to the original operation channel */
5255 if (backup_oper_channel>0)
5256 SelectChannel23a(padapter,
5257 backup_oper_channel);
5259 if (rx_chk != _SUCCESS) {
5260 if (pmlmeext->retry == 0) {
5261 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5262 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5263 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5267 if (tx_chk != _SUCCESS &&
5268 pmlmeinfo->link_count++ == 0xf)
5269 tx_chk = issue_nulldata23a(padapter,
5274 if (rx_chk == _FAIL) {
5276 if (pmlmeext->retry > rx_chk_limit) {
5277 DBG_8723A_LEVEL(_drv_always_,
5278 "%s(%s): disconnect or "
5279 "roaming\n", __func__,
5280 padapter->pnetdev->name);
5281 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress,
5282 WLAN_REASON_EXPIRATION_CHK);
5286 pmlmeext->retry = 0;
5288 if (tx_chk == _FAIL)
5289 pmlmeinfo->link_count &= 0xf;
5291 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
5292 pmlmeinfo->link_count = 0;
5296 } else if (is_client_associated_to_ibss23a(padapter)) {
5297 /* linked IBSS mode */
5298 /* for each assoc list entry to check the rx pkt counter */
5299 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
5300 if (pmlmeinfo->FW_sta_info[i].status == 1) {
5301 psta = pmlmeinfo->FW_sta_info[i].psta;
5306 if (pmlmeinfo->FW_sta_info[i].rx_pkt ==
5307 sta_rx_pkts(psta)) {
5309 if (pmlmeinfo->FW_sta_info[i].retry<3) {
5310 pmlmeinfo->FW_sta_info[i].retry++;
5312 pmlmeinfo->FW_sta_info[i].retry = 0;
5313 pmlmeinfo->FW_sta_info[i].status = 0;
5314 report_del_sta_event23a(padapter, psta->hwaddr,
5315 65535/* indicate disconnect caused by no rx */
5319 pmlmeinfo->FW_sta_info[i].retry = 0;
5320 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
5324 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5328 static void survey_timer_hdl(unsigned long data)
5330 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5331 struct cmd_obj *ph2c;
5332 struct sitesurvey_parm *psurveyPara;
5333 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5334 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5336 /* issue rtw_sitesurvey_cmd23a */
5337 if (pmlmeext->sitesurvey_res.state > SCAN_START) {
5338 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
5339 pmlmeext->sitesurvey_res.channel_idx++;
5341 if (pmlmeext->scan_abort == true) {
5342 pmlmeext->sitesurvey_res.channel_idx =
5343 pmlmeext->sitesurvey_res.ch_num;
5344 DBG_8723A("%s idx:%d\n", __func__,
5345 pmlmeext->sitesurvey_res.channel_idx);
5347 pmlmeext->scan_abort = false;/* reset */
5350 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
5352 goto exit_survey_timer_hdl;
5354 psurveyPara = kzalloc(sizeof(struct sitesurvey_parm),
5358 goto exit_survey_timer_hdl;
5361 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara,
5362 GEN_CMD_CODE(_SiteSurvey));
5363 rtw_enqueue_cmd23a(pcmdpriv, ph2c);
5366 exit_survey_timer_hdl:
5370 static void link_timer_hdl(unsigned long data)
5372 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5373 /* static unsigned int rx_pkt = 0; */
5374 /* static u64 tx_cnt = 0; */
5375 /* struct xmit_priv *pxmitpriv = &padapter->xmitpriv; */
5376 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5377 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5378 /* struct sta_priv *pstapriv = &padapter->stapriv; */
5380 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
5381 DBG_8723A("link_timer_hdl:no beacon while connecting\n");
5382 pmlmeinfo->state = MSR_NOLINK;
5383 report_join_res23a(padapter, -3);
5384 } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
5386 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
5387 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
5389 pmlmeinfo->state = 0;
5390 report_join_res23a(padapter, -1);
5395 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
5396 /* pmlmeinfo->reauth_count = 0; */
5400 DBG_8723A("link_timer_hdl: auth timeout and try again\n");
5401 pmlmeinfo->auth_seq = 1;
5402 issue_auth(padapter, NULL, 0);
5403 set_link_timer(pmlmeext, REAUTH_TO);
5404 } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
5405 /* re-assoc timer */
5406 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
5407 pmlmeinfo->state = MSR_NOLINK;
5408 report_join_res23a(padapter, -2);
5412 DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
5413 issue_assocreq(padapter);
5414 set_link_timer(pmlmeext, REASSOC_TO);
5420 static void addba_timer_hdl(unsigned long data)
5422 struct sta_info *psta = (struct sta_info *)data;
5423 struct ht_priv *phtpriv;
5428 phtpriv = &psta->htpriv;
5430 if (phtpriv->ht_option && phtpriv->ampdu_enable) {
5431 if (phtpriv->candidate_tid_bitmap)
5432 phtpriv->candidate_tid_bitmap = 0x0;
5436 void init_addba_retry_timer23a(struct sta_info *psta)
5438 setup_timer(&psta->addba_retry_timer, addba_timer_hdl,
5439 (unsigned long)psta);
5442 void init_mlme_ext_timer23a(struct rtw_adapter *padapter)
5444 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5446 setup_timer(&pmlmeext->survey_timer, survey_timer_hdl,
5447 (unsigned long)padapter);
5449 setup_timer(&pmlmeext->link_timer, link_timer_hdl,
5450 (unsigned long)padapter);
5453 int NULL_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5458 int setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5460 enum nl80211_iftype type;
5461 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5462 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5463 const struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
5465 switch (psetop->mode) {
5466 case NL80211_IFTYPE_P2P_GO:
5467 case NL80211_IFTYPE_AP:
5468 pmlmeinfo->state = MSR_AP;
5471 case NL80211_IFTYPE_P2P_CLIENT:
5472 case NL80211_IFTYPE_STATION:
5474 pmlmeinfo->state &= ~(BIT(0)|BIT(1));
5475 /* set to STATION_STATE */
5476 pmlmeinfo->state |= MSR_INFRA;
5479 case NL80211_IFTYPE_ADHOC:
5487 hw_var_set_opmode(padapter, type);
5488 /* Set_NETYPE0_MSR(padapter, type); */
5493 int createbss_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5495 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5496 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5497 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5498 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5499 /* u32 initialgain; */
5501 if (pparm->ifmode == NL80211_IFTYPE_AP ||
5502 pparm->ifmode == NL80211_IFTYPE_P2P_GO) {
5503 #ifdef CONFIG_8723AU_AP_MODE
5504 if (pmlmeinfo->state == MSR_AP) {
5511 /* below is for ad-hoc master */
5512 if (pparm->ifmode == NL80211_IFTYPE_ADHOC) {
5513 rtw_joinbss_reset23a(padapter);
5515 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5516 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5517 pmlmeinfo->ERP_enable = 0;
5518 pmlmeinfo->WMM_enable = 0;
5519 pmlmeinfo->HT_enable = 0;
5520 pmlmeinfo->HT_caps_enable = 0;
5521 pmlmeinfo->HT_info_enable = 0;
5523 /* disable dynamic functions, such as high power, DIG */
5524 rtl8723a_odm_support_ability_backup(padapter);
5526 rtl8723a_odm_support_ability_clr(padapter,
5527 DYNAMIC_FUNC_DISABLE);
5529 /* cancel link timer */
5530 del_timer_sync(&pmlmeext->link_timer);
5533 flush_all_cam_entry23a(padapter);
5535 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5536 return H2C_PARAMETERS_ERROR;
5538 memcpy(pnetwork, pparm, sizeof(struct wlan_bssid_ex));
5540 start_create_ibss(padapter);
5546 int join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5548 struct registry_priv *pregpriv = &padapter->registrypriv;
5549 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5550 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5551 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5552 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5553 struct ieee80211_ht_operation *pht_info;
5556 /* u32 initialgain; */
5559 /* check already connecting to AP or not */
5560 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
5561 if (pmlmeinfo->state & MSR_INFRA)
5562 issue_deauth_ex(padapter, pnetwork->MacAddress,
5563 WLAN_REASON_DEAUTH_LEAVING, 5, 100);
5565 pmlmeinfo->state = MSR_NOLINK;
5568 flush_all_cam_entry23a(padapter);
5570 del_timer_sync(&pmlmeext->link_timer);
5572 /* set MSR to nolink -> infra. mode */
5573 rtl8723a_set_media_status(padapter, MSR_INFRA);
5575 hw_var_set_mlme_disconnect(padapter);
5578 rtw_joinbss_reset23a(padapter);
5580 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5581 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5582 pmlmeinfo->ERP_enable = 0;
5583 pmlmeinfo->WMM_enable = 0;
5584 pmlmeinfo->HT_enable = 0;
5585 pmlmeinfo->HT_caps_enable = 0;
5586 pmlmeinfo->HT_info_enable = 0;
5587 pmlmeinfo->bwmode_updated = false;
5588 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
5590 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5591 return H2C_PARAMETERS_ERROR;
5593 memcpy(pnetwork, pbuf, sizeof(struct wlan_bssid_ex));
5595 /* Check AP vendor to move rtw_joinbss_cmd23a() */
5596 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pnetwork->IEs,
5597 pnetwork->IELength); */
5599 for (i = 0; i < pnetwork->IELength;) {
5600 p = pnetwork->IEs + i;
5603 case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */
5604 if (!memcmp(p + 2, WMM_OUI23A, 4))
5605 pmlmeinfo->WMM_enable = 1;
5608 case WLAN_EID_HT_CAPABILITY: /* Get HT Cap IE. */
5609 pmlmeinfo->HT_caps_enable = 1;
5612 case WLAN_EID_HT_OPERATION: /* Get HT Info IE. */
5613 pmlmeinfo->HT_info_enable = 1;
5615 /* spec case only for cisco's ap because cisco's ap
5616 * issue assoc rsp using mcs rate @40MHz or @20MHz */
5617 pht_info = (struct ieee80211_ht_operation *)(p + 2);
5619 if (pregpriv->cbw40_enable &&
5620 (pht_info->ht_param &
5621 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
5622 /* switch to the 40M Hz mode according to AP */
5623 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
5624 switch (pht_info->ht_param &
5625 IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
5626 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
5627 pmlmeext->cur_ch_offset =
5628 HAL_PRIME_CHNL_OFFSET_LOWER;
5631 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
5632 pmlmeext->cur_ch_offset =
5633 HAL_PRIME_CHNL_OFFSET_UPPER;
5637 pmlmeext->cur_ch_offset =
5638 HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5642 DBG_8723A("set ch/bw before connected\n");
5653 hw_var_set_bssid(padapter, pmlmeinfo->network.MacAddress);
5654 hw_var_set_mlme_join(padapter, 0);
5656 /* cancel link timer */
5657 del_timer_sync(&pmlmeext->link_timer);
5659 start_clnt_join(padapter);
5664 int disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5666 const struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
5667 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5668 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5669 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5671 if (is_client_associated_to_ap23a(padapter)) {
5672 issue_deauth_ex(padapter, pnetwork->MacAddress,
5673 WLAN_REASON_DEAUTH_LEAVING,
5674 param->deauth_timeout_ms/100, 100);
5677 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5679 /* pmlmeinfo->state = MSR_NOLINK; */
5681 hw_var_set_mlme_disconnect(padapter);
5682 hw_var_set_bssid(padapter, null_addr);
5684 /* restore to initial setting. */
5685 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
5687 if ((pmlmeinfo->state & 0x03) == MSR_ADHOC ||
5688 (pmlmeinfo->state & 0x03) == MSR_AP)
5689 rtl8723a_set_bcn_func(padapter, 0); /* Stop BCN */
5691 /* set MSR to no link state -> infra. mode */
5692 rtl8723a_set_media_status(padapter, MSR_INFRA);
5694 pmlmeinfo->state = MSR_NOLINK;
5696 /* switch to the 20M Hz mode after disconnect */
5697 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5698 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5700 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
5701 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5703 flush_all_cam_entry23a(padapter);
5705 del_timer_sync(&pmlmeext->link_timer);
5707 rtw_free_uc_swdec_pending_queue23a(padapter);
5713 rtw_scan_ch_decision(struct rtw_adapter *padapter,
5714 struct rtw_ieee80211_channel *out, u32 out_num,
5715 const struct rtw_ieee80211_channel *in, u32 in_num)
5718 int scan_ch_num = 0;
5720 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5722 /* clear out first */
5723 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
5725 /* acquire channels from in */
5727 for (i = 0;i<in_num;i++) {
5728 if (in[i].hw_value &&
5729 !(in[i].flags & IEEE80211_CHAN_DISABLED) &&
5730 (set_idx = rtw_ch_set_search_ch23a(pmlmeext->channel_set,
5731 in[i].hw_value)) >= 0) {
5732 memcpy(&out[j], &in[i],
5733 sizeof(struct rtw_ieee80211_channel));
5735 if (pmlmeext->channel_set[set_idx].ScanType ==
5737 out[j].flags &= IEEE80211_CHAN_NO_IR;
5745 /* if out is empty, use channel_set as default */
5747 for (i = 0;i<pmlmeext->max_chan_nums;i++) {
5748 out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
5750 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
5751 out[i].flags &= IEEE80211_CHAN_NO_IR;
5757 if (padapter->setband == GHZ_24) { /* 2.4G */
5758 for (i = 0; i < j ; i++) {
5759 if (out[i].hw_value > 35)
5761 sizeof(struct rtw_ieee80211_channel));
5766 } else if (padapter->setband == GHZ_50) { /* 5G */
5767 for (i = 0; i < j ; i++) {
5768 if (out[i].hw_value > 35) {
5769 memcpy(&out[scan_ch_num++], &out[i],
5770 sizeof(struct rtw_ieee80211_channel));
5780 int sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5782 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5783 const struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
5784 u8 bdelayscan = false;
5788 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
5789 pmlmeext->sitesurvey_res.state = SCAN_START;
5790 pmlmeext->sitesurvey_res.bss_cnt = 0;
5791 pmlmeext->sitesurvey_res.channel_idx = 0;
5793 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
5794 if (pparm->ssid[i].ssid_len) {
5795 memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid,
5796 pparm->ssid[i].ssid,
5797 IEEE80211_MAX_SSID_LEN);
5798 pmlmeext->sitesurvey_res.ssid[i].ssid_len =
5799 pparm->ssid[i].ssid_len;
5801 pmlmeext->sitesurvey_res.ssid[i].ssid_len = 0;
5805 pmlmeext->sitesurvey_res.ch_num =
5806 rtw_scan_ch_decision(padapter,
5807 pmlmeext->sitesurvey_res.ch,
5808 RTW_CHANNEL_SCAN_AMOUNT,
5809 pparm->ch, pparm->ch_num);
5811 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
5813 /* issue null data if associating to the AP */
5814 if (is_client_associated_to_ap23a(padapter)) {
5815 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
5817 /* switch to correct channel of current network
5818 before issue keep-alive frames */
5819 if (rtw_get_oper_ch23a(padapter) !=
5820 pmlmeext->cur_channel)
5821 SelectChannel23a(padapter,
5822 pmlmeext->cur_channel);
5824 issue_nulldata23a(padapter, NULL, 1, 3, 500);
5830 /* delay 50ms to protect nulldata(1). */
5831 set_survey_timer(pmlmeext, 50);
5836 if (pmlmeext->sitesurvey_res.state == SCAN_START ||
5837 pmlmeext->sitesurvey_res.state == SCAN_TXNULL) {
5838 /* disable dynamic functions, such as high power, DIG */
5839 rtl8723a_odm_support_ability_backup(padapter);
5840 rtl8723a_odm_support_ability_clr(padapter,
5841 DYNAMIC_FUNC_DISABLE);
5843 /* config the initial gain under scanning, need to
5844 write the BB registers */
5845 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == true)
5850 rtl8723a_set_initial_gain(padapter, initialgain);
5852 /* set MSR to no link state */
5853 rtl8723a_set_media_status(padapter, MSR_NOLINK);
5855 rtl8723a_mlme_sitesurvey(padapter, 1);
5857 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
5860 rtw_site_survey(padapter);
5865 int setauth_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5867 const struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
5868 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5869 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5871 if (pparm->mode < 4)
5872 pmlmeinfo->auth_algo = pparm->mode;
5877 int setkey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5879 unsigned short ctrl;
5880 const struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
5881 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5882 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5883 unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
5885 /* main tx key for wep. */
5887 pmlmeinfo->key_index = pparm->keyid;
5890 ctrl = BIT(15) | (pparm->algorithm) << 2 | pparm->keyid;
5892 DBG_8723A_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 "
5893 "WEP104-5 TKIP-2 AES-4) keyid:%d\n",
5894 pparm->algorithm, pparm->keyid);
5895 rtl8723a_cam_write(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
5897 /* allow multicast packets to driver */
5898 rtl8723a_on_rcr_am(padapter);
5903 int set_stakey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5906 u8 cam_id;/* cam_entry */
5907 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5908 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5909 const struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
5912 /* 0~3 for default key */
5914 /* for concurrent mode (ap+sta): */
5915 /* default key is disable, using sw encrypt/decrypt */
5916 /* cam_entry = 4 for sta mode (macid = 0) */
5917 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
5919 /* for concurrent mode (sta+sta): */
5920 /* default key is disable, using sw encrypt/decrypt */
5921 /* cam_entry = 4 mapping to macid = 0 */
5922 /* cam_entry = 5 mapping to macid = 2 */
5926 DBG_8723A_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 "
5927 "WEP104-5 TKIP-2 AES-4) camid:%d\n",
5928 pparm->algorithm, cam_id);
5929 if ((pmlmeinfo->state & 0x03) == MSR_AP) {
5930 struct sta_info *psta;
5931 struct sta_priv *pstapriv = &padapter->stapriv;
5933 if (pparm->algorithm == 0) { /* clear cam entry */
5934 clear_cam_entry23a(padapter, pparm->id);
5935 return H2C_SUCCESS_RSP;
5938 psta = rtw_get_stainfo23a(pstapriv, pparm->addr);
5940 ctrl = BIT(15) | (pparm->algorithm << 2);
5942 DBG_8723A("r871x_set_stakey_hdl23a(): enc_algorithm "
5943 "=%d\n", pparm->algorithm);
5945 if (psta->mac_id < 1 || psta->mac_id > (NUM_STA - 4)) {
5946 DBG_8723A("r871x_set_stakey_hdl23a():set_stakey"
5947 " failed, mac_id(aid) =%d\n",
5949 return H2C_REJECTED;
5952 /* 0~3 for default key, cmd_id = macid + 3,
5954 cam_id = (psta->mac_id + 3);
5956 DBG_8723A("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, "
5957 "cam_entry =%d\n", pparm->addr[0],
5958 pparm->addr[1], pparm->addr[2],
5959 pparm->addr[3], pparm->addr[4],
5960 pparm->addr[5], cam_id);
5962 rtl8723a_cam_write(padapter, cam_id, ctrl,
5963 pparm->addr, pparm->key);
5965 return H2C_SUCCESS_RSP;
5967 DBG_8723A("r871x_set_stakey_hdl23a(): sta has been "
5969 return H2C_REJECTED;
5973 /* below for sta mode */
5975 if (pparm->algorithm == 0) { /* clear cam entry */
5976 clear_cam_entry23a(padapter, pparm->id);
5980 ctrl = BIT(15) | (pparm->algorithm << 2);
5982 rtl8723a_cam_write(padapter, cam_id, ctrl, pparm->addr, pparm->key);
5984 pmlmeinfo->enc_algo = pparm->algorithm;
5989 int add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5991 const struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
5992 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5993 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5994 struct sta_info *psta;
5996 psta = rtw_get_stainfo23a(&padapter->stapriv, pparm->addr);
6001 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
6002 pmlmeinfo->HT_enable) ||
6003 (pmlmeinfo->state & 0x03) == MSR_AP) {
6004 issue_action_BA23a(padapter, pparm->addr,
6005 WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
6006 mod_timer(&psta->addba_retry_timer,
6007 jiffies + msecs_to_jiffies(ADDBA_TO));
6009 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
6014 int set_tx_beacon_cmd23a(struct rtw_adapter *padapter)
6016 struct cmd_obj *ph2c;
6017 struct Tx_Beacon_param *ptxBeacon_parm;
6018 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
6019 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6020 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6024 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
6030 ptxBeacon_parm = kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC);
6031 if (!ptxBeacon_parm) {
6037 memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network,
6038 sizeof(struct wlan_bssid_ex));
6040 len_diff = update_hidden_ssid(ptxBeacon_parm->network.IEs,
6041 ptxBeacon_parm->network.IELength,
6042 pmlmeinfo->hidden_ssid_mode);
6043 ptxBeacon_parm->network.IELength += len_diff;
6045 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm,
6046 GEN_CMD_CODE(_TX_Beacon));
6048 res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
6054 int mlme_evt_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6056 u8 evt_code, evt_seq;
6058 const struct C2HEvent_Header *c2h;
6059 void (*event_callback)(struct rtw_adapter *dev, const u8 *pbuf);
6061 c2h = (struct C2HEvent_Header *)pbuf;
6066 /* checking if event code is valid */
6067 if (evt_code >= MAX_C2HEVT) {
6068 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
6069 ("\nEvent Code(%d) mismatch!\n", evt_code));
6073 /* checking if event size match the event parm size */
6074 if (wlanevents[evt_code].parmsize != 0 &&
6075 wlanevents[evt_code].parmsize != evt_sz) {
6076 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
6077 ("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
6078 evt_code, wlanevents[evt_code].parmsize, evt_sz));
6082 event_callback = wlanevents[evt_code].event_callback;
6083 event_callback(padapter, pbuf + sizeof(struct C2HEvent_Header));
6090 int h2c_msg_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6093 return H2C_PARAMETERS_ERROR;
6098 int tx_beacon_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6100 if (send_beacon23a(padapter) == _FAIL) {
6101 DBG_8723A("issue_beacon23a, fail!\n");
6102 return H2C_PARAMETERS_ERROR;
6104 #ifdef CONFIG_8723AU_AP_MODE
6105 else { /* tx bc/mc frames after update TIM */
6106 struct sta_info *psta_bmc;
6107 struct list_head *plist, *phead, *ptmp;
6108 struct xmit_frame *pxmitframe;
6109 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6110 struct sta_priv *pstapriv = &padapter->stapriv;
6112 /* for BC/MC Frames */
6113 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
6117 if (pstapriv->tim_bitmap & BIT(0) && psta_bmc->sleepq_len > 0) {
6118 msleep(10);/* 10ms, ATIM(HIQ) Windows */
6119 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
6120 spin_lock_bh(&pxmitpriv->lock);
6122 phead = get_list_head(&psta_bmc->sleep_q);
6124 list_for_each_safe(plist, ptmp, phead) {
6125 pxmitframe = container_of(plist,
6129 list_del_init(&pxmitframe->list);
6131 psta_bmc->sleepq_len--;
6132 if (psta_bmc->sleepq_len>0)
6133 pxmitframe->attrib.mdata = 1;
6135 pxmitframe->attrib.mdata = 0;
6137 pxmitframe->attrib.triggered = 1;
6139 pxmitframe->attrib.qsel = 0x11;/* HIQ */
6141 rtl8723au_hal_xmitframe_enqueue(padapter,
6145 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
6146 spin_unlock_bh(&pxmitpriv->lock);
6154 int set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6156 const struct set_ch_parm *set_ch_parm;
6157 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6160 return H2C_PARAMETERS_ERROR;
6162 set_ch_parm = (struct set_ch_parm *)pbuf;
6164 DBG_8723A("%s(%s): ch:%u, bw:%u, ch_offset:%u\n", __func__,
6165 padapter->pnetdev->name, set_ch_parm->ch,
6166 set_ch_parm->bw, set_ch_parm->ch_offset);
6168 pmlmeext->cur_channel = set_ch_parm->ch;
6169 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
6170 pmlmeext->cur_bwmode = set_ch_parm->bw;
6172 set_channel_bwmode23a(padapter, set_ch_parm->ch,
6173 set_ch_parm->ch_offset, set_ch_parm->bw);
6178 int set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6180 const struct SetChannelPlan_param *setChannelPlan_param;
6181 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6184 return H2C_PARAMETERS_ERROR;
6186 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
6188 pmlmeext->max_chan_nums =
6189 init_channel_set(padapter, setChannelPlan_param->channel_plan,
6190 pmlmeext->channel_set);
6191 init_channel_list(padapter, pmlmeext->channel_set,
6192 pmlmeext->max_chan_nums, &pmlmeext->channel_list);
6197 int led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6199 struct LedBlink_param *ledBlink_param;
6202 return H2C_PARAMETERS_ERROR;
6204 ledBlink_param = (struct LedBlink_param *)pbuf;
6209 int set_csa_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6211 return H2C_REJECTED;
6214 /* TDLS_WRCR : write RCR DATA BIT */
6215 /* TDLS_SD_PTI : issue peer traffic indication */
6216 /* TDLS_CS_OFF : go back to the channel linked with AP,
6217 terminating channel switch procedure */
6218 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and
6220 /* TDLS_DONE_CH_SEN : channel sensing and report candidate channel */
6221 /* TDLS_OFF_CH : first time set channel to off channel */
6222 /* TDLS_BASE_CH : go back tp the channel linked with AP when set
6223 base channel as target channel */
6224 /* TDLS_P_OFF_CH : periodically go to off channel */
6225 /* TDLS_P_BASE_CH : periodically go back to base channel */
6226 /* TDLS_RS_RCR : restore RCR */
6227 /* TDLS_CKALV_PH1 : check alive timer phase1 */
6228 /* TDLS_CKALV_PH2 : check alive timer phase2 */
6229 /* TDLS_FREE_STA : free tdls sta */
6230 int tdls_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6232 return H2C_REJECTED;