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>
26 #ifdef CONFIG_8723AU_BT_COEXIST
27 #include <rtl8723a_hal.h>
30 static int OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
31 static int OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
32 static int OnProbeReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
33 static int OnProbeRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
34 static int DoReserved23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
35 static int OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
36 static int OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
37 static int OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
38 static int OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
39 static int OnAuth23aClient23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
40 static int OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
41 static int OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
43 static int on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
44 static int OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
45 static int OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
46 static int OnAction23a_back23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
47 static int on_action_public23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
48 static int OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
49 static int OnAction23a_wmm(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
50 static int OnAction23a_p2p(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
52 static struct mlme_handler mlme_sta_tbl[]={
53 {"OnAssocReq23a", &OnAssocReq23a},
54 {"OnAssocRsp23a", &OnAssocRsp23a},
55 {"OnReAssocReq", &OnAssocReq23a},
56 {"OnReAssocRsp", &OnAssocRsp23a},
57 {"OnProbeReq23a", &OnProbeReq23a},
58 {"OnProbeRsp23a", &OnProbeRsp23a},
60 /*----------------------------------------------------------
62 -----------------------------------------------------------*/
63 {"DoReserved23a", &DoReserved23a},
64 {"DoReserved23a", &DoReserved23a},
65 {"OnBeacon23a", &OnBeacon23a},
66 {"OnATIM", &OnAtim23a},
67 {"OnDisassoc23a", &OnDisassoc23a},
68 {"OnAuth23a", &OnAuth23aClient23a},
69 {"OnDeAuth23a", &OnDeAuth23a},
70 {"OnAction23a", &OnAction23a},
73 static struct action_handler OnAction23a_tbl[]={
74 {WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct23a},
75 {WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction23a_qos},
76 {WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction23a_dls},
77 {WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction23a_back23a},
78 {WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public23a},
79 {WLAN_CATEGORY_HT, "ACTION_HT", &OnAction23a_ht},
80 {WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved23a},
81 {WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction23a_wmm},
82 {WLAN_CATEGORY_VENDOR_SPECIFIC, "ACTION_P2P", &OnAction23a_p2p},
85 static u8 null_addr[ETH_ALEN]= {0, 0, 0, 0, 0, 0};
87 /**************************************************
88 OUI definitions for the vendor specific IE
89 ***************************************************/
90 unsigned char WMM_OUI23A[] = {0x00, 0x50, 0xf2, 0x02};
91 unsigned char WPS_OUI23A[] = {0x00, 0x50, 0xf2, 0x04};
92 unsigned char P2P_OUI23A[] = {0x50, 0x6F, 0x9A, 0x09};
93 unsigned char WFD_OUI23A[] = {0x50, 0x6F, 0x9A, 0x0A};
95 unsigned char WMM_INFO_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
96 unsigned char WMM_PARA_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
98 unsigned char WPA_TKIP_CIPHER23A[4] = {0x00, 0x50, 0xf2, 0x02};
99 unsigned char RSN_TKIP_CIPHER23A[4] = {0x00, 0x0f, 0xac, 0x02};
101 static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
103 /********************************************************
105 *********************************************************/
106 unsigned char MCS_rate_2R23A[16] = {
107 0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
108 unsigned char MCS_rate_1R23A[16] = {
109 0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
111 /********************************************************
112 ChannelPlan definitions
113 *********************************************************/
115 static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
116 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
117 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
118 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
119 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
120 {{10, 11, 12, 13}, 4}, /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
121 {{}, 0}, /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
124 static struct rt_channel_plan_5g RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
125 {{}, 0}, /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
126 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19}, /* 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 */
127 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, /* 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 */
128 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22}, /* 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 */
129 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, /* 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */
130 {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9}, /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
131 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13}, /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
132 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12}, /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
133 {{149, 153, 157, 161, 165}, 5}, /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
134 {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
135 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20}, /* 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 */
136 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 20}, /* 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 */
137 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19}, /* 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 */
138 {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
139 {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11}, /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
140 {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 15}, /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
141 {{56, 60, 64, 149, 153, 157, 161, 165}, 8}, /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
143 /* Driver self defined for old channel plan Compatible , Remember to modify if have new channel plan definition ===== */
144 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21}, /* 0x11, RT_CHANNEL_DOMAIN_5G_FCC */
145 {{36, 40, 44, 48}, 4}, /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
146 {{36, 40, 44, 48, 149, 153, 157, 161}, 8}, /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
149 static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
150 /* 0x00 ~ 0x1F , Old Define ===== */
151 {0x02, 0x11}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
152 {0x02, 0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
153 {0x01, 0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
154 {0x01, 0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
155 {0x01, 0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
156 {0x03, 0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
157 {0x03, 0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
158 {0x01, 0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
159 {0x03, 0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
160 {0x03, 0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
161 {0x00, 0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
162 {0x02, 0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
163 {0x01, 0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
164 {0x02, 0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
165 {0x02, 0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
166 {0x02, 0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
167 {0x01, 0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
168 {0x02, 0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
169 {0x01, 0x12}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
170 {0x00, 0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
171 {0x02, 0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
172 {0x00, 0x12}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
173 {0x00, 0x13}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
174 {0x03, 0x12}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
175 {0x05, 0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
176 {0x02, 0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
177 {0x00, 0x00}, /* 0x1A, */
178 {0x00, 0x00}, /* 0x1B, */
179 {0x00, 0x00}, /* 0x1C, */
180 {0x00, 0x00}, /* 0x1D, */
181 {0x00, 0x00}, /* 0x1E, */
182 {0x05, 0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
183 /* 0x20 ~ 0x7F , New Define ===== */
184 {0x00, 0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
185 {0x01, 0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
186 {0x02, 0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
187 {0x03, 0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
188 {0x04, 0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
189 {0x02, 0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
190 {0x00, 0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
191 {0x03, 0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
192 {0x00, 0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
193 {0x00, 0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
194 {0x00, 0x00}, /* 0x2A, */
195 {0x00, 0x00}, /* 0x2B, */
196 {0x00, 0x00}, /* 0x2C, */
197 {0x00, 0x00}, /* 0x2D, */
198 {0x00, 0x00}, /* 0x2E, */
199 {0x00, 0x00}, /* 0x2F, */
200 {0x00, 0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
201 {0x00, 0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
202 {0x00, 0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
203 {0x00, 0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
204 {0x02, 0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
205 {0x00, 0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
206 {0x00, 0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
207 {0x03, 0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
208 {0x03, 0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
209 {0x02, 0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
210 {0x00, 0x00}, /* 0x3A, */
211 {0x00, 0x00}, /* 0x3B, */
212 {0x00, 0x00}, /* 0x3C, */
213 {0x00, 0x00}, /* 0x3D, */
214 {0x00, 0x00}, /* 0x3E, */
215 {0x00, 0x00}, /* 0x3F, */
216 {0x02, 0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
217 {0x03, 0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
220 static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03, 0x02}; /* use the conbination for max channel numbers */
222 static struct fwevent wlanevents[] =
224 {0, rtw_dummy_event_callback23a}, /*0*/
232 {0, &rtw_survey_event_cb23a}, /*8*/
233 {sizeof (struct surveydone_event), &rtw_surveydone_event_callback23a}, /*9*/
235 {0, &rtw23a_joinbss_event_cb}, /*10*/
236 {sizeof(struct stassoc_event), &rtw_stassoc_event_callback23a},
237 {sizeof(struct stadel_event), &rtw_stadel_event_callback23a},
238 {0, &rtw_atimdone_event_callback23a},
239 {0, rtw_dummy_event_callback23a},
244 {0, rtw23a_fwdbg_event_callback},
248 {0, &rtw_cpwm_event_callback23a},
253 static void rtw_correct_TSF(struct rtw_adapter *padapter)
255 hw_var_set_correct_tsf(padapter);
259 rtw_update_TSF(struct mlme_ext_priv *pmlmeext, struct ieee80211_mgmt *mgmt)
261 pmlmeext->TSFValue = get_unaligned_le64(&mgmt->u.beacon.timestamp);
265 * Search the @param channel_num in given @param channel_set
266 * @ch_set: the given channel set
267 * @ch: the given channel number
269 * return the index of channel_num in channel_set, -1 if not found
271 int rtw_ch_set_search_ch23a(struct rt_channel_info *ch_set, const u32 ch)
274 for (i = 0; ch_set[i]. ChannelNum != 0; i++) {
275 if (ch == ch_set[i].ChannelNum)
279 if (i >= ch_set[i].ChannelNum)
284 /****************************************************************************
286 Following are the initialization functions for WiFi MLME
288 *****************************************************************************/
290 int init_hw_mlme_ext23a(struct rtw_adapter *padapter)
292 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
294 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
295 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
299 static void init_mlme_ext_priv23a_value(struct rtw_adapter* padapter)
301 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
302 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
303 unsigned char mixed_datarate[NumRates] = {
304 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
305 _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_,
306 _48M_RATE_, _54M_RATE_, 0xff};
307 unsigned char mixed_basicrate[NumRates] = {
308 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
309 _12M_RATE_, _24M_RATE_, 0xff,};
311 atomic_set(&pmlmeext->event_seq, 0);
312 /* reset to zero when disconnect at client mode */
313 pmlmeext->mgnt_seq = 0;
315 pmlmeext->cur_channel = padapter->registrypriv.channel;
316 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
317 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
321 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
323 memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
324 memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
326 if (pmlmeext->cur_channel > 14)
327 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
329 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
331 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
332 pmlmeext->sitesurvey_res.channel_idx = 0;
333 pmlmeext->sitesurvey_res.bss_cnt = 0;
334 pmlmeext->scan_abort = false;
336 pmlmeinfo->state = WIFI_FW_NULL_STATE;
337 pmlmeinfo->reauth_count = 0;
338 pmlmeinfo->reassoc_count = 0;
339 pmlmeinfo->link_count = 0;
340 pmlmeinfo->auth_seq = 0;
341 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
342 pmlmeinfo->key_index = 0;
345 pmlmeinfo->enc_algo = _NO_PRIVACY_;
346 pmlmeinfo->authModeToggle = 0;
348 memset(pmlmeinfo->chg_txt, 0, 128);
350 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
351 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
353 pmlmeinfo->dialogToken = 0;
355 pmlmeext->action_public_rxseq = 0xffff;
356 pmlmeext->action_public_dialog_token = 0xff;
359 static int has_channel(struct rt_channel_info *channel_set,
360 u8 chanset_size, u8 chan) {
363 for (i = 0; i < chanset_size; i++) {
364 if (channel_set[i].ChannelNum == chan)
371 static void init_channel_list(struct rtw_adapter *padapter,
372 struct rt_channel_info *channel_set,
374 struct p2p_channels *channel_list) {
376 struct p2p_oper_class_map op_class[] = {
377 { IEEE80211G, 81, 1, 13, 1, BW20 },
378 { IEEE80211G, 82, 14, 14, 1, BW20 },
379 { IEEE80211A, 115, 36, 48, 4, BW20 },
380 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
381 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
382 { IEEE80211A, 124, 149, 161, 4, BW20 },
383 { IEEE80211A, 125, 149, 169, 4, BW20 },
384 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
385 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
386 { -1, 0, 0, 0, 0, BW20 }
393 for (op = 0; op_class[op].op_class; op++) {
395 struct p2p_oper_class_map *o = &op_class[op];
396 struct p2p_reg_class *reg = NULL;
398 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
399 if (!has_channel(channel_set, chanset_size, ch))
402 if ((0 == padapter->registrypriv.ht_enable) &&
406 if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) &&
407 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
411 reg = &channel_list->reg_class[cla];
413 reg->reg_class = o->op_class;
416 reg->channel[reg->channels] = ch;
420 channel_list->reg_classes = cla;
423 static u8 init_channel_set(struct rtw_adapter* padapter, u8 cplan,
424 struct rt_channel_info *c_set)
427 u8 b5GBand = false, b2_4GBand = false;
428 u8 Index2G = 0, Index5G = 0;
430 memset(c_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM);
432 if (cplan >= RT_CHANNEL_DOMAIN_MAX &&
433 cplan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) {
434 DBG_8723A("ChannelPlan ID %x error !!!!!\n", cplan);
438 if (padapter->registrypriv.wireless_mode & WIRELESS_11G) {
440 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
441 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
443 Index2G = RTW_ChannelPlanMap[cplan].Index2G;
446 if (padapter->registrypriv.wireless_mode & WIRELESS_11A) {
448 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
449 Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
451 Index5G = RTW_ChannelPlanMap[cplan].Index5G;
455 for (i = 0; i < RTW_ChannelPlan2G[Index2G].Len; i++) {
456 c_set[ch_size].ChannelNum =
457 RTW_ChannelPlan2G[Index2G].Channel[i];
459 if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == cplan) ||
460 /* Channel 1~11 is active, and 12~14 is passive */
461 RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == cplan) {
462 if (c_set[ch_size].ChannelNum >= 1 &&
463 c_set[ch_size].ChannelNum <= 11)
464 c_set[ch_size].ScanType = SCAN_ACTIVE;
465 else if (c_set[ch_size].ChannelNum >= 12 &&
466 c_set[ch_size].ChannelNum <= 14)
467 c_set[ch_size].ScanType = SCAN_PASSIVE;
468 } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == cplan ||
469 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == cplan ||
470 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) {
471 /* channel 12~13, passive scan */
472 if (c_set[ch_size].ChannelNum <= 11)
473 c_set[ch_size].ScanType = SCAN_ACTIVE;
475 c_set[ch_size].ScanType = SCAN_PASSIVE;
477 c_set[ch_size].ScanType = SCAN_ACTIVE;
484 for (i = 0; i < RTW_ChannelPlan5G[Index5G].Len; i++) {
485 if (RTW_ChannelPlan5G[Index5G].Channel[i] <= 48 ||
486 RTW_ChannelPlan5G[Index5G].Channel[i] >= 149) {
487 c_set[ch_size].ChannelNum =
488 RTW_ChannelPlan5G[Index5G].Channel[i];
489 if (RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == cplan) {
490 /* passive scan for all 5G channels */
491 c_set[ch_size].ScanType =
494 c_set[ch_size].ScanType =
496 DBG_8723A("%s(): channel_set[%d].ChannelNum = "
497 "%d\n", __func__, ch_size,
498 c_set[ch_size].ChannelNum);
507 int init_mlme_ext_priv23a(struct rtw_adapter* padapter)
510 struct registry_priv* pregistrypriv = &padapter->registrypriv;
511 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
512 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
513 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
515 pmlmeext->padapter = padapter;
517 init_mlme_ext_priv23a_value(padapter);
518 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
520 init_mlme_ext_timer23a(padapter);
522 #ifdef CONFIG_8723AU_AP_MODE
523 init_mlme_ap_info23a(padapter);
526 pmlmeext->max_chan_nums = init_channel_set(padapter,
527 pmlmepriv->ChannelPlan,
528 pmlmeext->channel_set);
529 init_channel_list(padapter, pmlmeext->channel_set,
530 pmlmeext->max_chan_nums, &pmlmeext->channel_list);
532 pmlmeext->chan_scan_time = SURVEY_TO;
533 pmlmeext->mlmeext_init = true;
535 pmlmeext->active_keep_alive_check = true;
539 void free_mlme_ext_priv23a (struct mlme_ext_priv *pmlmeext)
541 struct rtw_adapter *padapter = pmlmeext->padapter;
546 if (padapter->bDriverStopped == true) {
547 del_timer_sync(&pmlmeext->survey_timer);
548 del_timer_sync(&pmlmeext->link_timer);
549 /* del_timer_sync(&pmlmeext->ADDBA_timer); */
554 _mgt_dispatcher23a(struct rtw_adapter *padapter, struct mlme_handler *ptable,
555 struct recv_frame *precv_frame)
557 struct sk_buff *skb = precv_frame->pkt;
558 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
561 /* receive the frames that ra(a1) is my address
562 or ra(a1) is bc address. */
563 if (!ether_addr_equal(hdr->addr1, myid(&padapter->eeprompriv))&&
564 !is_broadcast_ether_addr(hdr->addr1))
567 ptable->func(padapter, precv_frame);
571 void mgt_dispatcher23a(struct rtw_adapter *padapter,
572 struct recv_frame *precv_frame)
574 struct mlme_handler *ptable;
575 #ifdef CONFIG_8723AU_AP_MODE
576 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
577 #endif /* CONFIG_8723AU_AP_MODE */
578 struct sk_buff *skb = precv_frame->pkt;
579 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
580 struct sta_info *psta;
584 if (!ieee80211_is_mgmt(mgmt->frame_control))
587 /* receive the frames that ra(a1) is my address or ra(a1) is
589 if (!ether_addr_equal(mgmt->da, myid(&padapter->eeprompriv)) &&
590 !is_broadcast_ether_addr(mgmt->da))
593 ptable = mlme_sta_tbl;
595 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
599 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
600 ("Currently we do not support reserved sub-fr-type ="
606 psta = rtw_get_stainfo23a(&padapter->stapriv, mgmt->sa);
609 if (ieee80211_has_retry(mgmt->frame_control)) {
610 if (precv_frame->attrib.seq_num ==
611 psta->RxMgmtFrameSeqNum) {
612 /* drop the duplicate management frame */
613 DBG_8723A("Drop duplicate management frame "
614 "with seq_num = %d.\n",
615 precv_frame->attrib.seq_num);
619 psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num;
622 #ifdef CONFIG_8723AU_AP_MODE
625 case IEEE80211_STYPE_AUTH:
626 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
627 ptable->func = &OnAuth23a;
629 ptable->func = &OnAuth23aClient23a;
631 case IEEE80211_STYPE_ASSOC_REQ:
632 case IEEE80211_STYPE_REASSOC_REQ:
633 _mgt_dispatcher23a(padapter, ptable, precv_frame);
635 case IEEE80211_STYPE_PROBE_REQ:
636 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
637 _mgt_dispatcher23a(padapter, ptable, precv_frame);
639 _mgt_dispatcher23a(padapter, ptable, precv_frame);
641 case IEEE80211_STYPE_BEACON:
642 _mgt_dispatcher23a(padapter, ptable, precv_frame);
644 case IEEE80211_STYPE_ACTION:
645 /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) */
646 _mgt_dispatcher23a(padapter, ptable, precv_frame);
649 _mgt_dispatcher23a(padapter, ptable, precv_frame);
653 _mgt_dispatcher23a(padapter, ptable, precv_frame);
657 /****************************************************************************
659 Following are the callback functions for each subtype of the management frames
661 *****************************************************************************/
664 OnProbeReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
667 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
668 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
669 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
670 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
671 struct sk_buff *skb = precv_frame->pkt;
672 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
675 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
678 if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
679 !check_fwstate(pmlmepriv,
680 WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
683 if (unlikely(!ieee80211_is_probe_req(mgmt->frame_control))) {
684 printk(KERN_WARNING "%s: Received non probe request frame\n",
689 len -= offsetof(struct ieee80211_mgmt, u.probe_req.variable);
691 ie = cfg80211_find_ie(WLAN_EID_SSID, mgmt->u.probe_req.variable, len);
693 /* check (wildcard) SSID */
697 if ((ie[1] && memcmp(ie + 2, cur->Ssid.ssid, cur->Ssid.ssid_len)) ||
698 (ie[1] == 0 && pmlmeinfo->hidden_ssid_mode)) {
702 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
703 pmlmepriv->cur_network.join_res)
704 issue_probersp23a(padapter, mgmt->sa, false);
711 OnProbeRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
713 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
715 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
716 report_survey_event23a(padapter, precv_frame);
724 OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
727 struct sta_info *psta;
728 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
729 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
730 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
731 struct sta_priv *pstapriv = &padapter->stapriv;
732 struct sk_buff *skb = precv_frame->pkt;
733 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
734 u8 *pframe = skb->data;
735 int pkt_len = skb->len;
736 struct wlan_bssid_ex *pbss;
742 pie = mgmt->u.beacon.variable;
743 pie_len = pkt_len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
744 p = rtw_get_ie23a(pie, WLAN_EID_EXT_SUPP_RATES, &ielen, pie_len);
745 if (p && ielen > 0) {
746 if (p[1 + ielen] == 0x2D && p[2 + ielen] != 0x2D) {
747 /* Invalid value 0x2D is detected in Extended Supported
748 * Rates (ESR) IE. Try to fix the IE length to avoid
749 * failed Beacon parsing.
751 DBG_8723A("[WIFIDBG] Error in ESR IE is detected in "
752 "Beacon of BSSID: %pM. Fix the length of "
753 "ESR IE to avoid failed Beacon parsing.\n",
759 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
760 report_survey_event23a(padapter, precv_frame);
764 if (!ether_addr_equal(mgmt->bssid,
765 get_my_bssid23a(&pmlmeinfo->network)))
768 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
769 /* we should update current network before auth,
770 or some IE is wrong */
771 pbss = (struct wlan_bssid_ex *)
772 kmalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
774 if (collect_bss_info23a(padapter, precv_frame, pbss) ==
777 &pmlmepriv->cur_network.network, pbss,
779 rtw_get_bcn_info23a(&pmlmepriv->cur_network);
784 /* check the vendor of the assoc AP */
785 pmlmeinfo->assoc_AP_vendor =
786 check_assoc_AP23a((u8 *)&mgmt->u.beacon, pkt_len -
787 offsetof(struct ieee80211_mgmt, u));
789 /* update TSF Value */
790 rtw_update_TSF(pmlmeext, mgmt);
793 start_clnt_auth23a(padapter);
798 if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) &&
799 (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
800 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
802 ret = rtw_check_bcn_info23a(padapter, mgmt, pkt_len);
804 DBG_8723A_LEVEL(_drv_always_, "ap has changed, "
806 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress, 65535);
809 /* update WMM, ERP in the beacon */
810 /* todo: the timer is used instead of
811 the number of the beacon received */
812 if ((sta_rx_pkts(psta) & 0xf) == 0) {
813 /* DBG_8723A("update_bcn_info\n"); */
814 update_beacon23a_info(padapter, pframe,
818 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
819 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
821 /* update WMM, ERP in the beacon */
822 /* todo: the timer is used instead of the
823 number of the beacon received */
824 if ((sta_rx_pkts(psta) & 0xf) == 0) {
825 /* DBG_8723A("update_bcn_info\n"); */
826 update_beacon23a_info(padapter, pframe,
830 /* allocate a new CAM entry for IBSS station */
831 cam_idx = allocate_fw_sta_entry23a(padapter);
832 if (cam_idx == NUM_STA)
835 /* get supported rate */
836 if (update_sta_support_rate23a(padapter, pie, pie_len,
838 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
842 /* update TSF Value */
843 rtw_update_TSF(pmlmeext, mgmt);
845 /* report sta add event */
846 report_add_sta_event23a(padapter, mgmt->sa,
857 OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
859 #ifdef CONFIG_8723AU_AP_MODE
860 static struct sta_info stat;
861 struct sta_info *pstat = NULL;
862 struct sta_priv *pstapriv = &padapter->stapriv;
863 struct security_priv *psecuritypriv = &padapter->securitypriv;
864 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
865 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
866 struct sk_buff *skb = precv_frame->pkt;
867 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
871 u16 auth_mode, seq, algorithm;
872 int status, len = skb->len;
874 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
877 DBG_8723A("+OnAuth23a\n");
881 auth_mode = psecuritypriv->dot11AuthAlgrthm;
883 pframe = mgmt->u.auth.variable;
884 len = skb->len - offsetof(struct ieee80211_mgmt, u.auth.variable);
886 seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
887 algorithm = le16_to_cpu(mgmt->u.auth.auth_alg);
889 DBG_8723A("auth alg =%x, seq =%X\n", algorithm, seq);
891 if (auth_mode == 2 &&
892 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
893 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
896 /* rx a shared-key auth but shared not enabled, or */
897 /* rx a open-system auth but shared-key is enabled */
898 if ((algorithm != WLAN_AUTH_OPEN && auth_mode == 0) ||
899 (algorithm == WLAN_AUTH_OPEN && auth_mode == 1)) {
900 DBG_8723A("auth rejected due to bad alg [alg =%d, auth_mib "
901 "=%d] %02X%02X%02X%02X%02X%02X\n",
902 algorithm, auth_mode,
903 sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
905 status = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
910 if (rtw_access_ctrl23a(padapter, sa) == false) {
911 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
915 pstat = rtw_get_stainfo23a(pstapriv, sa);
917 /* allocate a new one */
918 DBG_8723A("going to alloc stainfo for sa ="MAC_FMT"\n",
920 pstat = rtw_alloc_stainfo23a(pstapriv, sa, GFP_ATOMIC);
922 DBG_8723A(" Exceed the upper limit of supported "
924 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
928 pstat->state = WIFI_FW_AUTH_NULL;
931 /* pstat->flags = 0; */
932 /* pstat->capability = 0; */
934 spin_lock_bh(&pstapriv->asoc_list_lock);
935 if (!list_empty(&pstat->asoc_list)) {
936 list_del_init(&pstat->asoc_list);
937 pstapriv->asoc_list_cnt--;
938 if (pstat->expire_to > 0) {
939 /* TODO: STA re_auth within expire_to */
942 spin_unlock_bh(&pstapriv->asoc_list_lock);
945 /* TODO: STA re_auth and auth timeout */
949 spin_lock_bh(&pstapriv->auth_list_lock);
950 if (list_empty(&pstat->auth_list)) {
951 list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
952 pstapriv->auth_list_cnt++;
954 spin_unlock_bh(&pstapriv->auth_list_lock);
956 if (pstat->auth_seq == 0)
957 pstat->expire_to = pstapriv->auth_to;
959 if ((pstat->auth_seq + 1) != seq) {
960 DBG_8723A("(1)auth rejected because out of seq [rx_seq =%d, "
961 "exp_seq =%d]!\n", seq, pstat->auth_seq+1);
962 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
966 if (algorithm == WLAN_AUTH_OPEN && (auth_mode == 0 || auth_mode == 2)) {
968 pstat->state &= ~WIFI_FW_AUTH_NULL;
969 pstat->state |= WIFI_FW_AUTH_SUCCESS;
970 pstat->expire_to = pstapriv->assoc_to;
971 pstat->authalg = algorithm;
973 DBG_8723A("(2)auth rejected because out of seq "
974 "[rx_seq =%d, exp_seq =%d]!\n",
975 seq, pstat->auth_seq+1);
976 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
979 } else { /* shared system or auto authentication */
981 /* prepare for the challenging txt... */
982 pstat->state &= ~WIFI_FW_AUTH_NULL;
983 pstat->state |= WIFI_FW_AUTH_STATE;
984 pstat->authalg = algorithm;
986 } else if (seq == 3) {
987 /* checking for challenging txt... */
988 DBG_8723A("checking for challenging txt...\n");
990 p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pframe, len);
991 if (!p || p[1] <= 0) {
992 DBG_8723A("auth rejected because challenge "
994 status = WLAN_STATUS_CHALLENGE_FAIL;
998 if (!memcmp(p + 2, pstat->chg_txt, 128)) {
999 pstat->state &= ~WIFI_FW_AUTH_STATE;
1000 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1001 /* challenging txt is correct... */
1002 pstat->expire_to = pstapriv->assoc_to;
1004 DBG_8723A("auth rejected because challenge "
1006 status = WLAN_STATUS_CHALLENGE_FAIL;
1010 DBG_8723A("(3)auth rejected because out of seq "
1011 "[rx_seq =%d, exp_seq =%d]!\n",
1012 seq, pstat->auth_seq+1);
1013 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1018 /* Now, we are going to issue_auth23a... */
1019 pstat->auth_seq = seq + 1;
1021 issue_auth23a(padapter, pstat, WLAN_STATUS_SUCCESS);
1023 if (pstat->state & WIFI_FW_AUTH_SUCCESS)
1024 pstat->auth_seq = 0;
1031 rtw_free_stainfo23a(padapter, pstat);
1034 memset((char *)pstat, '\0', sizeof(stat));
1035 pstat->auth_seq = 2;
1036 memcpy(pstat->hwaddr, sa, 6);
1038 issue_auth23a(padapter, pstat, (unsigned short)status);
1045 OnAuth23aClient23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1047 unsigned int seq, status, algthm;
1048 unsigned int go2asoc = 0;
1049 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1050 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1051 struct sk_buff *skb = precv_frame->pkt;
1052 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1055 int plen = skb->len;
1057 DBG_8723A("%s\n", __func__);
1059 /* check A1 matches or not */
1060 if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
1063 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
1066 pie = mgmt->u.auth.variable;
1067 plen -= offsetof(struct ieee80211_mgmt, u.auth.variable);
1069 algthm = le16_to_cpu(mgmt->u.auth.auth_alg);
1070 seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
1071 status = le16_to_cpu(mgmt->u.auth.status_code);
1074 DBG_8723A("clnt auth fail, status: %d\n", status);
1075 /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
1076 if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
1077 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1078 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1080 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
1081 /* pmlmeinfo->reauth_count = 0; */
1084 set_link_timer(pmlmeext, 1);
1089 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
1090 /* legendary shared system */
1091 p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pie, plen);
1094 /* DBG_8723A("marc: no challenge text?\n"); */
1098 memcpy((void *)(pmlmeinfo->chg_txt), p + 2, p[1]);
1099 pmlmeinfo->auth_seq = 3;
1100 issue_auth23a(padapter, NULL, 0);
1101 set_link_timer(pmlmeext, REAUTH_TO);
1108 } else if (seq == 4) {
1109 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1114 /* this is also illegal */
1115 /* DBG_8723A("marc: clnt auth failed due to illegal seq =%x\n",
1121 DBG_8723A_LEVEL(_drv_always_, "auth success, start assoc\n");
1122 start_clnt_assoc23a(padapter);
1128 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
1133 #ifdef CONFIG_8723AU_AP_MODE
1134 static int rtw_validate_vendor_specific_ies(const u8 *pos, int elen)
1138 /* first 3 bytes in vendor specific information element are the IEEE
1139 * OUI of the vendor. The following byte is used a vendor specific
1142 DBG_8723A("short vendor specific information element "
1143 "ignored (len =%i)\n", elen);
1147 oui = RTW_GET_BE24(pos);
1149 case WLAN_OUI_MICROSOFT:
1150 /* Microsoft/Wi-Fi information elements are further typed and
1154 /* Microsoft OUI (00:50:F2) with OUI Type 1:
1155 * real WPA information element */
1157 case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */
1159 DBG_8723A("short WME information element "
1160 "ignored (len =%i)\n", elen);
1164 case WME_OUI_SUBTYPE_INFORMATION_ELEMENT:
1165 case WME_OUI_SUBTYPE_PARAMETER_ELEMENT:
1167 case WME_OUI_SUBTYPE_TSPEC_ELEMENT:
1170 DBG_8723A("unknown WME information element "
1171 "ignored (subtype =%d len =%i)\n",
1177 /* Wi-Fi Protected Setup (WPS) IE */
1180 DBG_8723A("Unknown Microsoft information element "
1181 "ignored (type =%d len =%i)\n",
1189 case VENDOR_HT_CAPAB_OUI_TYPE:
1192 DBG_8723A("Unknown Broadcom information element "
1193 "ignored (type =%d len =%i)\n", pos[3], elen);
1199 DBG_8723A("unknown vendor specific information element "
1200 "ignored (vendor OUI %02x:%02x:%02x len =%i)\n",
1201 pos[0], pos[1], pos[2], elen);
1208 static int rtw_validate_frame_ies(const u8 *start, uint len)
1210 const u8 *pos = start;
1222 DBG_8723A("%s: IEEE 802.11 failed (id =%d elen =%d "
1223 "left =%i)\n", __func__, id, elen, left);
1229 case WLAN_EID_SUPP_RATES:
1230 case WLAN_EID_FH_PARAMS:
1231 case WLAN_EID_DS_PARAMS:
1232 case WLAN_EID_CF_PARAMS:
1234 case WLAN_EID_IBSS_PARAMS:
1235 case WLAN_EID_CHALLENGE:
1236 case WLAN_EID_ERP_INFO:
1237 case WLAN_EID_EXT_SUPP_RATES:
1238 case WLAN_EID_VENDOR_SPECIFIC:
1239 if (rtw_validate_vendor_specific_ies(pos, elen))
1243 case WLAN_EID_PWR_CAPABILITY:
1244 case WLAN_EID_SUPPORTED_CHANNELS:
1245 case WLAN_EID_MOBILITY_DOMAIN:
1246 case WLAN_EID_FAST_BSS_TRANSITION:
1247 case WLAN_EID_TIMEOUT_INTERVAL:
1248 case WLAN_EID_HT_CAPABILITY:
1249 case WLAN_EID_HT_OPERATION:
1252 DBG_8723A("%s IEEE 802.11 ignored unknown element "
1253 "(id =%d elen =%d)\n", __func__, id, elen);
1269 OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1271 #ifdef CONFIG_8723AU_AP_MODE
1272 u16 capab_info, listen_interval;
1273 struct sta_info *pstat;
1274 unsigned char reassoc;
1275 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
1276 int i, wpa_ie_len, left;
1277 unsigned char supportRate[16];
1279 unsigned short status = WLAN_STATUS_SUCCESS;
1280 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1281 struct security_priv *psecuritypriv = &padapter->securitypriv;
1282 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1283 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1284 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
1285 struct sta_priv *pstapriv = &padapter->stapriv;
1286 struct sk_buff *skb = precv_frame->pkt;
1287 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1288 const u8 *pos, *p, *wpa_ie, *wps_ie;
1289 u8 *pframe = skb->data;
1290 uint pkt_len = skb->len;
1293 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
1296 left = pkt_len - sizeof(struct ieee80211_hdr_3addr);
1297 if (ieee80211_is_assoc_req(mgmt->frame_control)) {
1299 pos = mgmt->u.assoc_req.variable;
1300 left -= offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
1301 } else { /* WIFI_REASSOCREQ */
1303 pos = mgmt->u.reassoc_req.variable;
1304 left -= offsetof(struct ieee80211_mgmt, u.reassoc_req.variable);
1308 DBG_8723A("handle_assoc(reassoc =%d) - too short payload "
1309 "(len =%lu)\n", reassoc, (unsigned long)pkt_len);
1313 pstat = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1315 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1316 goto asoc_class2_error;
1319 /* These two are located at the same offsets whether it's an
1320 * assoc_req or a reassoc_req */
1321 capab_info = get_unaligned_le16(&mgmt->u.assoc_req.capab_info);
1323 get_unaligned_le16(&mgmt->u.assoc_req.listen_interval);
1325 DBG_8723A("%s\n", __func__);
1327 /* check if this stat has been successfully authenticated/assocated */
1328 if (!(pstat->state & WIFI_FW_AUTH_SUCCESS)) {
1329 if (!(pstat->state & WIFI_FW_ASSOC_SUCCESS)) {
1330 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1331 goto asoc_class2_error;
1333 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
1334 pstat->state |= WIFI_FW_ASSOC_STATE;
1337 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1338 pstat->state |= WIFI_FW_ASSOC_STATE;
1341 pstat->capability = capab_info;
1343 /* now parse all ieee802_11 ie to point to elems */
1345 if (rtw_validate_frame_ies(pos, left)) {
1346 DBG_8723A("STA " MAC_FMT " sent invalid association request\n",
1347 MAC_ARG(pstat->hwaddr));
1348 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1349 goto OnAssocReq23aFail;
1352 /* now we should check all the fields... */
1354 p = cfg80211_find_ie(WLAN_EID_SSID, pos, left);
1355 if (!p || p[1] == 0) {
1356 /* broadcast ssid, however it is not allowed in assocreq */
1357 DBG_8723A("STA " MAC_FMT " sent invalid association request "
1358 "lacking an SSID\n", MAC_ARG(pstat->hwaddr));
1359 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1360 goto OnAssocReq23aFail;
1362 /* check if ssid match */
1363 if (memcmp(p + 2, cur->Ssid.ssid, cur->Ssid.ssid_len))
1364 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1366 if (p[1] != cur->Ssid.ssid_len)
1367 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1370 if (status != WLAN_STATUS_SUCCESS)
1371 goto OnAssocReq23aFail;
1373 /* check if the supported rate is ok */
1374 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, pos, left);
1376 DBG_8723A("Rx a sta assoc-req which supported rate is "
1378 /* use our own rate set as statoin used */
1379 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
1380 /* supportRateNum = AP_BSSRATE_LEN; */
1382 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1383 goto OnAssocReq23aFail;
1385 memcpy(supportRate, p + 2, p[1]);
1386 supportRateNum = p[1];
1388 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, pos, left);
1390 if (supportRateNum <= sizeof(supportRate)) {
1391 memcpy(supportRate+supportRateNum, p + 2, p[1]);
1392 supportRateNum += p[1];
1397 /* todo: mask supportRate between AP & STA -> move to update raid */
1398 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
1400 /* update station supportRate */
1401 pstat->bssratelen = supportRateNum;
1402 memcpy(pstat->bssrateset, supportRate, supportRateNum);
1403 Update23aTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
1405 /* check RSN/WPA/WPS */
1406 pstat->dot8021xalg = 0;
1408 pstat->wpa_group_cipher = 0;
1409 pstat->wpa2_group_cipher = 0;
1410 pstat->wpa_pairwise_cipher = 0;
1411 pstat->wpa2_pairwise_cipher = 0;
1412 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
1414 wpa_ie = cfg80211_find_ie(WLAN_EID_RSN, pos, left);
1416 wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1417 WLAN_OUI_TYPE_MICROSOFT_WPA,
1420 int group_cipher = 0, pairwise_cipher = 0;
1422 wpa_ie_len = wpa_ie[1];
1423 if (psecuritypriv->wpa_psk & BIT(1)) {
1424 r = rtw_parse_wpa2_ie23a(wpa_ie, wpa_ie_len + 2,
1426 &pairwise_cipher, NULL);
1427 if (r == _SUCCESS) {
1428 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1429 pstat->wpa_psk |= BIT(1);
1431 pstat->wpa2_group_cipher = group_cipher &
1432 psecuritypriv->wpa2_group_cipher;
1433 pstat->wpa2_pairwise_cipher = pairwise_cipher &
1434 psecuritypriv->wpa2_pairwise_cipher;
1436 status = WLAN_STATUS_INVALID_IE;
1437 } else if (psecuritypriv->wpa_psk & BIT(0)) {
1438 r = rtw_parse_wpa_ie23a(wpa_ie, wpa_ie_len + 2,
1439 &group_cipher, &pairwise_cipher,
1441 if (r == _SUCCESS) {
1442 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1443 pstat->wpa_psk |= BIT(0);
1445 pstat->wpa_group_cipher = group_cipher &
1446 psecuritypriv->wpa_group_cipher;
1447 pstat->wpa_pairwise_cipher = pairwise_cipher &
1448 psecuritypriv->wpa_pairwise_cipher;
1450 status = WLAN_STATUS_INVALID_IE;
1455 if (wpa_ie && status == WLAN_STATUS_SUCCESS) {
1456 if (!pstat->wpa_group_cipher)
1457 status = WLAN_STATUS_INVALID_GROUP_CIPHER;
1459 if (!pstat->wpa_pairwise_cipher)
1460 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
1464 if (status != WLAN_STATUS_SUCCESS)
1465 goto OnAssocReq23aFail;
1467 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
1469 wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1470 WLAN_OUI_TYPE_MICROSOFT_WPS,
1475 DBG_8723A("STA included WPS IE in (Re)Association "
1476 "Request - assume WPS is used\n");
1477 pstat->flags |= WLAN_STA_WPS;
1479 DBG_8723A("STA did not include WPA/RSN IE in (Re)"
1480 "Association Request - possible WPS use\n");
1481 pstat->flags |= WLAN_STA_MAYBE_WPS;
1484 /* AP support WPA/RSN, and sta is going to do WPS, but AP
1486 /* that the selected registrar of AP is _FLASE */
1487 if (psecuritypriv->wpa_psk > 0 &&
1488 pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)) {
1489 if (pmlmepriv->wps_beacon_ie) {
1490 u8 selected_registrar = 0;
1492 rtw_get_wps_attr_content23a(
1493 pmlmepriv->wps_beacon_ie,
1494 pmlmepriv->wps_beacon_ie_len,
1495 WPS_ATTR_SELECTED_REGISTRAR,
1496 &selected_registrar, NULL);
1498 if (!selected_registrar) {
1499 DBG_8723A("selected_registrar is false,"
1500 "or AP is not ready to do "
1503 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1504 goto OnAssocReq23aFail;
1511 if (psecuritypriv->wpa_psk == 0) {
1512 DBG_8723A("STA " MAC_FMT ": WPA/RSN IE in association "
1513 "request, but AP don't support WPA/RSN\n",
1514 MAC_ARG(pstat->hwaddr));
1516 status = WLAN_STATUS_INVALID_IE;
1518 goto OnAssocReq23aFail;
1522 DBG_8723A("STA included WPS IE in (Re)Association "
1523 "Request - WPS is used\n");
1524 pstat->flags |= WLAN_STA_WPS;
1527 copy_len = ((wpa_ie_len + 2) > sizeof(pstat->wpa_ie)) ?
1528 sizeof(pstat->wpa_ie) : (wpa_ie_len + 2);
1532 memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len);
1535 /* check if there is WMM IE & support WWM-PS */
1536 pstat->flags &= ~WLAN_STA_WME;
1537 pstat->qos_option = 0;
1538 pstat->qos_info = 0;
1539 pstat->has_legacy_ac = true;
1540 pstat->uapsd_vo = 0;
1541 pstat->uapsd_vi = 0;
1542 pstat->uapsd_be = 0;
1543 pstat->uapsd_bk = 0;
1544 if (pmlmepriv->qos_option) {
1545 const u8 *end = pos + left;
1550 p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p, left);
1552 if (!memcmp(p + 2, WMM_IE, 6)) {
1553 pstat->flags |= WLAN_STA_WME;
1555 pstat->qos_option = 1;
1556 pstat->qos_info = *(p + 8);
1559 (pstat->qos_info >> 5) & 0x3;
1561 if ((pstat->qos_info & 0xf) != 0xf)
1562 pstat->has_legacy_ac = true;
1564 pstat->has_legacy_ac = false;
1566 if (pstat->qos_info & 0xf) {
1567 if (pstat->qos_info & BIT(0))
1568 pstat->uapsd_vo = BIT(0)|BIT(1);
1570 pstat->uapsd_vo = 0;
1572 if (pstat->qos_info & BIT(1))
1573 pstat->uapsd_vi = BIT(0)|BIT(1);
1575 pstat->uapsd_vi = 0;
1577 if (pstat->qos_info & BIT(2))
1578 pstat->uapsd_bk = BIT(0)|BIT(1);
1580 pstat->uapsd_bk = 0;
1582 if (pstat->qos_info & BIT(3))
1583 pstat->uapsd_be = BIT(0)|BIT(1);
1585 pstat->uapsd_be = 0;
1598 /* save HT capabilities in the sta object */
1599 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
1600 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pos, left);
1602 if (p && p[1] >= sizeof(struct ieee80211_ht_cap)) {
1603 pstat->flags |= WLAN_STA_HT;
1605 pstat->flags |= WLAN_STA_WME;
1607 memcpy(&pstat->htpriv.ht_cap, p + 2,
1608 sizeof(struct ieee80211_ht_cap));
1610 pstat->flags &= ~WLAN_STA_HT;
1612 if (pmlmepriv->htpriv.ht_option == false && pstat->flags & WLAN_STA_HT){
1613 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1614 goto OnAssocReq23aFail;
1617 if (pstat->flags & WLAN_STA_HT &&
1618 (pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP ||
1619 pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) {
1620 DBG_8723A("HT: " MAC_FMT " tried to use TKIP with HT "
1621 "association\n", MAC_ARG(pstat->hwaddr));
1623 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
1624 /* goto OnAssocReq23aFail; */
1627 pstat->flags |= WLAN_STA_NONERP;
1628 for (i = 0; i < pstat->bssratelen; i++) {
1629 if ((pstat->bssrateset[i] & 0x7f) > 22) {
1630 pstat->flags &= ~WLAN_STA_NONERP;
1635 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1636 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
1638 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1640 if (status != WLAN_STATUS_SUCCESS)
1641 goto OnAssocReq23aFail;
1643 /* TODO: identify_proprietary_vendor_ie(); */
1644 /* Realtek proprietary IE */
1645 /* identify if this is Broadcom sta */
1646 /* identify if this is ralink sta */
1647 /* Customer proprietary IE */
1649 /* get a unique AID */
1650 if (pstat->aid > 0) {
1651 DBG_8723A(" old AID %d\n", pstat->aid);
1653 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
1654 if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
1657 if (pstat->aid > NUM_STA)
1658 pstat->aid = NUM_STA;
1659 if (pstat->aid > pstapriv->max_num_sta) {
1663 DBG_8723A(" no room for more AIDs\n");
1665 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1667 goto OnAssocReq23aFail;
1669 pstapriv->sta_aid[pstat->aid - 1] = pstat;
1670 DBG_8723A("allocate new AID = (%d)\n", pstat->aid);
1674 pstat->state &= ~WIFI_FW_ASSOC_STATE;
1675 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
1677 spin_lock_bh(&pstapriv->auth_list_lock);
1678 if (!list_empty(&pstat->auth_list)) {
1679 list_del_init(&pstat->auth_list);
1680 pstapriv->auth_list_cnt--;
1682 spin_unlock_bh(&pstapriv->auth_list_lock);
1684 spin_lock_bh(&pstapriv->asoc_list_lock);
1685 if (list_empty(&pstat->asoc_list)) {
1686 pstat->expire_to = pstapriv->expire_to;
1687 list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
1688 pstapriv->asoc_list_cnt++;
1690 spin_unlock_bh(&pstapriv->asoc_list_lock);
1692 /* now the station is qualified to join our BSS... */
1693 if (pstat && pstat->state & WIFI_FW_ASSOC_SUCCESS &&
1694 status == WLAN_STATUS_SUCCESS) {
1695 #ifdef CONFIG_8723AU_AP_MODE
1696 /* 1 bss_cap_update & sta_info_update23a */
1697 bss_cap_update_on_sta_join23a(padapter, pstat);
1698 sta_info_update23a(padapter, pstat);
1700 /* issue assoc rsp before notify station join event. */
1701 if (ieee80211_is_assoc_req(mgmt->frame_control))
1702 issue_asocrsp23a(padapter, status, pstat,
1705 issue_asocrsp23a(padapter, status, pstat,
1708 /* 2 - report to upper layer */
1709 DBG_8723A("indicate_sta_join_event to upper layer - hostapd\n");
1710 rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
1712 /* 3-(1) report sta add event */
1713 report_add_sta_event23a(padapter, pstat->hwaddr, pstat->aid);
1721 #ifdef CONFIG_8723AU_AP_MODE
1722 issue_deauth23a(padapter, mgmt->sa, status);
1728 #ifdef CONFIG_8723AU_AP_MODE
1730 if (ieee80211_is_assoc_req(mgmt->frame_control))
1731 issue_asocrsp23a(padapter, status, pstat, WIFI_ASSOCRSP);
1733 issue_asocrsp23a(padapter, status, pstat, WIFI_REASSOCRSP);
1736 #endif /* CONFIG_8723AU_AP_MODE */
1742 OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1744 struct ndis_802_11_var_ies *pIE;
1745 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1746 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1747 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1748 struct sk_buff *skb = precv_frame->pkt;
1749 struct ieee80211_mgmt *pmgmt = (struct ieee80211_mgmt *) skb->data;
1751 unsigned short status;
1752 u8 *pframe = skb->data;
1753 int pkt_len = skb->len;
1755 DBG_8723A("%s\n", __func__);
1757 /* check A1 matches or not */
1758 if (!ether_addr_equal(myid(&padapter->eeprompriv), pmgmt->da))
1761 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
1764 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1767 del_timer_sync(&pmlmeext->link_timer);
1770 status = le16_to_cpu(pmgmt->u.assoc_resp.status_code);
1772 DBG_8723A("assoc reject, status code: %d\n", status);
1773 pmlmeinfo->state = WIFI_FW_NULL_STATE;
1775 goto report_assoc_result;
1778 /* get capabilities */
1779 pmlmeinfo->capability = le16_to_cpu(pmgmt->u.assoc_resp.capab_info);
1782 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
1785 res = pmlmeinfo->aid = le16_to_cpu(pmgmt->u.assoc_resp.aid) & 0x3fff;
1787 /* following are moved to join event callback function */
1788 /* to handle HT, WMM, rate adaptive, update MAC reg */
1789 /* for not to handle the synchronous IO in the tasklet */
1790 for (i = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
1792 pIE = (struct ndis_802_11_var_ies *)(pframe + i);
1794 switch (pIE->ElementID)
1796 case WLAN_EID_VENDOR_SPECIFIC:
1797 if (!memcmp(pIE->data, WMM_PARA_OUI23A, 6))/* WMM */
1798 WMM_param_handler23a(padapter, pIE);
1801 case WLAN_EID_HT_CAPABILITY: /* HT caps */
1802 HT_caps_handler23a(padapter, pIE);
1805 case WLAN_EID_HT_OPERATION: /* HT info */
1806 HT_info_handler23a(padapter, pIE);
1809 case WLAN_EID_ERP_INFO:
1810 ERP_IE_handler23a(padapter, pIE);
1816 i += (pIE->Length + 2);
1819 pmlmeinfo->state &= ~WIFI_FW_ASSOC_STATE;
1820 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
1822 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
1823 UpdateBrateTbl23a(padapter, pmlmeinfo->network.SupportedRates);
1825 report_assoc_result:
1826 pmlmepriv->assoc_rsp_len = 0;
1828 kfree(pmlmepriv->assoc_rsp);
1829 pmlmepriv->assoc_rsp = kmalloc(pkt_len, GFP_ATOMIC);
1830 if (pmlmepriv->assoc_rsp) {
1831 memcpy(pmlmepriv->assoc_rsp, pframe, pkt_len);
1832 pmlmepriv->assoc_rsp_len = pkt_len;
1835 kfree(pmlmepriv->assoc_rsp);
1837 report_join_res23a(padapter, res);
1843 OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1845 unsigned short reason;
1846 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1847 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1848 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1849 struct sk_buff *skb = precv_frame->pkt;
1850 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1852 if (!ether_addr_equal(mgmt->bssid,
1853 get_my_bssid23a(&pmlmeinfo->network)))
1856 reason = le16_to_cpu(mgmt->u.deauth.reason_code);
1858 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1860 #ifdef CONFIG_8723AU_AP_MODE
1861 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
1862 struct sta_info *psta;
1863 struct sta_priv *pstapriv = &padapter->stapriv;
1865 DBG_8723A_LEVEL(_drv_always_, "ap recv deauth reason code(%d) "
1866 "sta:%pM\n", reason, mgmt->sa);
1868 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1872 spin_lock_bh(&pstapriv->asoc_list_lock);
1873 if (!list_empty(&psta->asoc_list)) {
1874 list_del_init(&psta->asoc_list);
1875 pstapriv->asoc_list_cnt--;
1876 updated = ap_free_sta23a(padapter, psta,
1879 spin_unlock_bh(&pstapriv->asoc_list_lock);
1881 associated_clients_update23a(padapter, updated);
1888 DBG_8723A_LEVEL(_drv_always_, "sta recv deauth reason code(%d) "
1889 "sta:%pM\n", reason, mgmt->bssid);
1891 receive_disconnect23a(padapter, mgmt->bssid, reason);
1893 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1899 OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1901 unsigned short reason;
1902 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1903 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1904 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1905 struct sk_buff *skb = precv_frame->pkt;
1906 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1908 if (!ether_addr_equal(mgmt->bssid,
1909 get_my_bssid23a(&pmlmeinfo->network)))
1912 reason = le16_to_cpu(mgmt->u.disassoc.reason_code);
1914 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1916 #ifdef CONFIG_8723AU_AP_MODE
1917 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1918 struct sta_info *psta;
1919 struct sta_priv *pstapriv = &padapter->stapriv;
1921 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason code(%d)"
1922 " sta:%pM\n", reason, mgmt->sa);
1924 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1928 spin_lock_bh(&pstapriv->asoc_list_lock);
1929 if (!list_empty(&psta->asoc_list)) {
1930 list_del_init(&psta->asoc_list);
1931 pstapriv->asoc_list_cnt--;
1932 updated = ap_free_sta23a(padapter, psta,
1935 spin_unlock_bh(&pstapriv->asoc_list_lock);
1937 associated_clients_update23a(padapter, updated);
1944 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason "
1945 "code(%d) sta:%pM\n", reason, mgmt->bssid);
1947 receive_disconnect23a(padapter, mgmt->bssid, reason);
1949 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1954 OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1956 DBG_8723A("%s\n", __func__);
1961 on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1967 OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1973 OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1978 static int OnAction23a_back23a(struct rtw_adapter *padapter,
1979 struct recv_frame *precv_frame)
1982 struct sta_info *psta = NULL;
1983 struct recv_reorder_ctrl *preorder_ctrl;
1984 unsigned char category, action;
1985 unsigned short tid, status, capab, params, reason_code = 0;
1986 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1987 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1988 struct sk_buff *skb = precv_frame->pkt;
1989 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1990 struct sta_priv *pstapriv = &padapter->stapriv;
1992 /* check RA matches or not */
1993 if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
1996 DBG_8723A("%s\n", __func__);
1998 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1999 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
2003 psta = rtw_get_stainfo23a(pstapriv, addr);
2008 category = mgmt->u.action.category;
2009 if (category == WLAN_CATEGORY_BACK) { /* representing Block Ack */
2010 if (!pmlmeinfo->HT_enable)
2012 /* action_code is located in the same place for all
2013 action events, so pick any */
2014 action = mgmt->u.action.u.wme_action.action_code;
2015 DBG_8723A("%s, action =%d\n", __func__, action);
2017 case WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
2018 memcpy(&pmlmeinfo->ADDBA_req,
2019 &mgmt->u.action.u.addba_req.dialog_token,
2020 sizeof(struct ADDBA_request));
2021 process_addba_req23a(padapter,
2022 (u8 *)&pmlmeinfo->ADDBA_req, addr);
2023 if (pmlmeinfo->bAcceptAddbaReq == true)
2024 issue_action_BA23a(padapter, addr,
2025 WLAN_ACTION_ADDBA_RESP, 0);
2027 /* reject ADDBA Req */
2028 issue_action_BA23a(padapter, addr,
2029 WLAN_ACTION_ADDBA_RESP, 37);
2032 case WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
2033 status = get_unaligned_le16(
2034 &mgmt->u.action.u.addba_resp.status);
2035 capab = get_unaligned_le16(
2036 &mgmt->u.action.u.addba_resp.capab);
2037 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
2038 if (status == 0) { /* successful */
2039 DBG_8723A("agg_enable for TID =%d\n", tid);
2040 psta->htpriv.agg_enable_bitmap |= 1 << tid;
2041 psta->htpriv.candidate_tid_bitmap &=
2044 psta->htpriv.agg_enable_bitmap &= ~CHKBIT(tid);
2047 case WLAN_ACTION_DELBA: /* DELBA */
2048 params = get_unaligned_le16(
2049 &mgmt->u.action.u.delba.params);
2052 if (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) {
2053 preorder_ctrl = &psta->recvreorder_ctrl[tid];
2054 preorder_ctrl->enable = false;
2055 preorder_ctrl->indicate_seq = 0xffff;
2057 psta->htpriv.agg_enable_bitmap &= ~(1 << tid);
2058 psta->htpriv.candidate_tid_bitmap &=
2061 reason_code = get_unaligned_le16(
2062 &mgmt->u.action.u.delba.reason_code);
2063 DBG_8723A("%s(): DELBA: %x(%x)\n", __func__,
2064 pmlmeinfo->agg_enable_bitmap, reason_code);
2065 /* todo: how to notify the host while receiving
2075 static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token)
2077 struct rtw_adapter *adapter = recv_frame->adapter;
2078 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
2079 struct sk_buff *skb = recv_frame->pkt;
2080 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2083 seq_ctrl = ((recv_frame->attrib.seq_num&0xffff) << 4) |
2084 (recv_frame->attrib.frag_num & 0xf);
2086 if (ieee80211_has_retry(hdr->frame_control)) {
2088 if ((seq_ctrl == mlmeext->action_public_rxseq) &&
2089 (token == mlmeext->action_public_dialog_token)) {
2090 DBG_8723A("%s(%s): seq_ctrl = 0x%x, "
2091 "rxseq = 0x%x, token:%d\n", __func__,
2092 adapter->pnetdev->name, seq_ctrl,
2093 mlmeext->action_public_rxseq, token);
2097 if (seq_ctrl == mlmeext->action_public_rxseq) {
2098 DBG_8723A("%s(%s): seq_ctrl = 0x%x, "
2099 "rxseq = 0x%x\n", __func__,
2100 adapter->pnetdev->name, seq_ctrl,
2101 mlmeext->action_public_rxseq);
2107 mlmeext->action_public_rxseq = seq_ctrl;
2110 mlmeext->action_public_dialog_token = token;
2115 static unsigned int on_action_public23a_p2p(struct recv_frame *precv_frame)
2117 struct sk_buff *skb = precv_frame->pkt;
2118 u8 *pframe = skb->data;
2122 frame_body = (unsigned char *)
2123 (pframe + sizeof(struct ieee80211_hdr_3addr));
2125 dialogToken = frame_body[7];
2127 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
2133 static unsigned int on_action_public23a_vendor(struct recv_frame *precv_frame)
2135 unsigned int ret = _FAIL;
2136 struct sk_buff *skb = precv_frame->pkt;
2137 u8 *pframe = skb->data;
2138 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2140 if (!memcmp(frame_body + 2, P2P_OUI23A, 4)) {
2141 ret = on_action_public23a_p2p(precv_frame);
2148 on_action_public23a_default(struct recv_frame *precv_frame, u8 action)
2150 unsigned int ret = _FAIL;
2151 struct sk_buff *skb = precv_frame->pkt;
2152 u8 *pframe = skb->data;
2153 uint frame_len = skb->len;
2154 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2156 struct rtw_adapter *adapter = precv_frame->adapter;
2160 token = frame_body[2];
2162 if (rtw_action_public_decache(precv_frame, token) == _FAIL)
2165 cnt += sprintf((msg+cnt), "%s(token:%u)",
2166 action_public_str23a(action), token);
2167 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
2175 static int on_action_public23a(struct rtw_adapter *padapter,
2176 struct recv_frame *precv_frame)
2178 unsigned int ret = _FAIL;
2179 struct sk_buff *skb = precv_frame->pkt;
2180 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2181 u8 *pframe = skb->data;
2182 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2183 u8 category, action;
2185 /* check RA matches or not */
2186 if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
2189 category = frame_body[0];
2190 if (category != WLAN_CATEGORY_PUBLIC)
2193 action = frame_body[1];
2195 case ACT_PUBLIC_VENDOR:
2196 ret = on_action_public23a_vendor(precv_frame);
2199 ret = on_action_public23a_default(precv_frame, action);
2208 OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2214 OnAction23a_wmm(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2220 OnAction23a_p2p(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2226 OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2230 struct action_handler *ptable;
2231 struct sk_buff *skb = precv_frame->pkt;
2232 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
2234 category = mgmt->u.action.category;
2237 i < sizeof(OnAction23a_tbl) / sizeof(struct action_handler); i++) {
2238 ptable = &OnAction23a_tbl[i];
2240 if (category == ptable->num)
2241 ptable->func(padapter, precv_frame);
2247 static int DoReserved23a(struct rtw_adapter *padapter,
2248 struct recv_frame *precv_frame)
2253 struct xmit_frame *alloc_mgtxmitframe23a(struct xmit_priv *pxmitpriv)
2255 struct xmit_frame *pmgntframe;
2256 struct xmit_buf *pxmitbuf;
2258 pmgntframe = rtw_alloc_xmitframe23a_ext(pxmitpriv);
2261 DBG_8723A("%s(%s): alloc xmitframe fail\n", __func__,
2262 pxmitpriv->adapter->pnetdev->name);
2266 pxmitbuf = rtw_alloc_xmitbuf23a_ext(pxmitpriv);
2268 DBG_8723A("%s(%s): alloc xmitbuf fail\n", __func__,
2269 pxmitpriv->adapter->pnetdev->name);
2270 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
2275 pmgntframe->frame_tag = MGNT_FRAMETAG;
2276 pmgntframe->pxmitbuf = pxmitbuf;
2277 pmgntframe->buf_addr = pxmitbuf->pbuf;
2278 pxmitbuf->priv_data = pmgntframe;
2284 /****************************************************************************
2286 Following are some TX fuctions for WiFi MLME
2288 *****************************************************************************/
2290 void update_mgnt_tx_rate23a(struct rtw_adapter *padapter, u8 rate)
2292 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2294 pmlmeext->tx_rate = rate;
2295 DBG_8723A("%s(): rate = %x\n", __func__, rate);
2298 void update_mgntframe_attrib23a(struct rtw_adapter *padapter,
2299 struct pkt_attrib *pattrib)
2301 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2303 memset((u8 *)pattrib, 0, sizeof(struct pkt_attrib));
2305 pattrib->hdrlen = 24;
2306 pattrib->nr_frags = 1;
2307 pattrib->priority = 7;
2308 pattrib->mac_id = 0;
2309 pattrib->qsel = 0x12;
2311 pattrib->pktlen = 0;
2313 if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
2314 pattrib->raid = 6;/* b mode */
2316 pattrib->raid = 5;/* a/g mode */
2318 pattrib->encrypt = _NO_PRIVACY_;
2319 pattrib->bswenc = false;
2321 pattrib->qos_en = false;
2322 pattrib->ht_en = false;
2323 pattrib->bwmode = HT_CHANNEL_WIDTH_20;
2324 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2325 pattrib->sgi = false;
2327 pattrib->seqnum = pmlmeext->mgnt_seq;
2329 pattrib->retry_ctrl = true;
2332 void dump_mgntframe23a(struct rtw_adapter *padapter,
2333 struct xmit_frame *pmgntframe)
2335 if (padapter->bSurpriseRemoved == true ||
2336 padapter->bDriverStopped == true)
2339 rtw_hal_mgnt_xmit23a(padapter, pmgntframe);
2342 s32 dump_mgntframe23a_and_wait(struct rtw_adapter *padapter,
2343 struct xmit_frame *pmgntframe, int timeout_ms)
2347 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2348 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
2349 struct submit_ctx sctx;
2351 if (padapter->bSurpriseRemoved == true ||
2352 padapter->bDriverStopped == true)
2355 rtw_sctx_init23a(&sctx, timeout_ms);
2356 pxmitbuf->sctx = &sctx;
2358 ret = rtw_hal_mgnt_xmit23a(padapter, pmgntframe);
2360 if (ret == _SUCCESS)
2361 ret = rtw_sctx_wait23a(&sctx);
2363 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
2364 pxmitbuf->sctx = NULL;
2365 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
2370 s32 dump_mgntframe23a_and_wait_ack23a(struct rtw_adapter *padapter,
2371 struct xmit_frame *pmgntframe)
2374 u32 timeout_ms = 500;/* 500ms */
2375 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2377 if (padapter->bSurpriseRemoved == true ||
2378 padapter->bDriverStopped == true)
2381 mutex_lock(&pxmitpriv->ack_tx_mutex);
2382 pxmitpriv->ack_tx = true;
2384 pmgntframe->ack_report = 1;
2385 if (rtw_hal_mgnt_xmit23a(padapter, pmgntframe) == _SUCCESS) {
2386 ret = rtw_ack_tx_wait23a(pxmitpriv, timeout_ms);
2389 pxmitpriv->ack_tx = false;
2390 mutex_unlock(&pxmitpriv->ack_tx_mutex);
2395 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
2403 ssid_ie = rtw_get_ie23a(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
2405 /* DBG_8723A("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n",
2406 __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
2408 if (ssid_ie && ssid_len_ori > 0) {
2409 switch (hidden_ssid_mode)
2412 next_ie = ssid_ie + 2 + ssid_len_ori;
2415 remain_len = ies_len -(next_ie-ies);
2418 memcpy(ssid_ie+2, next_ie, remain_len);
2419 len_diff -= ssid_len_ori;
2423 memset(&ssid_ie[2], 0, ssid_len_ori);
2433 void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
2435 struct xmit_frame *pmgntframe;
2436 struct pkt_attrib *pattrib;
2437 unsigned char *pframe;
2438 struct ieee80211_hdr *pwlanhdr;
2440 unsigned int rate_len;
2441 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2442 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2443 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2444 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2445 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2446 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2452 /* DBG_8723A("%s\n", __func__); */
2454 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL) {
2455 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2458 #ifdef CONFIG_8723AU_AP_MODE
2459 spin_lock_bh(&pmlmepriv->bcn_update_lock);
2462 /* update attribute */
2463 pattrib = &pmgntframe->attrib;
2464 update_mgntframe_attrib23a(padapter, pattrib);
2465 pattrib->qsel = 0x10;
2467 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2469 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2470 pwlanhdr = (struct ieee80211_hdr *)pframe;
2472 fctrl = &pwlanhdr->frame_control;
2475 ether_addr_copy(pwlanhdr->addr1, bc_addr);
2476 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
2477 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(cur_network));
2479 SetSeqNum(pwlanhdr, 0 /*pmlmeext->mgnt_seq*/);
2480 /* pmlmeext->mgnt_seq++; */
2481 SetFrameSubType(pframe, WIFI_BEACON);
2483 pframe += sizeof(struct ieee80211_hdr_3addr);
2484 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2486 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
2487 /* DBG_8723A("ie len =%d\n", cur_network->IELength); */
2488 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2489 len_diff = update_hidden_ssid(pframe + _BEACON_IE_OFFSET_,
2490 cur_network->IELength -
2492 pmlmeinfo->hidden_ssid_mode);
2493 pframe += (cur_network->IELength+len_diff);
2494 pattrib->pktlen += (cur_network->IELength+len_diff);
2496 wps_ie = rtw_get_wps_ie23a(pmgntframe->buf_addr + TXDESC_OFFSET+
2497 sizeof (struct ieee80211_hdr_3addr) +
2498 _BEACON_IE_OFFSET_, pattrib->pktlen -
2499 sizeof (struct ieee80211_hdr_3addr) -
2500 _BEACON_IE_OFFSET_, NULL,
2502 if (wps_ie && wps_ielen > 0) {
2503 rtw_get_wps_attr_content23a(wps_ie, wps_ielen,
2504 WPS_ATTR_SELECTED_REGISTRAR,
2508 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
2510 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
2515 /* below for ad-hoc mode */
2517 /* timestamp will be inserted by hardware */
2519 pattrib->pktlen += 8;
2521 /* beacon interval: 2 bytes */
2523 memcpy(pframe, (unsigned char *)
2524 rtw_get_beacon_interval23a_from_ie(cur_network->IEs), 2);
2527 pattrib->pktlen += 2;
2529 /* capability info: 2 bytes */
2531 memcpy(pframe, (unsigned char *)
2532 rtw_get_capability23a_from_ie(cur_network->IEs), 2);
2535 pattrib->pktlen += 2;
2538 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2539 cur_network->Ssid.ssid_len,
2540 cur_network->Ssid.ssid, &pattrib->pktlen);
2542 /* supported rates... */
2543 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2544 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2545 ((rate_len > 8)? 8: rate_len),
2546 cur_network->SupportedRates, &pattrib->pktlen);
2548 /* DS parameter set */
2549 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)
2550 &cur_network->Configuration.DSConfig,
2553 /* if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
2557 /* IBSS Parameter Set... */
2558 /* ATIMWindow = cur->Configuration.ATIMWindow; */
2560 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2561 (unsigned char *)&ATIMWindow,
2565 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2566 &erpinfo, &pattrib->pktlen);
2569 /* EXTERNDED SUPPORTED RATE */
2571 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2573 cur_network->SupportedRates + 8,
2576 /* todo:HT for adhoc */
2580 #ifdef CONFIG_8723AU_AP_MODE
2581 pmlmepriv->update_bcn = false;
2583 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
2586 if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
2587 DBG_8723A("beacon frame too large\n");
2591 pattrib->last_txcmdsz = pattrib->pktlen;
2593 /* DBG_8723A("issue bcn_sz =%d\n", pattrib->last_txcmdsz); */
2595 dump_mgntframe23a_and_wait(padapter, pmgntframe, timeout_ms);
2597 dump_mgntframe23a(padapter, pmgntframe);
2600 void issue_probersp23a(struct rtw_adapter *padapter, unsigned char *da,
2601 u8 is_valid_p2p_probereq)
2603 struct xmit_frame *pmgntframe;
2604 struct pkt_attrib *pattrib;
2605 unsigned char *pframe;
2606 struct ieee80211_hdr *pwlanhdr;
2608 unsigned char *mac, *bssid;
2609 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2610 #ifdef CONFIG_8723AU_AP_MODE
2615 int ssid_ielen_diff;
2618 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2620 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2621 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2622 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2623 unsigned int rate_len;
2625 /* DBG_8723A("%s\n", __func__); */
2627 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2629 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2633 /* update attribute */
2634 pattrib = &pmgntframe->attrib;
2635 update_mgntframe_attrib23a(padapter, pattrib);
2637 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2639 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
2640 pwlanhdr = (struct ieee80211_hdr *)pframe;
2642 mac = myid(&padapter->eeprompriv);
2643 bssid = cur_network->MacAddress;
2645 fctrl = &pwlanhdr->frame_control;
2647 ether_addr_copy(pwlanhdr->addr1, da);
2648 ether_addr_copy(pwlanhdr->addr2, mac);
2649 ether_addr_copy(pwlanhdr->addr3, bssid);
2651 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2652 pmlmeext->mgnt_seq++;
2653 SetFrameSubType(fctrl, WIFI_PROBERSP);
2655 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2656 pattrib->pktlen = pattrib->hdrlen;
2657 pframe += pattrib->hdrlen;
2659 if (cur_network->IELength > MAX_IE_SZ)
2662 #ifdef CONFIG_8723AU_AP_MODE
2663 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
2664 pwps_ie = rtw_get_wps_ie23a(cur_network->IEs +
2666 cur_network->IELength -
2667 _FIXED_IE_LENGTH_, NULL,
2670 /* inerset & update wps_probe_resp_ie */
2671 if (pmlmepriv->wps_probe_resp_ie && pwps_ie && wps_ielen > 0) {
2672 uint wps_offset, remainder_ielen;
2675 wps_offset = (uint)(pwps_ie - cur_network->IEs);
2677 premainder_ie = pwps_ie + wps_ielen;
2679 remainder_ielen = cur_network->IELength - wps_offset -
2682 memcpy(pframe, cur_network->IEs, wps_offset);
2683 pframe += wps_offset;
2684 pattrib->pktlen += wps_offset;
2686 /* to get ie data len */
2687 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];
2688 if (wps_offset + wps_ielen + 2 <= MAX_IE_SZ) {
2689 memcpy(pframe, pmlmepriv->wps_probe_resp_ie,
2691 pframe += wps_ielen+2;
2692 pattrib->pktlen += wps_ielen+2;
2695 if (wps_offset + wps_ielen + 2 + remainder_ielen <=
2697 memcpy(pframe, premainder_ie, remainder_ielen);
2698 pframe += remainder_ielen;
2699 pattrib->pktlen += remainder_ielen;
2702 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2703 pframe += cur_network->IELength;
2704 pattrib->pktlen += cur_network->IELength;
2707 /* retrieve SSID IE from cur_network->Ssid */
2708 ies = pmgntframe->buf_addr + TXDESC_OFFSET +
2709 sizeof(struct ieee80211_hdr_3addr);
2711 ssid_ie = rtw_get_ie23a(ies + _FIXED_IE_LENGTH_, WLAN_EID_SSID,
2713 pframe - ies - _FIXED_IE_LENGTH_);
2715 ssid_ielen_diff = cur_network->Ssid.ssid_len - ssid_ielen;
2717 if (ssid_ie && cur_network->Ssid.ssid_len) {
2718 uint remainder_ielen;
2720 remainder_ie = ssid_ie + 2;
2721 remainder_ielen = pframe - remainder_ie;
2723 DBG_8723A_LEVEL(_drv_warning_, "%s(%s): "
2724 "remainder_ielen > MAX_IE_SZ\n",
2725 __func__, padapter->pnetdev->name);
2726 if (remainder_ielen > MAX_IE_SZ)
2727 remainder_ielen = MAX_IE_SZ;
2729 memcpy(buf, remainder_ie, remainder_ielen);
2730 memcpy(remainder_ie + ssid_ielen_diff, buf,
2732 *(ssid_ie + 1) = cur_network->Ssid.ssid_len;
2733 memcpy(ssid_ie + 2, cur_network->Ssid.ssid,
2734 cur_network->Ssid.ssid_len);
2736 pframe += ssid_ielen_diff;
2737 pattrib->pktlen += ssid_ielen_diff;
2743 /* timestamp will be inserted by hardware */
2745 pattrib->pktlen += 8;
2747 /* beacon interval: 2 bytes */
2749 memcpy(pframe, (unsigned char *)
2750 rtw_get_beacon_interval23a_from_ie(cur_network->IEs), 2);
2753 pattrib->pktlen += 2;
2755 /* capability info: 2 bytes */
2757 memcpy(pframe, (unsigned char *)
2758 rtw_get_capability23a_from_ie(cur_network->IEs), 2);
2761 pattrib->pktlen += 2;
2763 /* below for ad-hoc mode */
2766 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2767 cur_network->Ssid.ssid_len,
2768 cur_network->Ssid.ssid,
2771 /* supported rates... */
2772 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2773 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2774 ((rate_len > 8)? 8: rate_len),
2775 cur_network->SupportedRates,
2778 /* DS parameter set */
2779 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1,
2781 &cur_network->Configuration.DSConfig,
2784 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
2787 /* IBSS Parameter Set... */
2788 /* ATIMWindow = cur->Configuration.ATIMWindow; */
2790 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2791 (unsigned char *)&ATIMWindow,
2795 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2796 &erpinfo, &pattrib->pktlen);
2799 /* EXTERNDED SUPPORTED RATE */
2801 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2803 cur_network->SupportedRates + 8,
2806 /* todo:HT for adhoc */
2809 pattrib->last_txcmdsz = pattrib->pktlen;
2811 dump_mgntframe23a(padapter, pmgntframe);
2816 static int _issue_probereq23a(struct rtw_adapter *padapter,
2817 struct cfg80211_ssid *pssid, u8 *da, int wait_ack)
2820 struct xmit_frame *pmgntframe;
2821 struct pkt_attrib *pattrib;
2822 unsigned char *pframe;
2823 struct ieee80211_hdr *pwlanhdr;
2826 unsigned char bssrate[NumRates];
2827 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2828 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2829 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2830 int bssrate_len = 0;
2831 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2833 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2834 ("+issue_probereq23a\n"));
2836 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
2839 /* update attribute */
2840 pattrib = &pmgntframe->attrib;
2841 update_mgntframe_attrib23a(padapter, pattrib);
2843 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2845 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2846 pwlanhdr = (struct ieee80211_hdr *)pframe;
2848 mac = myid(&padapter->eeprompriv);
2850 fctrl = &pwlanhdr->frame_control;
2854 /* unicast probe request frame */
2855 ether_addr_copy(pwlanhdr->addr1, da);
2856 ether_addr_copy(pwlanhdr->addr3, da);
2858 /* broadcast probe request frame */
2859 ether_addr_copy(pwlanhdr->addr1, bc_addr);
2860 ether_addr_copy(pwlanhdr->addr3, bc_addr);
2863 ether_addr_copy(pwlanhdr->addr2, mac);
2865 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2866 pmlmeext->mgnt_seq++;
2867 SetFrameSubType(pframe, WIFI_PROBEREQ);
2869 pframe += sizeof (struct ieee80211_hdr_3addr);
2870 pattrib->pktlen = sizeof (struct ieee80211_hdr_3addr);
2873 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, pssid->ssid_len,
2874 pssid->ssid, &pattrib->pktlen);
2876 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, 0, NULL,
2879 get_rate_set23a(padapter, bssrate, &bssrate_len);
2881 if (bssrate_len > 8) {
2882 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
2883 bssrate, &pattrib->pktlen);
2884 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2885 (bssrate_len - 8), (bssrate + 8),
2888 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2889 bssrate_len, bssrate, &pattrib->pktlen);
2892 /* add wps_ie for wps2.0 */
2893 if (pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie) {
2894 memcpy(pframe, pmlmepriv->wps_probe_req_ie,
2895 pmlmepriv->wps_probe_req_ie_len);
2896 pframe += pmlmepriv->wps_probe_req_ie_len;
2897 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
2900 pattrib->last_txcmdsz = pattrib->pktlen;
2902 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2903 ("issuing probe_req, tx_len =%d\n", pattrib->last_txcmdsz));
2906 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
2908 dump_mgntframe23a(padapter, pmgntframe);
2916 inline void issue_probereq23a(struct rtw_adapter *padapter,
2917 struct cfg80211_ssid *pssid, u8 *da)
2919 _issue_probereq23a(padapter, pssid, da, false);
2922 int issue_probereq23a_ex23a(struct rtw_adapter *padapter,
2923 struct cfg80211_ssid *pssid, u8 *da,
2924 int try_cnt, int wait_ms)
2928 unsigned long start = jiffies;
2931 ret = _issue_probereq23a(padapter, pssid, da,
2932 wait_ms > 0 ? true : false);
2936 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
2939 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
2942 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
2949 if (try_cnt && wait_ms) {
2951 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
2952 "in %u ms\n", __func__,
2953 padapter->pnetdev->name,
2954 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
2955 ret == _SUCCESS?", acked":"", i, try_cnt,
2956 jiffies_to_msecs(jiffies - start));
2958 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
2959 __func__, padapter->pnetdev->name,
2960 rtw_get_oper_ch23a(padapter),
2961 ret == _SUCCESS?", acked":"", i, try_cnt,
2962 jiffies_to_msecs(jiffies - start));
2968 /* if psta == NULL, indiate we are station(client) now... */
2969 void issue_auth23a(struct rtw_adapter *padapter, struct sta_info *psta,
2970 unsigned short status)
2972 struct xmit_frame *pmgntframe;
2973 struct pkt_attrib *pattrib;
2974 unsigned char *pframe;
2975 struct ieee80211_hdr *pwlanhdr;
2978 unsigned short val16;
2979 int use_shared_key = 0;
2980 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2981 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2982 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2984 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
2987 /* update attribute */
2988 pattrib = &pmgntframe->attrib;
2989 update_mgntframe_attrib23a(padapter, pattrib);
2991 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2993 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2994 pwlanhdr = (struct ieee80211_hdr *)pframe;
2996 fctrl = &pwlanhdr->frame_control;
2999 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3000 pmlmeext->mgnt_seq++;
3001 SetFrameSubType(pframe, WIFI_AUTH);
3003 pframe += sizeof(struct ieee80211_hdr_3addr);
3004 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3006 if (psta) { /* for AP mode */
3007 #ifdef CONFIG_8723AU_AP_MODE
3009 ether_addr_copy(pwlanhdr->addr1, psta->hwaddr);
3010 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3011 ether_addr_copy(pwlanhdr->addr3, myid(&padapter->eeprompriv));
3013 /* setting auth algo number */
3014 val16 = (u16)psta->authalg;
3016 if (status != WLAN_STATUS_SUCCESS)
3020 val16 = cpu_to_le16(val16);
3024 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_ALGM_NUM_,
3025 (unsigned char *)&val16,
3028 /* setting auth seq number */
3029 val16 = (u16)psta->auth_seq;
3030 val16 = cpu_to_le16(val16);
3031 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_SEQ_NUM_,
3032 (unsigned char *)&val16,
3035 /* setting status code... */
3037 val16 = cpu_to_le16(val16);
3038 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
3039 (unsigned char *)&val16,
3042 /* added challenging text... */
3043 if ((psta->auth_seq == 2) &&
3044 (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
3045 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
3046 psta->chg_txt, &pattrib->pktlen);
3049 ether_addr_copy(pwlanhdr->addr1,
3050 get_my_bssid23a(&pmlmeinfo->network));
3051 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3052 ether_addr_copy(pwlanhdr->addr3,
3053 get_my_bssid23a(&pmlmeinfo->network));
3055 /* setting auth algo number */
3056 /* 0:OPEN System, 1:Shared key */
3057 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;
3059 val16 = cpu_to_le16(val16);
3062 /* DBG_8723A("%s auth_algo = %s auth_seq =%d\n", __func__,
3063 (pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED",
3064 pmlmeinfo->auth_seq); */
3066 /* setting IV for auth seq #3 */
3067 if ((pmlmeinfo->auth_seq == 3) &&
3068 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
3069 (use_shared_key == 1)) {
3070 /* DBG_8723A("==> iv(%d), key_index(%d)\n",
3071 pmlmeinfo->iv, pmlmeinfo->key_index); */
3072 val32 = ((pmlmeinfo->iv++) |
3073 (pmlmeinfo->key_index << 30));
3074 val32 = cpu_to_le32(val32);
3075 pframe = rtw_set_fixed_ie23a(pframe, 4,
3076 (unsigned char *)&val32,
3079 pattrib->iv_len = 4;
3082 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_ALGM_NUM_,
3083 (unsigned char *)&val16,
3086 /* setting auth seq number */
3087 val16 = pmlmeinfo->auth_seq;
3088 val16 = cpu_to_le16(val16);
3089 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_SEQ_NUM_,
3090 (unsigned char *)&val16,
3093 /* setting status code... */
3095 val16 = cpu_to_le16(val16);
3096 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
3097 (unsigned char *)&val16,
3100 /* then checking to see if sending challenging text... */
3101 if ((pmlmeinfo->auth_seq == 3) &&
3102 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
3103 (use_shared_key == 1)) {
3104 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
3110 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3112 pattrib->encrypt = _WEP40_;
3114 pattrib->icv_len = 4;
3116 pattrib->pktlen += pattrib->icv_len;
3120 pattrib->last_txcmdsz = pattrib->pktlen;
3122 rtw_wep_encrypt23a(padapter, pmgntframe);
3123 DBG_8723A("%s\n", __func__);
3124 dump_mgntframe23a(padapter, pmgntframe);
3129 void issue_asocrsp23a(struct rtw_adapter *padapter, unsigned short status,
3130 struct sta_info *pstat, int pkt_type)
3132 #ifdef CONFIG_8723AU_AP_MODE
3133 struct xmit_frame *pmgntframe;
3134 struct ieee80211_hdr *pwlanhdr;
3135 struct pkt_attrib *pattrib;
3136 unsigned char *pframe;
3138 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3139 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3140 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3141 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3142 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
3144 u8 *ie = pnetwork->IEs;
3146 DBG_8723A("%s\n", __func__);
3148 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3152 /* update attribute */
3153 pattrib = &pmgntframe->attrib;
3154 update_mgntframe_attrib23a(padapter, pattrib);
3156 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3158 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3159 pwlanhdr = (struct ieee80211_hdr *)pframe;
3161 pwlanhdr->frame_control = 0;
3163 ether_addr_copy(pwlanhdr->addr1, pstat->hwaddr);
3164 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3165 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3167 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3168 pmlmeext->mgnt_seq++;
3169 if (pkt_type == WIFI_ASSOCRSP || pkt_type == WIFI_REASSOCRSP)
3170 SetFrameSubType(pwlanhdr, pkt_type);
3174 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3175 pattrib->pktlen += pattrib->hdrlen;
3176 pframe += pattrib->hdrlen;
3179 val = *(unsigned short *)rtw_get_capability23a_from_ie(ie);
3181 pframe = rtw_set_fixed_ie23a(pframe, _CAPABILITY_,
3182 (unsigned char *)&val, &pattrib->pktlen);
3184 status = cpu_to_le16(status);
3185 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
3186 (unsigned char *)&status,
3189 val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
3190 pframe = rtw_set_fixed_ie23a(pframe, _ASOC_ID_, (unsigned char *)&val,
3193 if (pstat->bssratelen <= 8) {
3194 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3195 pstat->bssratelen, pstat->bssrateset,
3198 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3199 pstat->bssrateset, &pattrib->pktlen);
3200 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3201 pstat->bssratelen - 8,
3202 pstat->bssrateset + 8, &pattrib->pktlen);
3205 if (pstat->flags & WLAN_STA_HT && pmlmepriv->htpriv.ht_option) {
3206 /* FILL HT CAP INFO IE */
3207 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
3208 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
3209 ie + _BEACON_IE_OFFSET_,
3210 pnetwork->IELength -_BEACON_IE_OFFSET_);
3212 memcpy(pframe, p, p[1] + 2);
3213 pframe += (p[1] + 2);
3214 pattrib->pktlen += (p[1] + 2);
3217 /* FILL HT ADD INFO IE */
3218 /* p = hostapd_eid_ht_operation(hapd, p); */
3219 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
3220 ie + _BEACON_IE_OFFSET_,
3221 pnetwork->IELength - _BEACON_IE_OFFSET_);
3222 if (p && p[1] > 0) {
3223 memcpy(pframe, p, p[1] + 2);
3224 pframe += (p[1] + 2);
3225 pattrib->pktlen += (p[1] + 2);
3230 if (pstat->flags & WLAN_STA_WME && pmlmepriv->qos_option) {
3231 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02,
3235 for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
3236 p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p,
3237 pnetwork->IELength -
3238 _BEACON_IE_OFFSET_ - (ie_len + 2));
3243 if (p && !memcmp(p + 2, WMM_PARA_IE, 6)) {
3244 memcpy(pframe, p, ie_len + 2);
3245 pframe += (ie_len + 2);
3246 pattrib->pktlen += (ie_len + 2);
3251 if (!p || ie_len == 0)
3256 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) {
3257 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3258 REALTEK_96B_IE, &pattrib->pktlen);
3261 /* add WPS IE ie for wps 2.0 */
3262 if (pmlmepriv->wps_assoc_resp_ie &&
3263 pmlmepriv->wps_assoc_resp_ie_len > 0) {
3264 memcpy(pframe, pmlmepriv->wps_assoc_resp_ie,
3265 pmlmepriv->wps_assoc_resp_ie_len);
3267 pframe += pmlmepriv->wps_assoc_resp_ie_len;
3268 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
3271 pattrib->last_txcmdsz = pattrib->pktlen;
3273 dump_mgntframe23a(padapter, pmgntframe);
3277 void issue_assocreq23a(struct rtw_adapter *padapter)
3280 struct xmit_frame *pmgntframe;
3281 struct pkt_attrib *pattrib;
3282 unsigned char *pframe;
3284 struct ieee80211_hdr *pwlanhdr;
3286 unsigned int i, j, index = 0;
3287 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
3288 struct ndis_802_11_var_ies *pIE;
3289 struct registry_priv *pregpriv = &padapter->registrypriv;
3290 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3291 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3292 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3293 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3294 int bssrate_len = 0, sta_bssrate_len = 0, pie_len;
3297 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3301 /* update attribute */
3302 pattrib = &pmgntframe->attrib;
3303 update_mgntframe_attrib23a(padapter, pattrib);
3305 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3307 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
3308 pwlanhdr = (struct ieee80211_hdr *)pframe;
3310 fctrl = &pwlanhdr->frame_control;
3312 ether_addr_copy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network));
3313 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3314 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3316 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3317 pmlmeext->mgnt_seq++;
3318 SetFrameSubType(pframe, WIFI_ASSOCREQ);
3320 pframe += sizeof(struct ieee80211_hdr_3addr);
3321 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3325 rtw_get_capability23a_from_ie(pmlmeinfo->network.IEs), 2);
3328 pattrib->pktlen += 2;
3330 /* listen interval */
3331 /* todo: listen interval for power saving */
3332 put_unaligned_le16(3, pframe);
3334 pattrib->pktlen += 2;
3337 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
3338 pmlmeinfo->network.Ssid.ssid_len,
3339 pmlmeinfo->network.Ssid.ssid, &pattrib->pktlen);
3341 /* supported rate & extended supported rate */
3343 get_rate_set23a(padapter, sta_bssrate, &sta_bssrate_len);
3344 /* DBG_8723A("sta_bssrate_len =%d\n", sta_bssrate_len); */
3346 /* for JAPAN, channel 14 can only uses B Mode(CCK) */
3347 if (pmlmeext->cur_channel == 14)
3348 sta_bssrate_len = 4;
3350 /* for (i = 0; i < sta_bssrate_len; i++) { */
3351 /* DBG_8723A("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
3354 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3355 if (pmlmeinfo->network.SupportedRates[i] == 0)
3357 DBG_8723A("network.SupportedRates[%d]=%02X\n", i,
3358 pmlmeinfo->network.SupportedRates[i]);
3361 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3362 if (pmlmeinfo->network.SupportedRates[i] == 0)
3365 /* Check if the AP's supported rates are also
3366 supported by STA. */
3367 for (j = 0; j < sta_bssrate_len; j++) {
3368 /* Avoid the proprietary data rate (22Mbps) of
3369 Handlink WSG-4000 AP */
3370 if ((pmlmeinfo->network.SupportedRates[i] |
3371 IEEE80211_BASIC_RATE_MASK) ==
3372 (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
3373 /* DBG_8723A("match i = %d, j =%d\n", i, j); */
3378 if (j == sta_bssrate_len) {
3379 /* the rate is not supported by STA */
3380 DBG_8723A("%s(): the rate[%d]=%02X is not supported by "
3381 "STA!\n", __func__, i,
3382 pmlmeinfo->network.SupportedRates[i]);
3384 /* the rate is supported by STA */
3385 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
3389 bssrate_len = index;
3390 DBG_8723A("bssrate_len = %d\n", bssrate_len);
3392 if (bssrate_len == 0) {
3393 rtw_free_xmitbuf23a(pxmitpriv, pmgntframe->pxmitbuf);
3394 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
3395 goto exit; /* don't connect to AP if no joint supported rate */
3398 if (bssrate_len > 8) {
3399 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3400 bssrate, &pattrib->pktlen);
3401 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3402 (bssrate_len - 8), (bssrate + 8),
3405 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3406 bssrate_len, bssrate, &pattrib->pktlen);
3409 pie = pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ies);
3410 pie_len = pmlmeinfo->network.IELength -
3411 sizeof(struct ndis_802_11_fixed_ies);
3413 p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
3415 pframe = rtw_set_ie23a(pframe, WLAN_EID_RSN, p[1], p + 2,
3419 if (padapter->mlmepriv.htpriv.ht_option == true) {
3420 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, pie_len);
3422 if (p && !is_ap_in_tkip23a(padapter)) {
3423 memcpy(&pmlmeinfo->HT_caps, p + 2,
3424 sizeof(struct HT_caps_element));
3426 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
3427 if (pregpriv->cbw40_enable == 0) {
3428 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= (~(BIT(6) | BIT(1)));
3430 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= BIT(1);
3433 /* todo: disable SM power save mode */
3434 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |=
3437 rf_type = rtl8723a_get_rf_type(padapter);
3438 /* switch (pregpriv->rf_config) */
3441 /* RX STBC One spatial stream */
3442 if (pregpriv->rx_stbc)
3443 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);
3445 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R23A, 16);
3451 /* enable for 2.4/5 GHz */
3452 if (pregpriv->rx_stbc == 0x3 ||
3453 (pmlmeext->cur_wireless_mode &
3455 /* enable for 2.4GHz */
3456 pregpriv->rx_stbc == 0x1) ||
3457 (pmlmeext->cur_wireless_mode &
3459 pregpriv->rx_stbc == 0x2) ||
3460 /* enable for 5GHz */
3461 pregpriv->wifi_spec == 1) {
3462 DBG_8723A("declare supporting RX "
3464 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
3466 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R23A, 16);
3469 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info =
3470 cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
3472 #ifdef CONFIG_8723AU_BT_COEXIST
3473 if (BT_1Ant(padapter) == true) {
3475 pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para &= (u8)~IEEE80211_HT_AMPDU_PARM_FACTOR;
3476 /* pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para |= MAX_AMPDU_FACTOR_8K */
3480 pframe = rtw_set_ie23a(pframe, WLAN_EID_HT_CAPABILITY,
3481 p[1], (u8 *)&pmlmeinfo->HT_caps,
3486 /* vendor specific IE, such as WPA, WMM, WPS */
3487 for (i = sizeof(struct ndis_802_11_fixed_ies);
3488 i < pmlmeinfo->network.IELength;) {
3489 pIE = (struct ndis_802_11_var_ies *)
3490 (pmlmeinfo->network.IEs + i);
3492 switch (pIE->ElementID)
3494 case WLAN_EID_VENDOR_SPECIFIC:
3495 if (!memcmp(pIE->data, RTW_WPA_OUI23A_TYPE, 4) ||
3496 !memcmp(pIE->data, WMM_OUI23A, 4) ||
3497 !memcmp(pIE->data, WPS_OUI23A, 4)) {
3498 if (!padapter->registrypriv.wifi_spec) {
3499 /* Commented by Kurt 20110629 */
3500 /* In some older APs, WPS handshake */
3501 /* would be fail if we append vender
3502 extensions informations to AP */
3503 if (!memcmp(pIE->data, WPS_OUI23A, 4))
3506 pframe = rtw_set_ie23a(pframe,
3507 WLAN_EID_VENDOR_SPECIFIC,
3508 pIE->Length, pIE->data,
3517 i += pIE->Length + 2;
3520 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
3521 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3522 REALTEK_96B_IE, &pattrib->pktlen);
3524 pattrib->last_txcmdsz = pattrib->pktlen;
3525 dump_mgntframe23a(padapter, pmgntframe);
3530 pmlmepriv->assoc_req_len = 0;
3531 if (ret == _SUCCESS) {
3532 kfree(pmlmepriv->assoc_req);
3533 pmlmepriv->assoc_req = kmalloc(pattrib->pktlen, GFP_ATOMIC);
3534 if (pmlmepriv->assoc_req) {
3535 memcpy(pmlmepriv->assoc_req, pwlanhdr, pattrib->pktlen);
3536 pmlmepriv->assoc_req_len = pattrib->pktlen;
3539 kfree(pmlmepriv->assoc_req);
3544 /* when wait_ack is ture, this function shoule be called at process context */
3545 static int _issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3546 unsigned int power_mode, int wait_ack)
3549 struct xmit_frame *pmgntframe;
3550 struct pkt_attrib *pattrib;
3551 unsigned char *pframe;
3552 struct ieee80211_hdr *pwlanhdr;
3554 struct xmit_priv *pxmitpriv;
3555 struct mlme_ext_priv *pmlmeext;
3556 struct mlme_ext_info *pmlmeinfo;
3558 /* DBG_8723A("%s:%d\n", __func__, power_mode); */
3563 pxmitpriv = &padapter->xmitpriv;
3564 pmlmeext = &padapter->mlmeextpriv;
3565 pmlmeinfo = &pmlmeext->mlmext_info;
3567 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3570 /* update attribute */
3571 pattrib = &pmgntframe->attrib;
3572 update_mgntframe_attrib23a(padapter, pattrib);
3573 pattrib->retry_ctrl = false;
3575 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3577 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3578 pwlanhdr = (struct ieee80211_hdr *)pframe;
3580 fctrl = &pwlanhdr->frame_control;
3583 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3585 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3591 ether_addr_copy(pwlanhdr->addr1, da);
3592 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3593 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3595 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3596 pmlmeext->mgnt_seq++;
3597 SetFrameSubType(pframe, WIFI_DATA_NULL);
3599 pframe += sizeof(struct ieee80211_hdr_3addr);
3600 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3602 pattrib->last_txcmdsz = pattrib->pktlen;
3605 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3607 dump_mgntframe23a(padapter, pmgntframe);
3615 /* when wait_ms >0 , this function shoule be called at process context */
3616 /* da == NULL for station mode */
3617 int issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3618 unsigned int power_mode, int try_cnt, int wait_ms)
3622 unsigned long start = jiffies;
3623 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3624 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3626 /* da == NULL, assum it's null data for sta to ap*/
3628 da = get_my_bssid23a(&pmlmeinfo->network);
3631 ret = _issue_nulldata23a(padapter, da, power_mode,
3632 wait_ms > 0 ? true : false);
3636 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3639 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3642 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3649 if (try_cnt && wait_ms) {
3651 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3652 "in %u ms\n", __func__,
3653 padapter->pnetdev->name,
3654 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3655 ret == _SUCCESS?", acked":"", i, try_cnt,
3656 jiffies_to_msecs(jiffies - start));
3658 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3659 __func__, padapter->pnetdev->name,
3660 rtw_get_oper_ch23a(padapter),
3661 ret == _SUCCESS?", acked":"", i, try_cnt,
3662 jiffies_to_msecs(jiffies - start));
3668 /* when wait_ack is ture, this function shoule be called at process context */
3669 static int _issue_qos_nulldata23a(struct rtw_adapter *padapter,
3670 unsigned char *da, u16 tid, int wait_ack)
3673 struct xmit_frame *pmgntframe;
3674 struct pkt_attrib *pattrib;
3675 unsigned char *pframe;
3676 struct ieee80211_hdr *pwlanhdr;
3679 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3680 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3681 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3683 DBG_8723A("%s\n", __func__);
3685 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3688 /* update attribute */
3689 pattrib = &pmgntframe->attrib;
3690 update_mgntframe_attrib23a(padapter, pattrib);
3692 pattrib->hdrlen += 2;
3693 pattrib->qos_en = true;
3695 pattrib->ack_policy = 0;
3698 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3700 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3701 pwlanhdr = (struct ieee80211_hdr *)pframe;
3703 fctrl = &pwlanhdr->frame_control;
3706 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3708 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3714 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
3716 SetPriority(qc, tid);
3718 SetEOSP(qc, pattrib->eosp);
3720 SetAckpolicy(qc, pattrib->ack_policy);
3722 ether_addr_copy(pwlanhdr->addr1, da);
3723 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3724 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3726 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3727 pmlmeext->mgnt_seq++;
3728 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
3730 pframe += sizeof(struct ieee80211_qos_hdr);
3731 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
3733 pattrib->last_txcmdsz = pattrib->pktlen;
3736 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3738 dump_mgntframe23a(padapter, pmgntframe);
3746 /* when wait_ms >0 , this function shoule be called at process context */
3747 /* da == NULL for station mode */
3748 int issue_qos_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3749 u16 tid, int try_cnt, int wait_ms)
3753 unsigned long start = jiffies;
3754 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3755 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3757 /* da == NULL, assum it's null data for sta to ap*/
3759 da = get_my_bssid23a(&pmlmeinfo->network);
3762 ret = _issue_qos_nulldata23a(padapter, da, tid,
3763 wait_ms > 0 ? true : false);
3767 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3770 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3772 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3779 if (try_cnt && wait_ms) {
3781 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3782 "in %u ms\n", __func__,
3783 padapter->pnetdev->name,
3784 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3785 ret == _SUCCESS?", acked":"", i, try_cnt,
3786 jiffies_to_msecs(jiffies - start));
3788 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3789 __func__, padapter->pnetdev->name,
3790 rtw_get_oper_ch23a(padapter),
3791 ret == _SUCCESS?", acked":"", i, try_cnt,
3792 jiffies_to_msecs(jiffies - start));
3798 static int _issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
3799 unsigned short reason, u8 wait_ack)
3801 struct xmit_frame *pmgntframe;
3802 struct pkt_attrib *pattrib;
3803 unsigned char *pframe;
3804 struct ieee80211_hdr *pwlanhdr;
3806 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3807 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3808 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3811 /* DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
3813 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3816 /* update attribute */
3817 pattrib = &pmgntframe->attrib;
3818 update_mgntframe_attrib23a(padapter, pattrib);
3819 pattrib->retry_ctrl = false;
3821 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3823 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3824 pwlanhdr = (struct ieee80211_hdr *)pframe;
3826 fctrl = &pwlanhdr->frame_control;
3829 ether_addr_copy(pwlanhdr->addr1, da);
3830 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3831 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3833 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3834 pmlmeext->mgnt_seq++;
3835 SetFrameSubType(pframe, WIFI_DEAUTH);
3837 pframe += sizeof(struct ieee80211_hdr_3addr);
3838 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3840 reason = cpu_to_le16(reason);
3841 pframe = rtw_set_fixed_ie23a(pframe, WLAN_REASON_PREV_AUTH_NOT_VALID,
3842 (unsigned char *)&reason,
3845 pattrib->last_txcmdsz = pattrib->pktlen;
3848 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3850 dump_mgntframe23a(padapter, pmgntframe);
3858 int issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
3859 unsigned short reason)
3861 DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
3862 return _issue_deauth23a(padapter, da, reason, false);
3865 int issue_deauth23a_ex23a(struct rtw_adapter *padapter, u8 *da,
3866 unsigned short reason, int try_cnt, int wait_ms)
3870 unsigned long start = jiffies;
3873 ret = _issue_deauth23a(padapter, da, reason,
3874 wait_ms >0 ? true : false);
3878 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3881 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3884 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3891 if (try_cnt && wait_ms) {
3893 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3894 "in %u ms\n", __func__,
3895 padapter->pnetdev->name,
3896 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3897 ret == _SUCCESS?", acked":"", i, try_cnt,
3898 jiffies_to_msecs(jiffies - start));
3900 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3901 __func__, padapter->pnetdev->name,
3902 rtw_get_oper_ch23a(padapter),
3903 ret == _SUCCESS?", acked":"", i, try_cnt,
3904 jiffies_to_msecs(jiffies - start));
3910 void issue_action_spct_ch_switch23a(struct rtw_adapter *padapter,
3911 u8 *ra, u8 new_ch, u8 ch_offset)
3913 struct xmit_frame *pmgntframe;
3914 struct pkt_attrib *pattrib;
3915 unsigned char *pframe;
3916 struct ieee80211_hdr *pwlanhdr;
3918 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3919 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3920 u8 category, action;
3922 DBG_8723A("%s(%s): ra ="MAC_FMT", ch:%u, offset:%u\n", __func__,
3923 padapter->pnetdev->name, MAC_ARG(ra), new_ch, ch_offset);
3925 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3928 /* update attribute */
3929 pattrib = &pmgntframe->attrib;
3930 update_mgntframe_attrib23a(padapter, pattrib);
3932 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3934 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3935 pwlanhdr = (struct ieee80211_hdr *)pframe;
3937 fctrl = &pwlanhdr->frame_control;
3940 ether_addr_copy(pwlanhdr->addr1, ra); /* RA */
3941 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv)); /* TA */
3942 ether_addr_copy(pwlanhdr->addr3, ra); /* DA = RA */
3944 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3945 pmlmeext->mgnt_seq++;
3946 SetFrameSubType(pframe, WIFI_ACTION);
3948 pframe += sizeof(struct ieee80211_hdr_3addr);
3949 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3951 /* category, action */
3952 category = WLAN_CATEGORY_SPECTRUM_MGMT;
3953 action = WLAN_ACTION_SPCT_CHL_SWITCH;
3955 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
3956 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
3958 pframe = rtw_set_ie23a_ch_switch (pframe, &pattrib->pktlen, 0,
3960 pframe = rtw_set_ie23a_secondary_ch_offset(pframe, &pattrib->pktlen,
3961 hal_ch_offset_to_secondary_ch_offset23a(ch_offset));
3963 pattrib->last_txcmdsz = pattrib->pktlen;
3965 dump_mgntframe23a(padapter, pmgntframe);
3968 void issue_action_BA23a(struct rtw_adapter *padapter,
3969 const unsigned char *raddr,
3970 unsigned char action, unsigned short status)
3972 u8 category = WLAN_CATEGORY_BACK;
3976 u16 BA_timeout_value;
3977 u16 BA_starting_seqctrl;
3978 int max_rx_ampdu_factor;
3979 struct xmit_frame *pmgntframe;
3980 struct pkt_attrib *pattrib;
3982 struct ieee80211_hdr *pwlanhdr;
3984 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3985 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3986 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3987 struct sta_info *psta;
3988 struct sta_priv *pstapriv = &padapter->stapriv;
3989 struct registry_priv *pregpriv = &padapter->registrypriv;
3990 #ifdef CONFIG_8723AU_BT_COEXIST
3991 u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
3994 DBG_8723A("%s, category =%d, action =%d, status =%d\n",
3995 __func__, category, action, status);
3997 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
4000 /* update attribute */
4001 pattrib = &pmgntframe->attrib;
4002 update_mgntframe_attrib23a(padapter, pattrib);
4004 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4006 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4007 pwlanhdr = (struct ieee80211_hdr *)pframe;
4009 fctrl = &pwlanhdr->frame_control;
4012 /* memcpy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN); */
4013 ether_addr_copy(pwlanhdr->addr1, raddr);
4014 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
4015 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
4017 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4018 pmlmeext->mgnt_seq++;
4019 SetFrameSubType(pframe, WIFI_ACTION);
4021 pframe += sizeof(struct ieee80211_hdr_3addr);
4022 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
4024 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
4025 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
4027 status = cpu_to_le16(status);
4034 case 0: /* ADDBA req */
4036 pmlmeinfo->dialogToken++;
4037 } while (pmlmeinfo->dialogToken == 0);
4038 pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->dialogToken,
4041 #ifdef CONFIG_8723AU_BT_COEXIST
4042 if ((BT_1Ant(padapter) == true) &&
4043 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
4044 memcmp(raddr, tendaAPMac, 3))) {
4045 /* A-MSDU NOT Supported */
4047 /* immediate Block Ack */
4048 BA_para_set |= (1 << 1) &
4049 IEEE80211_ADDBA_PARAM_POLICY_MASK;
4051 BA_para_set |= (status << 2) &
4052 IEEE80211_ADDBA_PARAM_TID_MASK;
4053 /* max buffer size is 8 MSDU */
4054 BA_para_set |= (8 << 6) &
4055 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4059 /* immediate ack & 64 buffer size */
4060 BA_para_set = (0x1002 | ((status & 0xf) << 2));
4062 BA_para_set = cpu_to_le16(BA_para_set);
4063 pframe = rtw_set_fixed_ie23a(pframe, 2,
4064 (unsigned char *)&BA_para_set,
4067 BA_timeout_value = 5000;/* 5ms */
4068 BA_timeout_value = cpu_to_le16(BA_timeout_value);
4069 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)
4073 /* if ((psta = rtw_get_stainfo23a(pstapriv,
4074 pmlmeinfo->network.MacAddress)) != NULL) */
4075 if ((psta = rtw_get_stainfo23a(pstapriv, raddr))) {
4076 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
4078 DBG_8723A("BA_starting_seqctrl = %d for TID =%d\n",
4079 start_seq, status & 0x07);
4081 psta->BA_starting_seqctrl[status & 0x07] = start_seq;
4083 BA_starting_seqctrl = start_seq << 4;
4086 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
4087 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&BA_starting_seqctrl, &pattrib->pktlen);
4090 case 1: /* ADDBA rsp */
4091 pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->ADDBA_req.dialog_token, &pattrib->pktlen);
4092 pframe = rtw_set_fixed_ie23a(pframe, 2,
4093 (unsigned char *)&status,
4095 rtw_hal_get_def_var23a(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
4096 &max_rx_ampdu_factor);
4097 if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_64K)
4098 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
4099 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_32K)
4100 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); /* 32 buffer size */
4101 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_16K)
4102 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); /* 16 buffer size */
4103 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_8K)
4104 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); /* 8 buffer size */
4106 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
4108 #ifdef CONFIG_8723AU_BT_COEXIST
4109 if ((BT_1Ant(padapter) == true) &&
4110 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
4111 memcmp(raddr, tendaAPMac, 3))) {
4112 /* max buffer size is 8 MSDU */
4113 BA_para_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4114 BA_para_set |= (8 << 6) &
4115 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4119 if (pregpriv->ampdu_amsdu == 0)/* disabled */
4120 BA_para_set = cpu_to_le16(BA_para_set & ~BIT(0));
4121 else if (pregpriv->ampdu_amsdu == 1)/* enabled */
4122 BA_para_set = cpu_to_le16(BA_para_set | BIT(0));
4124 BA_para_set = cpu_to_le16(BA_para_set);
4126 pframe = rtw_set_fixed_ie23a(pframe, 2,
4127 (unsigned char *)&BA_para_set,
4129 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&pmlmeinfo->ADDBA_req.BA_timeout_value, &pattrib->pktlen);
4132 BA_para_set = (status & 0x1F) << 3;
4133 BA_para_set = cpu_to_le16(BA_para_set);
4134 pframe = rtw_set_fixed_ie23a(pframe, 2,
4135 (unsigned char *)&BA_para_set,
4138 reason_code = 37;/* Requested from peer STA as it does not
4139 want to use the mechanism */
4140 reason_code = cpu_to_le16(reason_code);
4141 pframe = rtw_set_fixed_ie23a(pframe, 2,
4142 (unsigned char *)&reason_code,
4150 pattrib->last_txcmdsz = pattrib->pktlen;
4152 dump_mgntframe23a(padapter, pmgntframe);
4155 static void issue_action_BSSCoexistPacket(struct rtw_adapter *padapter)
4157 struct list_head *plist, *phead, *ptmp;
4158 unsigned char category, action;
4159 struct xmit_frame *pmgntframe;
4160 struct pkt_attrib *pattrib;
4162 struct ieee80211_hdr *pwlanhdr;
4164 struct wlan_network *pnetwork;
4165 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4166 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4167 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4168 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4169 struct rtw_queue *queue = &pmlmepriv->scanned_queue;
4170 u8 InfoContent[16] = {0};
4174 if (pmlmepriv->num_FortyMHzIntolerant == 0 ||
4175 pmlmepriv->num_sta_no_ht == 0)
4178 if (pmlmeinfo->bwmode_updated)
4181 DBG_8723A("%s\n", __func__);
4183 category = WLAN_CATEGORY_PUBLIC;
4184 action = ACT_PUBLIC_BSSCOEXIST;
4186 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
4190 /* update attribute */
4191 pattrib = &pmgntframe->attrib;
4192 update_mgntframe_attrib23a(padapter, pattrib);
4194 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4196 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
4197 pwlanhdr = (struct ieee80211_hdr *)pframe;
4199 fctrl = &pwlanhdr->frame_control;
4202 ether_addr_copy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network));
4203 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
4204 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
4206 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4207 pmlmeext->mgnt_seq++;
4208 SetFrameSubType(pframe, WIFI_ACTION);
4210 pframe += sizeof(struct ieee80211_hdr_3addr);
4211 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
4213 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
4214 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
4216 if (pmlmepriv->num_FortyMHzIntolerant > 0) {
4217 u8 iedata = BIT(2);/* 20 MHz BSS Width Request */
4219 pframe = rtw_set_ie23a(pframe, WLAN_EID_BSS_COEX_2040, 1,
4220 &iedata, &pattrib->pktlen);
4223 if (pmlmepriv->num_sta_no_ht <= 0)
4226 memset(ICS, 0, sizeof(ICS));
4228 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
4230 phead = get_list_head(queue);
4231 plist = phead->next;
4233 list_for_each_safe(plist, ptmp, phead) {
4235 struct wlan_bssid_ex *pbss_network;
4237 pnetwork = container_of(plist, struct wlan_network, list);
4239 pbss_network = &pnetwork->network;
4241 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
4242 pbss_network->IEs + _FIXED_IE_LENGTH_,
4243 pbss_network->IELength -_FIXED_IE_LENGTH_);
4244 if (!p || !p[1]) { /* non-HT */
4245 if (pbss_network->Configuration.DSConfig <= 0 ||
4246 pbss_network->Configuration.DSConfig > 14)
4249 ICS[0][pbss_network->Configuration.DSConfig] = 1;
4257 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
4259 for (i = 0; i < 8;i++) {
4260 if (ICS[i][0] == 1) {
4264 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
4267 for (j = 1; j <= 14; j++) {
4268 if (ICS[i][j] == 1) {
4270 /* channel number */
4277 pframe = rtw_set_ie23a(pframe,
4278 EID_BSSIntolerantChlReport, k,
4279 InfoContent, &pattrib->pktlen);
4284 pattrib->last_txcmdsz = pattrib->pktlen;
4286 dump_mgntframe23a(padapter, pmgntframe);
4289 unsigned int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr)
4291 struct sta_priv *pstapriv = &padapter->stapriv;
4292 struct sta_info *psta = NULL;
4293 /* struct recv_reorder_ctrl *preorder_ctrl; */
4294 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4295 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4298 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
4299 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
4302 psta = rtw_get_stainfo23a(pstapriv, addr);
4306 if (initiator == 0) { /* recipient */
4307 for (tid = 0; tid < MAXTID; tid++) {
4308 if (psta->recvreorder_ctrl[tid].enable == true) {
4309 DBG_8723A("rx agg disable tid(%d)\n", tid);
4310 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
4311 psta->recvreorder_ctrl[tid].enable = false;
4312 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
4315 } else if (initiator == 1) { /* originator */
4316 for (tid = 0; tid < MAXTID; tid++) {
4317 if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
4318 DBG_8723A("tx agg disable tid(%d)\n", tid);
4319 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
4320 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
4321 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
4329 unsigned int send_beacon23a(struct rtw_adapter *padapter)
4334 unsigned long start = jiffies;
4335 unsigned int passing_time;
4337 rtl8723a_bcn_valid(padapter);
4339 issue_beacon23a(padapter, 100);
4343 bxmitok = rtl8723a_get_bcn_valid(padapter);
4345 } while ((poll % 10) != 0 && bxmitok == false &&
4346 !padapter->bSurpriseRemoved &&
4347 !padapter->bDriverStopped);
4349 } while (!bxmitok && issue<100 && !padapter->bSurpriseRemoved &&
4350 !padapter->bDriverStopped);
4352 if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
4355 passing_time = jiffies_to_msecs(jiffies - start);
4358 DBG_8723A("%s fail! %u ms\n", __func__, passing_time);
4362 if (passing_time > 100 || issue > 3)
4363 DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n",
4364 __func__, issue, poll, passing_time);
4369 /****************************************************************************
4371 Following are some utitity fuctions for WiFi MLME
4373 *****************************************************************************/
4375 bool IsLegal5GChannel(struct rtw_adapter *Adapter, u8 channel)
4379 u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
4380 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
4381 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
4383 for (i = 0; i < sizeof(Channel_5G); i++)
4384 if (channel == Channel_5G[i])
4389 void site_survey23a(struct rtw_adapter *padapter)
4391 unsigned char survey_channel = 0;
4392 enum rt_scan_type ScanType = SCAN_PASSIVE;
4393 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4394 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4395 struct rtw_ieee80211_channel *ch;
4397 if (pmlmeext->sitesurvey_res.channel_idx <
4398 pmlmeext->sitesurvey_res.ch_num) {
4399 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
4400 survey_channel = ch->hw_value;
4401 ScanType = (ch->flags & IEEE80211_CHAN_NO_IR) ?
4402 SCAN_PASSIVE : SCAN_ACTIVE;
4405 if (survey_channel != 0) {
4406 /* PAUSE 4-AC Queue when site_survey23a */
4407 if (pmlmeext->sitesurvey_res.channel_idx == 0)
4408 set_channel_bwmode23a(padapter, survey_channel,
4409 HAL_PRIME_CHNL_OFFSET_DONT_CARE,
4410 HT_CHANNEL_WIDTH_20);
4412 SelectChannel23a(padapter, survey_channel);
4414 if (ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */
4417 for (i = 0;i<RTW_SSID_SCAN_AMOUNT;i++) {
4418 if (pmlmeext->sitesurvey_res.ssid[i].ssid_len) {
4419 /* todo: to issue two probe req??? */
4420 issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4421 /* msleep(SURVEY_TO>>1); */
4422 issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4426 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
4427 /* todo: to issue two probe req??? */
4428 issue_probereq23a(padapter, NULL, NULL);
4429 /* msleep(SURVEY_TO>>1); */
4430 issue_probereq23a(padapter, NULL, NULL);
4434 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
4436 /* channel number is 0 or this channel is not valid. */
4437 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
4439 /* switch back to the original channel */
4441 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
4442 pmlmeext->cur_ch_offset,
4443 pmlmeext->cur_bwmode);
4445 /* flush 4-AC Queue after site_survey23a */
4449 Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
4451 /* restore RX GAIN */
4452 rtl8723a_set_initial_gain(padapter, 0xff);
4453 /* turn on dynamic functions */
4454 rtl8723a_odm_support_ability_restore(padapter);
4456 if (is_client_associated_to_ap23a(padapter) == true)
4457 issue_nulldata23a(padapter, NULL, 0, 3, 500);
4459 rtl8723a_mlme_sitesurvey(padapter, 0);
4461 report_surveydone_event23a(padapter);
4463 pmlmeext->chan_scan_time = SURVEY_TO;
4464 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
4466 issue_action_BSSCoexistPacket(padapter);
4467 issue_action_BSSCoexistPacket(padapter);
4468 issue_action_BSSCoexistPacket(padapter);
4474 /* collect bss info from Beacon and Probe request/response frames. */
4475 u8 collect_bss_info23a(struct rtw_adapter *padapter,
4476 struct recv_frame *precv_frame,
4477 struct wlan_bssid_ex *bssid)
4481 struct sk_buff *skb = precv_frame->pkt;
4482 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
4483 unsigned int length;
4485 struct registry_priv *pregistrypriv = &padapter->registrypriv;
4486 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4487 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4490 length = skb->len - sizeof(struct ieee80211_hdr_3addr);
4492 if (length > MAX_IE_SZ) {
4493 /* DBG_8723A("IE too long for survey event\n"); */
4497 memset(bssid, 0, sizeof(struct wlan_bssid_ex));
4499 if (ieee80211_is_beacon(mgmt->frame_control)) {
4500 bssid->reserved = 1;
4501 ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
4502 capab_info = mgmt->u.beacon.capab_info;
4503 } else if (ieee80211_is_probe_req(mgmt->frame_control)) {
4504 ie_offset = offsetof(struct ieee80211_mgmt,
4505 u.probe_req.variable);
4506 bssid->reserved = 2;
4508 } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4509 ie_offset = offsetof(struct ieee80211_mgmt,
4510 u.probe_resp.variable);
4511 bssid->reserved = 3;
4512 capab_info = mgmt->u.probe_resp.capab_info;
4514 bssid->reserved = 0;
4515 ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
4516 capab_info = mgmt->u.beacon.capab_info;
4518 ie_offset -= offsetof(struct ieee80211_mgmt, u);
4520 bssid->Length = offsetof(struct wlan_bssid_ex, IEs) + length;
4522 /* below is to copy the information element */
4523 bssid->IELength = length;
4524 memcpy(bssid->IEs, &mgmt->u, bssid->IELength);
4526 /* get the signal strength */
4527 /* in dBM.raw data */
4528 bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower;
4529 bssid->PhyInfo.SignalQuality =
4530 precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
4531 bssid->PhyInfo.SignalStrength =
4532 precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
4535 p = cfg80211_find_ie(WLAN_EID_SSID, bssid->IEs + ie_offset,
4536 bssid->IELength - ie_offset);
4539 DBG_8723A("marc: cannot find SSID for survey event\n");
4543 if (p[1] > IEEE80211_MAX_SSID_LEN) {
4544 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4545 "event\n", __func__, __LINE__, p[1]);
4548 memcpy(bssid->Ssid.ssid, p + 2, p[1]);
4549 bssid->Ssid.ssid_len = p[1];
4551 memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
4553 /* checking rate info... */
4555 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, bssid->IEs + ie_offset,
4556 bssid->IELength - ie_offset);
4558 if (p[1] > NDIS_802_11_LENGTH_RATES_EX) {
4559 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4560 "event\n", __func__, __LINE__, p[1]);
4563 memcpy(bssid->SupportedRates, p + 2, p[1]);
4567 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, bssid->IEs + ie_offset,
4568 bssid->IELength - ie_offset);
4570 if (p[1] > (NDIS_802_11_LENGTH_RATES_EX-i)) {
4571 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4572 "event\n", __func__, __LINE__, p[1]);
4575 memcpy(bssid->SupportedRates + i, p + 2, p[1]);
4578 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
4580 if (bssid->IELength < 12)
4583 /* Checking for DSConfig */
4584 p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bssid->IEs + ie_offset,
4585 bssid->IELength - ie_offset);
4587 bssid->Configuration.DSConfig = 0;
4588 bssid->Configuration.Length = 0;
4591 bssid->Configuration.DSConfig = p[2];
4592 } else {/* In 5G, some ap do not have DSSET IE */
4593 /* checking HT info for channel */
4594 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
4595 bssid->IEs + ie_offset,
4596 bssid->IELength - ie_offset);
4598 struct HT_info_element *HT_info =
4599 (struct HT_info_element *)(p + 2);
4600 bssid->Configuration.DSConfig =
4601 HT_info->primary_channel;
4602 } else { /* use current channel */
4603 bssid->Configuration.DSConfig =
4604 rtw_get_oper_ch23a(padapter);
4608 if (ieee80211_is_probe_req(mgmt->frame_control)) {
4610 bssid->InfrastructureMode = Ndis802_11Infrastructure;
4611 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4616 memcpy(&bssid->Configuration.BeaconPeriod,
4617 rtw_get_beacon_interval23a_from_ie(bssid->IEs), 2);
4618 bssid->Configuration.BeaconPeriod =
4619 le32_to_cpu(bssid->Configuration.BeaconPeriod);
4621 if (capab_info & BIT(0)) {
4622 bssid->InfrastructureMode = Ndis802_11Infrastructure;
4623 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4625 bssid->InfrastructureMode = Ndis802_11IBSS;
4626 ether_addr_copy(bssid->MacAddress, mgmt->bssid);
4629 if (capab_info & BIT(4))
4634 bssid->Configuration.ATIMWindow = 0;
4636 /* 20/40 BSS Coexistence check */
4637 if (pregistrypriv->wifi_spec == 1 &&
4638 pmlmeinfo->bwmode_updated == false) {
4639 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4641 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
4642 bssid->IEs + ie_offset,
4643 bssid->IELength - ie_offset);
4644 if (p && p[1] > 0) {
4645 struct HT_caps_element *pHT_caps;
4646 pHT_caps = (struct HT_caps_element *)(p + 2);
4648 if (pHT_caps->u.HT_cap_element.HT_caps_info & BIT(14))
4649 pmlmepriv->num_FortyMHzIntolerant++;
4651 pmlmepriv->num_sta_no_ht++;
4655 /* mark bss info receving from nearby channel as SignalQuality 101 */
4656 if (bssid->Configuration.DSConfig != rtw_get_oper_ch23a(padapter))
4657 bssid->PhyInfo.SignalQuality = 101;
4662 void start_create_ibss23a(struct rtw_adapter* padapter)
4664 unsigned short caps;
4665 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4666 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4667 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4668 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
4669 pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
4671 /* update wireless mode */
4672 update_wireless_mode23a(padapter);
4674 /* udpate capability */
4675 caps = rtw_get_capability23a(pnetwork);
4676 update_capinfo23a(padapter, caps);
4677 if (caps&cap_IBSS) { /* adhoc master */
4678 rtl8723a_set_sec_cfg(padapter, 0xcf);
4680 /* switch channel */
4681 /* SelectChannel23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
4682 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4684 beacon_timing_control23a(padapter);
4686 /* set msr to WIFI_FW_ADHOC_STATE */
4687 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4688 Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
4691 if (send_beacon23a(padapter) == _FAIL)
4693 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("issuing beacon frame fail....\n"));
4695 report_join_res23a(padapter, -1);
4696 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4700 hw_var_set_bssid(padapter, padapter->registrypriv.dev_network.MacAddress);
4701 hw_var_set_mlme_join(padapter, 0);
4703 report_join_res23a(padapter, 1);
4704 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
4709 DBG_8723A("start_create_ibss23a, invalid cap:%x\n", caps);
4714 void start_clnt_join23a(struct rtw_adapter* padapter)
4716 unsigned short caps;
4718 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4719 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4720 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4723 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
4724 pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
4726 /* update wireless mode */
4727 update_wireless_mode23a(padapter);
4729 /* udpate capability */
4730 caps = rtw_get_capability23a(pnetwork);
4731 update_capinfo23a(padapter, caps);
4733 /* switch channel */
4734 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4736 Set_MSR23a(padapter, WIFI_FW_STATION_STATE);
4738 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ?
4741 rtl8723a_set_sec_cfg(padapter, val8);
4743 /* switch channel */
4744 /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
4746 /* here wait for receiving the beacon to start auth */
4747 /* and enable a timer */
4748 beacon_timeout = decide_wait_for_beacon_timeout23a(pmlmeinfo->bcn_interval);
4749 set_link_timer(pmlmeext, beacon_timeout);
4750 mod_timer(&padapter->mlmepriv.assoc_timer, jiffies +
4751 msecs_to_jiffies((REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout));
4752 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
4754 else if (caps&cap_IBSS) { /* adhoc client */
4755 Set_MSR23a(padapter, WIFI_FW_ADHOC_STATE);
4757 rtl8723a_set_sec_cfg(padapter, 0xcf);
4759 /* switch channel */
4760 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4762 beacon_timing_control23a(padapter);
4764 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4766 report_join_res23a(padapter, 1);
4770 /* DBG_8723A("marc: invalid cap:%x\n", caps); */
4775 void start_clnt_auth23a(struct rtw_adapter* padapter)
4777 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4778 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4780 del_timer_sync(&pmlmeext->link_timer);
4782 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
4783 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
4785 pmlmeinfo->auth_seq = 1;
4786 pmlmeinfo->reauth_count = 0;
4787 pmlmeinfo->reassoc_count = 0;
4788 pmlmeinfo->link_count = 0;
4789 pmlmeext->retry = 0;
4791 /* Because of AP's not receiving deauth before */
4792 /* AP may: 1)not response auth or 2)deauth us after link is complete */
4793 /* issue deauth before issuing auth to deal with the situation */
4794 /* Commented by Albert 2012/07/21 */
4795 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
4796 issue_deauth23a(padapter, (&pmlmeinfo->network)->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
4798 DBG_8723A_LEVEL(_drv_always_, "start auth\n");
4799 issue_auth23a(padapter, NULL, 0);
4801 set_link_timer(pmlmeext, REAUTH_TO);
4804 void start_clnt_assoc23a(struct rtw_adapter* padapter)
4806 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4807 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4809 del_timer_sync(&pmlmeext->link_timer);
4811 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
4812 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
4814 issue_assocreq23a(padapter);
4816 set_link_timer(pmlmeext, REASSOC_TO);
4819 unsigned int receive_disconnect23a(struct rtw_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
4821 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4822 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4825 if (!ether_addr_equal(MacAddr, get_my_bssid23a(&pmlmeinfo->network)))
4828 DBG_8723A("%s\n", __func__);
4830 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
4832 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
4834 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4835 report_del_sta_event23a(padapter, MacAddr, reason);
4838 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
4840 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4841 report_join_res23a(padapter, -2);
4848 static void process_80211d(struct rtw_adapter *padapter,
4849 struct wlan_bssid_ex *bssid)
4851 struct registry_priv *pregistrypriv;
4852 struct mlme_ext_priv *pmlmeext;
4853 struct rt_channel_info *chplan_new;
4857 pregistrypriv = &padapter->registrypriv;
4858 pmlmeext = &padapter->mlmeextpriv;
4860 /* Adjust channel plan by AP Country IE */
4861 if (pregistrypriv->enable80211d &&
4862 !pmlmeext->update_channel_plan_by_ap_done) {
4864 struct rt_channel_plan chplan_ap;
4865 struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
4867 u8 fcn; /* first channel number */
4868 u8 noc; /* number of channel */
4871 ie = cfg80211_find_ie(WLAN_EID_COUNTRY,
4872 bssid->IEs + _FIXED_IE_LENGTH_,
4873 bssid->IELength - _FIXED_IE_LENGTH_);
4874 if (!ie || ie[1] < IEEE80211_COUNTRY_IE_MIN_LEN)
4881 memcpy(country, p, 3);
4885 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4886 ("%s: 802.11d country =%s\n", __func__, country));
4889 while ((ie - p) >= 3) {
4894 for (j = 0; j < noc; j++) {
4896 channel = fcn + j; /* 2.4 GHz */
4898 channel = fcn + j * 4; /* 5 GHz */
4900 chplan_ap.Channel[i++] = channel;
4905 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
4906 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
4907 chplan_new = pmlmeext->channel_set;
4910 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
4912 if (i == MAX_CHANNEL_NUM ||
4913 chplan_sta[i].ChannelNum == 0 ||
4914 chplan_sta[i].ChannelNum > 14)
4917 if (j == chplan_ap.Len ||
4918 chplan_ap.Channel[j] > 14)
4921 if (chplan_sta[i].ChannelNum ==
4922 chplan_ap.Channel[j]) {
4923 chplan_new[k].ChannelNum =
4924 chplan_ap.Channel[j];
4925 chplan_new[k].ScanType = SCAN_ACTIVE;
4929 } else if (chplan_sta[i].ChannelNum <
4930 chplan_ap.Channel[j]) {
4931 chplan_new[k].ChannelNum =
4932 chplan_sta[i].ChannelNum;
4933 chplan_new[k].ScanType =
4937 } else if (chplan_sta[i].ChannelNum >
4938 chplan_ap.Channel[j]) {
4939 chplan_new[k].ChannelNum =
4940 chplan_ap.Channel[j];
4941 chplan_new[k].ScanType =
4948 /* change AP not support channel to Passive scan */
4949 while (i < MAX_CHANNEL_NUM &&
4950 chplan_sta[i].ChannelNum != 0 &&
4951 chplan_sta[i].ChannelNum <= 14) {
4952 chplan_new[k].ChannelNum =
4953 chplan_sta[i].ChannelNum;
4954 chplan_new[k].ScanType = SCAN_PASSIVE;
4959 /* add channel AP supported */
4960 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14){
4961 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4962 chplan_new[k].ScanType = SCAN_ACTIVE;
4967 /* keep original STA 2.4G channel plan */
4968 while (i < MAX_CHANNEL_NUM &&
4969 chplan_sta[i].ChannelNum != 0 &&
4970 chplan_sta[i].ChannelNum <= 14) {
4971 chplan_new[k].ChannelNum =
4972 chplan_sta[i].ChannelNum;
4973 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4978 /* skip AP 2.4G channel plan */
4979 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14)
4983 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
4985 if (i == MAX_CHANNEL_NUM ||
4986 chplan_sta[i].ChannelNum == 0)
4989 if (j == chplan_ap.Len ||
4990 chplan_ap.Channel[j] == 0)
4993 if (chplan_sta[i].ChannelNum ==
4994 chplan_ap.Channel[j]) {
4995 chplan_new[k].ChannelNum =
4996 chplan_ap.Channel[j];
4997 chplan_new[k].ScanType = SCAN_ACTIVE;
5001 } else if (chplan_sta[i].ChannelNum <
5002 chplan_ap.Channel[j]) {
5003 chplan_new[k].ChannelNum =
5004 chplan_sta[i].ChannelNum;
5005 chplan_new[k].ScanType = SCAN_PASSIVE;
5008 } else if (chplan_sta[i].ChannelNum >
5009 chplan_ap.Channel[j]) {
5010 chplan_new[k].ChannelNum =
5011 chplan_ap.Channel[j];
5012 chplan_new[k].ScanType = SCAN_ACTIVE;
5018 /* change AP not support channel to Passive scan */
5019 while (i < MAX_CHANNEL_NUM &&
5020 chplan_sta[i].ChannelNum != 0) {
5021 chplan_new[k].ChannelNum =
5022 chplan_sta[i].ChannelNum;
5023 chplan_new[k].ScanType = SCAN_PASSIVE;
5028 /* add channel AP supported */
5029 while (j < chplan_ap.Len && chplan_ap.Channel[j] != 0) {
5030 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
5031 chplan_new[k].ScanType = SCAN_ACTIVE;
5036 /* keep original STA 5G channel plan */
5037 while (i < MAX_CHANNEL_NUM &&
5038 chplan_sta[i].ChannelNum != 0) {
5039 chplan_new[k].ChannelNum =
5040 chplan_sta[i].ChannelNum;
5041 chplan_new[k].ScanType = chplan_sta[i].ScanType;
5046 pmlmeext->update_channel_plan_by_ap_done = 1;
5049 /* If channel is used by AP, set channel scan type to active */
5050 channel = bssid->Configuration.DSConfig;
5051 chplan_new = pmlmeext->channel_set;
5053 while (i < MAX_CHANNEL_NUM && chplan_new[i].ChannelNum != 0) {
5054 if (chplan_new[i].ChannelNum == channel) {
5055 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
5056 /* 5G Bnad 2, 3 (DFS) doesn't change
5058 if (channel >= 52 && channel <= 144)
5061 chplan_new[i].ScanType = SCAN_ACTIVE;
5062 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
5063 ("%s: change channel %d scan type "
5064 "from passive to active\n",
5065 __func__, channel));
5073 /****************************************************************************
5075 Following are the functions to report events
5077 *****************************************************************************/
5079 void report_survey_event23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
5081 struct cmd_obj *pcmd_obj;
5084 struct survey_event *psurvey_evt;
5085 struct C2HEvent_Header *pc2h_evt_hdr;
5086 struct mlme_ext_priv *pmlmeext;
5087 struct cmd_priv *pcmdpriv;
5092 pmlmeext = &padapter->mlmeextpriv;
5093 pcmdpriv = &padapter->cmdpriv;
5095 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5100 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
5101 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5107 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5108 pcmd_obj->cmdsz = cmdsz;
5109 pcmd_obj->parmbuf = pevtcmd;
5111 pcmd_obj->rsp = NULL;
5112 pcmd_obj->rspsz = 0;
5114 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5115 pc2h_evt_hdr->len = sizeof(struct survey_event);
5116 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
5117 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5119 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5121 if (collect_bss_info23a(padapter, precv_frame, &psurvey_evt->bss) == _FAIL) {
5127 process_80211d(padapter, &psurvey_evt->bss);
5129 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5131 pmlmeext->sitesurvey_res.bss_cnt++;
5136 void report_surveydone_event23a(struct rtw_adapter *padapter)
5138 struct cmd_obj *pcmd_obj;
5141 struct surveydone_event *psurveydone_evt;
5142 struct C2HEvent_Header *pc2h_evt_hdr;
5143 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5144 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5146 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5151 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
5152 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5158 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5159 pcmd_obj->cmdsz = cmdsz;
5160 pcmd_obj->parmbuf = pevtcmd;
5162 pcmd_obj->rsp = NULL;
5163 pcmd_obj->rspsz = 0;
5165 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5166 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
5167 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
5168 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5170 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5171 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
5173 DBG_8723A("survey done event(%x)\n", psurveydone_evt->bss_cnt);
5175 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5180 void report_join_res23a(struct rtw_adapter *padapter, int res)
5182 struct cmd_obj *pcmd_obj;
5185 struct joinbss_event *pjoinbss_evt;
5186 struct C2HEvent_Header *pc2h_evt_hdr;
5187 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5188 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5189 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5191 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5196 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
5197 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5203 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5204 pcmd_obj->cmdsz = cmdsz;
5205 pcmd_obj->parmbuf = pevtcmd;
5207 pcmd_obj->rsp = NULL;
5208 pcmd_obj->rspsz = 0;
5210 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5211 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
5212 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
5213 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5215 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5216 memcpy((unsigned char *)&pjoinbss_evt->network.network,
5217 &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
5218 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
5220 DBG_8723A("report_join_res23a(%d)\n", res);
5222 rtw_joinbss_event_prehandle23a(padapter, (u8 *)&pjoinbss_evt->network);
5224 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5229 void report_del_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, unsigned short reason)
5231 struct cmd_obj *pcmd_obj;
5234 struct sta_info *psta;
5236 struct stadel_event *pdel_sta_evt;
5237 struct C2HEvent_Header *pc2h_evt_hdr;
5238 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5239 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5241 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5246 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
5247 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5253 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5254 pcmd_obj->cmdsz = cmdsz;
5255 pcmd_obj->parmbuf = pevtcmd;
5257 pcmd_obj->rsp = NULL;
5258 pcmd_obj->rspsz = 0;
5260 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5261 pc2h_evt_hdr->len = sizeof(struct stadel_event);
5262 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
5263 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5265 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5266 ether_addr_copy((unsigned char *)&pdel_sta_evt->macaddr, MacAddr);
5267 memcpy((unsigned char *)pdel_sta_evt->rsvd, (unsigned char *)&reason,
5270 psta = rtw_get_stainfo23a(&padapter->stapriv, MacAddr);
5272 mac_id = (int)psta->mac_id;
5276 pdel_sta_evt->mac_id = mac_id;
5278 DBG_8723A("report_del_sta_event23a: delete STA, mac_id =%d\n", mac_id);
5280 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5285 void report_add_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, int cam_idx)
5287 struct cmd_obj *pcmd_obj;
5290 struct stassoc_event *padd_sta_evt;
5291 struct C2HEvent_Header *pc2h_evt_hdr;
5292 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5293 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5295 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5300 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
5301 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5307 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5308 pcmd_obj->cmdsz = cmdsz;
5309 pcmd_obj->parmbuf = pevtcmd;
5311 pcmd_obj->rsp = NULL;
5312 pcmd_obj->rspsz = 0;
5314 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5315 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
5316 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
5317 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5319 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5320 ether_addr_copy((unsigned char *)&padd_sta_evt->macaddr, MacAddr);
5321 padd_sta_evt->cam_id = cam_idx;
5323 DBG_8723A("report_add_sta_event23a: add STA\n");
5325 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5330 /****************************************************************************
5332 Following are the event callback functions
5334 *****************************************************************************/
5336 /* for sta/adhoc mode */
5337 void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta)
5339 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5340 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5341 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5344 VCS_update23a(padapter, psta);
5347 if (pmlmepriv->htpriv.ht_option)
5349 psta->htpriv.ht_option = true;
5351 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
5353 if (support_short_GI23a(padapter, &pmlmeinfo->HT_caps))
5354 psta->htpriv.sgi = true;
5356 psta->qos_option = true;
5361 psta->htpriv.ht_option = false;
5363 psta->htpriv.ampdu_enable = false;
5365 psta->htpriv.sgi = false;
5366 psta->qos_option = false;
5369 psta->htpriv.bwmode = pmlmeext->cur_bwmode;
5370 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
5372 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
5373 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
5376 if (pmlmepriv->qos_option)
5377 psta->qos_option = true;
5379 psta->state = _FW_LINKED;
5382 void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, int join_res)
5384 struct sta_info *psta, *psta_bmc;
5385 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5386 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5387 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
5388 struct sta_priv *pstapriv = &padapter->stapriv;
5391 hw_var_set_mlme_join(padapter, 1);
5392 hw_var_set_bssid(padapter, null_addr);
5394 /* restore to initial setting. */
5395 update_tx_basic_rate23a(padapter,
5396 padapter->registrypriv.wireless_mode);
5398 goto exit_mlmeext_joinbss_event_callback23a;
5401 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5404 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
5407 pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
5408 update_bmc_sta_support_rate23a(padapter, psta_bmc->mac_id);
5409 Update_RA_Entry23a(padapter, psta_bmc);
5413 /* turn on dynamic functions */
5414 rtl8723a_odm_support_ability_set(padapter, DYNAMIC_ALL_FUNC_ENABLE);
5416 /* update IOT-releated issue */
5417 update_IOT_info23a(padapter);
5419 HalSetBrateCfg23a(padapter, cur_network->SupportedRates);
5422 rtl8723a_set_beacon_interval(padapter, pmlmeinfo->bcn_interval);
5424 /* udpate capability */
5425 update_capinfo23a(padapter, pmlmeinfo->capability);
5427 /* WMM, Update EDCA param */
5428 WMMOnAssocRsp23a(padapter);
5431 HTOnAssocRsp23a(padapter);
5433 /* Set cur_channel&cur_bwmode&cur_ch_offset */
5434 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5436 psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
5437 if (psta) /* only for infra. mode */
5439 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5441 /* DBG_8723A("set_sta_rate23a\n"); */
5443 psta->wireless_mode = pmlmeext->cur_wireless_mode;
5445 /* set per sta rate after updating HT cap. */
5446 set_sta_rate23a(padapter, psta);
5449 hw_var_set_mlme_join(padapter, 2);
5451 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
5452 /* correcting TSF */
5453 rtw_correct_TSF(padapter);
5455 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5458 rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_CONNECT, 0);
5460 exit_mlmeext_joinbss_event_callback23a:
5461 DBG_8723A("=>%s\n", __func__);
5464 void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter, struct sta_info *psta)
5466 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5467 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5469 DBG_8723A("%s\n", __func__);
5471 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5473 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)/* adhoc master or sta_count>1 */
5477 else/* adhoc client */
5479 /* correcting TSF */
5480 rtw_correct_TSF(padapter);
5483 if (send_beacon23a(padapter) == _FAIL)
5485 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
5487 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
5492 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
5496 hw_var_set_mlme_join(padapter, 2);
5499 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5501 /* rate radaptive */
5502 Update_RA_Entry23a(padapter, psta);
5504 /* update adhoc sta_info */
5505 update_sta_info23a(padapter, psta);
5508 void mlmeext_sta_del_event_callback23a(struct rtw_adapter *padapter)
5510 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5511 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5513 if (is_client_associated_to_ap23a(padapter) || is_IBSS_empty23a(padapter))
5515 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5517 hw_var_set_mlme_disconnect(padapter);
5518 hw_var_set_bssid(padapter, null_addr);
5520 /* restore to initial setting. */
5521 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
5523 /* switch to the 20M Hz mode after disconnect */
5524 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5525 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5527 /* SelectChannel23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
5528 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5530 flush_all_cam_entry23a(padapter);
5532 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5534 /* set MSR to no link state -> infra. mode */
5535 Set_MSR23a(padapter, _HW_STATE_STATION_);
5537 del_timer_sync(&pmlmeext->link_timer);
5541 static u8 chk_ap_is_alive(struct rtw_adapter *padapter, struct sta_info *psta)
5545 if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) &&
5546 sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) &&
5547 sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
5552 sta_update_last_rx_pkts(psta);
5556 void linked_status_chk23a(struct rtw_adapter *padapter)
5559 struct sta_info *psta;
5560 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5561 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5562 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5563 struct sta_priv *pstapriv = &padapter->stapriv;
5565 rtw_hal_sreset_linked_status_check23a(padapter);
5567 if (is_client_associated_to_ap23a(padapter))
5569 /* linked infrastructure client mode */
5571 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
5576 if ((psta = rtw_get_stainfo23a(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
5578 bool is_p2p_enable = false;
5580 if (chk_ap_is_alive(padapter, psta) == false)
5583 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
5586 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
5587 u8 backup_oper_channel = 0;
5589 /* switch to correct channel of current network before issue keep-alive frames */
5590 if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel) {
5591 backup_oper_channel = rtw_get_oper_ch23a(padapter);
5592 SelectChannel23a(padapter, pmlmeext->cur_channel);
5595 if (rx_chk != _SUCCESS)
5596 issue_probereq23a_ex23a(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
5598 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) {
5599 tx_chk = issue_nulldata23a(padapter, psta->hwaddr, 0, 3, 1);
5600 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
5601 if (tx_chk == _SUCCESS && !is_p2p_enable)
5605 /* back to the original operation channel */
5606 if (backup_oper_channel>0)
5607 SelectChannel23a(padapter, backup_oper_channel);
5610 if (rx_chk != _SUCCESS) {
5611 if (pmlmeext->retry == 0) {
5612 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5613 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5614 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5618 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf)
5619 tx_chk = issue_nulldata23a(padapter, NULL, 0, 1, 0);
5622 if (rx_chk == _FAIL) {
5624 if (pmlmeext->retry > rx_chk_limit) {
5625 DBG_8723A_LEVEL(_drv_always_,
5626 "%s(%s): disconnect or "
5627 "roaming\n", __func__,
5628 padapter->pnetdev->name);
5629 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress,
5630 WLAN_REASON_EXPIRATION_CHK);
5634 pmlmeext->retry = 0;
5637 if (tx_chk == _FAIL) {
5638 pmlmeinfo->link_count &= 0xf;
5640 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
5641 pmlmeinfo->link_count = 0;
5644 } /* end of if ((psta = rtw_get_stainfo23a(pstapriv, passoc_res->network.MacAddress)) != NULL) */
5646 else if (is_client_associated_to_ibss23a(padapter))
5648 /* linked IBSS mode */
5649 /* for each assoc list entry to check the rx pkt counter */
5650 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
5652 if (pmlmeinfo->FW_sta_info[i].status == 1)
5654 psta = pmlmeinfo->FW_sta_info[i].psta;
5656 if (NULL == psta) continue;
5658 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta))
5661 if (pmlmeinfo->FW_sta_info[i].retry<3)
5663 pmlmeinfo->FW_sta_info[i].retry++;
5667 pmlmeinfo->FW_sta_info[i].retry = 0;
5668 pmlmeinfo->FW_sta_info[i].status = 0;
5669 report_del_sta_event23a(padapter, psta->hwaddr,
5670 65535/* indicate disconnect caused by no rx */
5676 pmlmeinfo->FW_sta_info[i].retry = 0;
5677 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
5682 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5687 static void survey_timer_hdl(unsigned long data)
5689 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5690 struct cmd_obj *ph2c;
5691 struct sitesurvey_parm *psurveyPara;
5692 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5693 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5695 /* issue rtw_sitesurvey_cmd23a */
5696 if (pmlmeext->sitesurvey_res.state > SCAN_START) {
5697 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
5698 pmlmeext->sitesurvey_res.channel_idx++;
5700 if (pmlmeext->scan_abort == true) {
5701 pmlmeext->sitesurvey_res.channel_idx =
5702 pmlmeext->sitesurvey_res.ch_num;
5703 DBG_8723A("%s idx:%d\n", __func__,
5704 pmlmeext->sitesurvey_res.channel_idx);
5706 pmlmeext->scan_abort = false;/* reset */
5709 ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5712 goto exit_survey_timer_hdl;
5714 psurveyPara = (struct sitesurvey_parm*)
5715 kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
5718 goto exit_survey_timer_hdl;
5721 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
5722 rtw_enqueue_cmd23a(pcmdpriv, ph2c);
5725 exit_survey_timer_hdl:
5729 static void link_timer_hdl(unsigned long data)
5731 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5732 /* static unsigned int rx_pkt = 0; */
5733 /* static u64 tx_cnt = 0; */
5734 /* struct xmit_priv *pxmitpriv = &padapter->xmitpriv; */
5735 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5736 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5737 /* struct sta_priv *pstapriv = &padapter->stapriv; */
5739 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
5741 DBG_8723A("link_timer_hdl:no beacon while connecting\n");
5742 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5743 report_join_res23a(padapter, -3);
5745 else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
5748 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
5750 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
5752 pmlmeinfo->state = 0;
5753 report_join_res23a(padapter, -1);
5758 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
5759 /* pmlmeinfo->reauth_count = 0; */
5763 DBG_8723A("link_timer_hdl: auth timeout and try again\n");
5764 pmlmeinfo->auth_seq = 1;
5765 issue_auth23a(padapter, NULL, 0);
5766 set_link_timer(pmlmeext, REAUTH_TO);
5768 else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
5770 /* re-assoc timer */
5771 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
5773 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5774 report_join_res23a(padapter, -2);
5778 DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
5779 issue_assocreq23a(padapter);
5780 set_link_timer(pmlmeext, REASSOC_TO);
5786 static void addba_timer_hdl(unsigned long data)
5788 struct sta_info *psta = (struct sta_info *)data;
5789 struct ht_priv *phtpriv;
5794 phtpriv = &psta->htpriv;
5796 if ((phtpriv->ht_option == true) && (phtpriv->ampdu_enable == true))
5798 if (phtpriv->candidate_tid_bitmap)
5799 phtpriv->candidate_tid_bitmap = 0x0;
5804 void init_addba_retry_timer23a(struct sta_info *psta)
5806 setup_timer(&psta->addba_retry_timer, addba_timer_hdl,
5807 (unsigned long)psta);
5810 void init_mlme_ext_timer23a(struct rtw_adapter *padapter)
5812 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5814 setup_timer(&pmlmeext->survey_timer, survey_timer_hdl,
5815 (unsigned long)padapter);
5817 setup_timer(&pmlmeext->link_timer, link_timer_hdl,
5818 (unsigned long)padapter);
5821 u8 NULL_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5826 u8 setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5829 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5830 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5831 const struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
5833 if (psetop->mode == Ndis802_11APMode) {
5834 pmlmeinfo->state = WIFI_FW_AP_STATE;
5835 type = _HW_STATE_AP_;
5836 } else if (psetop->mode == Ndis802_11Infrastructure) {
5837 pmlmeinfo->state &= ~(BIT(0)|BIT(1));/* clear state */
5838 pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */
5839 type = _HW_STATE_STATION_;
5840 } else if (psetop->mode == Ndis802_11IBSS)
5841 type = _HW_STATE_ADHOC_;
5843 type = _HW_STATE_NOLINK_;
5845 hw_var_set_opmode(padapter, type);
5846 /* Set_NETYPE0_MSR(padapter, type); */
5851 u8 createbss_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5853 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5854 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5855 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5856 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5857 /* u32 initialgain; */
5859 if (pparm->InfrastructureMode == Ndis802_11APMode) {
5860 #ifdef CONFIG_8723AU_AP_MODE
5862 if (pmlmeinfo->state == WIFI_FW_AP_STATE)
5870 /* below is for ad-hoc master */
5871 if (pparm->InfrastructureMode == Ndis802_11IBSS) {
5872 rtw_joinbss_reset23a(padapter);
5874 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5875 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5876 pmlmeinfo->ERP_enable = 0;
5877 pmlmeinfo->WMM_enable = 0;
5878 pmlmeinfo->HT_enable = 0;
5879 pmlmeinfo->HT_caps_enable = 0;
5880 pmlmeinfo->HT_info_enable = 0;
5881 pmlmeinfo->agg_enable_bitmap = 0;
5882 pmlmeinfo->candidate_tid_bitmap = 0;
5884 /* disable dynamic functions, such as high power, DIG */
5885 rtl8723a_odm_support_ability_backup(padapter);
5887 rtl8723a_odm_support_ability_clr(padapter,
5888 DYNAMIC_FUNC_DISABLE);
5890 /* cancel link timer */
5891 del_timer_sync(&pmlmeext->link_timer);
5894 flush_all_cam_entry23a(padapter);
5896 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5897 return H2C_PARAMETERS_ERROR;
5899 memcpy(pnetwork, pparm, sizeof(struct wlan_bssid_ex));
5901 start_create_ibss23a(padapter);
5907 u8 join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5909 struct ndis_802_11_var_ies * pIE;
5910 struct registry_priv *pregpriv = &padapter->registrypriv;
5911 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5912 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5913 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5914 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5915 struct HT_info_element *pht_info;
5917 /* u32 initialgain; */
5920 /* check already connecting to AP or not */
5921 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
5923 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
5924 issue_deauth23a_ex23a(padapter, pnetwork->MacAddress,
5925 WLAN_REASON_DEAUTH_LEAVING, 5, 100);
5927 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5930 flush_all_cam_entry23a(padapter);
5932 del_timer_sync(&pmlmeext->link_timer);
5934 /* set MSR to nolink -> infra. mode */
5935 /* Set_MSR23a(padapter, _HW_STATE_NOLINK_); */
5936 Set_MSR23a(padapter, _HW_STATE_STATION_);
5938 hw_var_set_mlme_disconnect(padapter);
5941 rtw_joinbss_reset23a(padapter);
5943 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5944 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5945 pmlmeinfo->ERP_enable = 0;
5946 pmlmeinfo->WMM_enable = 0;
5947 pmlmeinfo->HT_enable = 0;
5948 pmlmeinfo->HT_caps_enable = 0;
5949 pmlmeinfo->HT_info_enable = 0;
5950 pmlmeinfo->agg_enable_bitmap = 0;
5951 pmlmeinfo->candidate_tid_bitmap = 0;
5952 pmlmeinfo->bwmode_updated = false;
5953 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
5955 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5956 return H2C_PARAMETERS_ERROR;
5958 memcpy(pnetwork, pbuf, sizeof(struct wlan_bssid_ex));
5960 /* Check AP vendor to move rtw_joinbss_cmd23a() */
5961 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pnetwork->IEs,
5962 pnetwork->IELength); */
5964 for (i = sizeof(struct ndis_802_11_fixed_ies); i < pnetwork->IELength;)
5966 pIE = (struct ndis_802_11_var_ies *)(pnetwork->IEs + i);
5968 switch (pIE->ElementID)
5970 case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */
5971 if (!memcmp(pIE->data, WMM_OUI23A, 4))
5972 pmlmeinfo->WMM_enable = 1;
5975 case WLAN_EID_HT_CAPABILITY: /* Get HT Cap IE. */
5976 pmlmeinfo->HT_caps_enable = 1;
5979 case WLAN_EID_HT_OPERATION: /* Get HT Info IE. */
5980 pmlmeinfo->HT_info_enable = 1;
5982 /* spec case only for cisco's ap because cisco's ap
5983 * issue assoc rsp using mcs rate @40MHz or @20MHz */
5984 pht_info = (struct HT_info_element *)(pIE->data);
5986 if ((pregpriv->cbw40_enable) &&
5987 (pht_info->infos[0] & BIT(2))) {
5988 /* switch to the 40M Hz mode according to AP */
5989 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
5990 switch (pht_info->infos[0] & 0x3)
5993 pmlmeext->cur_ch_offset =
5994 HAL_PRIME_CHNL_OFFSET_LOWER;
5998 pmlmeext->cur_ch_offset =
5999 HAL_PRIME_CHNL_OFFSET_UPPER;
6003 pmlmeext->cur_ch_offset =
6004 HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6008 DBG_8723A("set ch/bw before connected\n");
6016 i += (pIE->Length + 2);
6019 hw_var_set_bssid(padapter, pmlmeinfo->network.MacAddress);
6020 hw_var_set_mlme_join(padapter, 0);
6022 /* cancel link timer */
6023 del_timer_sync(&pmlmeext->link_timer);
6025 start_clnt_join23a(padapter);
6030 u8 disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6032 const struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
6033 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6034 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6035 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
6037 if (is_client_associated_to_ap23a(padapter))
6039 issue_deauth23a_ex23a(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
6042 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
6044 /* pmlmeinfo->state = WIFI_FW_NULL_STATE; */
6046 hw_var_set_mlme_disconnect(padapter);
6047 hw_var_set_bssid(padapter, null_addr);
6049 /* restore to initial setting. */
6050 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
6052 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
6053 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
6054 rtl8723a_set_bcn_func(padapter, 0); /* Stop BCN */
6056 /* set MSR to no link state -> infra. mode */
6057 Set_MSR23a(padapter, _HW_STATE_STATION_);
6059 pmlmeinfo->state = WIFI_FW_NULL_STATE;
6061 /* switch to the 20M Hz mode after disconnect */
6062 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
6063 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6065 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
6067 flush_all_cam_entry23a(padapter);
6069 del_timer_sync(&pmlmeext->link_timer);
6071 rtw_free_uc_swdec_pending_queue23a(padapter);
6077 rtw_scan_ch_decision(struct rtw_adapter *padapter,
6078 struct rtw_ieee80211_channel *out, u32 out_num,
6079 const struct rtw_ieee80211_channel *in, u32 in_num)
6082 int scan_ch_num = 0;
6084 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6086 /* clear out first */
6087 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
6089 /* acquire channels from in */
6091 for (i = 0;i<in_num;i++) {
6092 if (in[i].hw_value && !(in[i].flags & IEEE80211_CHAN_DISABLED)
6093 && (set_idx = rtw_ch_set_search_ch23a(pmlmeext->channel_set, in[i].hw_value)) >= 0
6096 memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
6098 if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
6099 out[j].flags &= IEEE80211_CHAN_NO_IR;
6107 /* if out is empty, use channel_set as default */
6109 for (i = 0;i<pmlmeext->max_chan_nums;i++) {
6110 out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
6112 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
6113 out[i].flags &= IEEE80211_CHAN_NO_IR;
6119 if (padapter->setband == GHZ_24) { /* 2.4G */
6120 for (i = 0; i < j ; i++) {
6121 if (out[i].hw_value > 35)
6123 sizeof(struct rtw_ieee80211_channel));
6128 } else if (padapter->setband == GHZ_50) { /* 5G */
6129 for (i = 0; i < j ; i++) {
6130 if (out[i].hw_value > 35) {
6131 memcpy(&out[scan_ch_num++], &out[i], sizeof(struct rtw_ieee80211_channel));
6141 u8 sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6143 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6144 const struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
6145 u8 bdelayscan = false;
6149 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
6150 pmlmeext->sitesurvey_res.state = SCAN_START;
6151 pmlmeext->sitesurvey_res.bss_cnt = 0;
6152 pmlmeext->sitesurvey_res.channel_idx = 0;
6154 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
6155 if (pparm->ssid[i].ssid_len) {
6156 memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid,
6157 pparm->ssid[i].ssid, IW_ESSID_MAX_SIZE);
6158 pmlmeext->sitesurvey_res.ssid[i].ssid_len =
6159 pparm->ssid[i].ssid_len;
6161 pmlmeext->sitesurvey_res.ssid[i].ssid_len = 0;
6165 pmlmeext->sitesurvey_res.ch_num =
6166 rtw_scan_ch_decision(padapter,
6167 pmlmeext->sitesurvey_res.ch,
6168 RTW_CHANNEL_SCAN_AMOUNT,
6169 pparm->ch, pparm->ch_num);
6171 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
6173 /* issue null data if associating to the AP */
6174 if (is_client_associated_to_ap23a(padapter)) {
6175 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
6177 /* switch to correct channel of current network
6178 before issue keep-alive frames */
6179 if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel)
6180 SelectChannel23a(padapter, pmlmeext->cur_channel);
6182 issue_nulldata23a(padapter, NULL, 1, 3, 500);
6188 /* delay 50ms to protect nulldata(1). */
6189 set_survey_timer(pmlmeext, 50);
6194 if ((pmlmeext->sitesurvey_res.state == SCAN_START) ||
6195 (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
6196 /* disable dynamic functions, such as high power, DIG */
6197 rtl8723a_odm_support_ability_backup(padapter);
6198 rtl8723a_odm_support_ability_clr(padapter,
6199 DYNAMIC_FUNC_DISABLE);
6201 /* config the initial gain under scaning, need to
6202 write the BB registers */
6203 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == true)
6208 rtl8723a_set_initial_gain(padapter, initialgain);
6210 /* set MSR to no link state */
6211 Set_MSR23a(padapter, _HW_STATE_NOLINK_);
6213 rtl8723a_mlme_sitesurvey(padapter, 1);
6215 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
6218 site_survey23a(padapter);
6223 u8 setauth_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6225 const struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
6226 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6227 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6229 if (pparm->mode < 4)
6231 pmlmeinfo->auth_algo = pparm->mode;
6237 u8 setkey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6239 unsigned short ctrl;
6240 const struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
6241 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6242 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6243 unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
6245 /* main tx key for wep. */
6247 pmlmeinfo->key_index = pparm->keyid;
6250 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
6252 DBG_8723A_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
6253 "keyid:%d\n", pparm->algorithm, pparm->keyid);
6254 rtl8723a_cam_write(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
6256 /* allow multicast packets to driver */
6257 rtl8723a_on_rcr_am(padapter);
6262 u8 set_stakey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6265 u8 cam_id;/* cam_entry */
6266 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6267 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6268 const struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
6271 /* 0~3 for default key */
6273 /* for concurrent mode (ap+sta): */
6274 /* default key is disable, using sw encrypt/decrypt */
6275 /* cam_entry = 4 for sta mode (macid = 0) */
6276 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
6278 /* for concurrent mode (sta+sta): */
6279 /* default key is disable, using sw encrypt/decrypt */
6280 /* cam_entry = 4 mapping to macid = 0 */
6281 /* cam_entry = 5 mapping to macid = 2 */
6285 DBG_8723A_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
6286 pparm->algorithm, cam_id);
6287 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
6290 struct sta_info *psta;
6291 struct sta_priv *pstapriv = &padapter->stapriv;
6293 if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
6295 clear_cam_entry23a(padapter, pparm->id);
6296 return H2C_SUCCESS_RSP;
6299 psta = rtw_get_stainfo23a(pstapriv, pparm->addr);
6302 ctrl = (BIT(15) | ((pparm->algorithm) << 2));
6304 DBG_8723A("r871x_set_stakey_hdl23a(): enc_algorithm =%d\n", pparm->algorithm);
6306 if ((psta->mac_id<1) || (psta->mac_id>(NUM_STA-4)))
6308 DBG_8723A("r871x_set_stakey_hdl23a():set_stakey failed, mac_id(aid) =%d\n", psta->mac_id);
6309 return H2C_REJECTED;
6312 cam_id = (psta->mac_id + 3);/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
6314 DBG_8723A("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, cam_entry =%d\n", pparm->addr[0],
6315 pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4],
6316 pparm->addr[5], cam_id);
6318 rtl8723a_cam_write(padapter, cam_id, ctrl,
6319 pparm->addr, pparm->key);
6321 return H2C_SUCCESS_RSP;
6326 DBG_8723A("r871x_set_stakey_hdl23a(): sta has been free\n");
6327 return H2C_REJECTED;
6332 /* below for sta mode */
6334 if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
6336 clear_cam_entry23a(padapter, pparm->id);
6340 ctrl = BIT(15) | ((pparm->algorithm) << 2);
6342 rtl8723a_cam_write(padapter, cam_id, ctrl, pparm->addr, pparm->key);
6344 pmlmeinfo->enc_algo = pparm->algorithm;
6349 u8 add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6351 const struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
6352 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6353 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6355 struct sta_info *psta = rtw_get_stainfo23a(&padapter->stapriv, pparm->addr);
6360 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
6361 (pmlmeinfo->HT_enable)) ||
6362 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
6363 issue_action_BA23a(padapter, pparm->addr,
6364 WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
6365 mod_timer(&psta->addba_retry_timer,
6366 jiffies + msecs_to_jiffies(ADDBA_TO));
6368 psta->htpriv.candidate_tid_bitmap &= ~CHKBIT(pparm->tid);
6373 u8 set_tx_beacon_cmd23a(struct rtw_adapter* padapter)
6375 struct cmd_obj *ph2c;
6376 struct Tx_Beacon_param *ptxBeacon_parm;
6377 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
6378 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6379 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6385 ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
6391 ptxBeacon_parm = (struct Tx_Beacon_param *)
6392 kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC);
6393 if (!ptxBeacon_parm) {
6399 memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network,
6400 sizeof(struct wlan_bssid_ex));
6402 len_diff = update_hidden_ssid(
6403 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_,
6404 ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_,
6405 pmlmeinfo->hidden_ssid_mode);
6406 ptxBeacon_parm->network.IELength += len_diff;
6408 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
6410 res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
6419 u8 mlme_evt_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6421 u8 evt_code, evt_seq;
6423 const struct C2HEvent_Header *c2h;
6424 void (*event_callback)(struct rtw_adapter *dev, const u8 *pbuf);
6426 c2h = (struct C2HEvent_Header *)pbuf;
6431 /* checking if event code is valid */
6432 if (evt_code >= MAX_C2HEVT) {
6433 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent Code(%d) mismatch!\n", evt_code));
6437 /* checking if event size match the event parm size */
6438 if ((wlanevents[evt_code].parmsize != 0) &&
6439 (wlanevents[evt_code].parmsize != evt_sz)) {
6440 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
6441 evt_code, wlanevents[evt_code].parmsize, evt_sz));
6445 event_callback = wlanevents[evt_code].event_callback;
6446 event_callback(padapter, pbuf + sizeof(struct C2HEvent_Header));
6453 u8 h2c_msg_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6456 return H2C_PARAMETERS_ERROR;
6461 u8 tx_beacon_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6463 if (send_beacon23a(padapter) == _FAIL)
6465 DBG_8723A("issue_beacon23a, fail!\n");
6466 return H2C_PARAMETERS_ERROR;
6468 #ifdef CONFIG_8723AU_AP_MODE
6469 else /* tx bc/mc frames after update TIM */
6471 struct sta_info *psta_bmc;
6472 struct list_head *plist, *phead, *ptmp;
6473 struct xmit_frame *pxmitframe;
6474 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6475 struct sta_priv *pstapriv = &padapter->stapriv;
6477 /* for BC/MC Frames */
6478 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
6482 if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
6484 msleep(10);/* 10ms, ATIM(HIQ) Windows */
6485 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
6486 spin_lock_bh(&pxmitpriv->lock);
6488 phead = get_list_head(&psta_bmc->sleep_q);
6490 list_for_each_safe(plist, ptmp, phead) {
6491 pxmitframe = container_of(plist,
6495 list_del_init(&pxmitframe->list);
6497 psta_bmc->sleepq_len--;
6498 if (psta_bmc->sleepq_len>0)
6499 pxmitframe->attrib.mdata = 1;
6501 pxmitframe->attrib.mdata = 0;
6503 pxmitframe->attrib.triggered = 1;
6505 pxmitframe->attrib.qsel = 0x11;/* HIQ */
6507 rtw_hal_xmit23aframe_enqueue(padapter, pxmitframe);
6510 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
6511 spin_unlock_bh(&pxmitpriv->lock);
6520 u8 set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6522 const struct set_ch_parm *set_ch_parm;
6523 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6526 return H2C_PARAMETERS_ERROR;
6528 set_ch_parm = (struct set_ch_parm *)pbuf;
6530 DBG_8723A("%s(%s): ch:%u, bw:%u, ch_offset:%u\n", __func__,
6531 padapter->pnetdev->name, set_ch_parm->ch,
6532 set_ch_parm->bw, set_ch_parm->ch_offset);
6534 pmlmeext->cur_channel = set_ch_parm->ch;
6535 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
6536 pmlmeext->cur_bwmode = set_ch_parm->bw;
6538 set_channel_bwmode23a(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
6543 u8 set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6545 const struct SetChannelPlan_param *setChannelPlan_param;
6546 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6549 return H2C_PARAMETERS_ERROR;
6551 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
6553 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
6554 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
6559 u8 led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6561 struct LedBlink_param *ledBlink_param;
6564 return H2C_PARAMETERS_ERROR;
6566 ledBlink_param = (struct LedBlink_param *)pbuf;
6571 u8 set_csa_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6573 return H2C_REJECTED;
6576 /* TDLS_WRCR : write RCR DATA BIT */
6577 /* TDLS_SD_PTI : issue peer traffic indication */
6578 /* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */
6579 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */
6580 /* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
6581 /* TDLS_OFF_CH : first time set channel to off channel */
6582 /* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */
6583 /* TDLS_P_OFF_CH : periodically go to off channel */
6584 /* TDLS_P_BASE_CH : periodically go back to base channel */
6585 /* TDLS_RS_RCR : restore RCR */
6586 /* TDLS_CKALV_PH1 : check alive timer phase1 */
6587 /* TDLS_CKALV_PH2 : check alive timer phase2 */
6588 /* TDLS_FREE_STA : free tdls sta */
6589 u8 tdls_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6591 return H2C_REJECTED;